ECDSA and Bitcoin I: Intuition About Elliptic Curve

The set of parameters Bitcoin used is called secp256k1. It’s one of the Standards for Efficient Cryptogrpahy(SEC) or Standards for Efficient Cryptography Group (SECG). SEC or SECG is base on Elliptic Curve Digital Signature Algorithm(ECDSA). Before dive in, we can get a glimpse of what the algorithm looks like in Brown et al’s publication(ec1.png, ec2.png).
More info: Elliptic Curve Cryptography: page 6-7

I. Intuition About Elliptic Curve: Basics

1. Double a point(Add a point to itself):

Let’s consider a elliptic curve (EC)(EC):

y2=x3+ax+by^2 = x^3 + ax + b

, mod(P) will be discussed latter.

There is a initial point G(x1,y1)G(x_{1},y_{1}) on ECEC, how to get D=G+GD = G + G?

Draw a tangent line at GG, and cross ECEC at C(xc,yc)C(x_{c},y_{c}). The vertical line crosses CC, will cross ECEC at D(x3,y3)D(x_{3},y_{3}), which is the result G+GG+G by definition.

1.1 The slope of the tangent line:

y2=x3+ax+b\because y^2 = x^3 + ax + b

2ydy=(3x2+a)dx\therefore 2ydy = (3x^2 +a)dx

dydx=(3x2+a)2y\therefore {\frac{dy}{dx}} = {\frac{(3x^2 +a)}{2y}}

λ=dydx=3x12+a2y1\therefore \lambda = {\frac{dy}{dx}} = {\frac{3x_{1}^2+a}{2y_{1}}}

1.2 Point C(xc,yc)C(x_{c},y_{c}) :

ycy1xcx1=λ\because {\frac{y_{c}-y_{1}}{x_{c}-x_{1}}} = \lambda

ycy1=λ(xcx1)\therefore y_{c}-y_{1} = \lambda(x_{c}-x_{1})

yc=λ(xcx1)+y1\therefore y_{c} = \lambda(x_{c}-x_{1}) + y_{1}

y2=x3+ax+b\because y^2 = x^3 + ax + b

yc2=(λ(xcx1)+y1)2=xc3+axc+b\therefore y_{c}^2 = (\lambda(x_{c}-x_{1}) + y_{1})^2 = x_{c}^3 + ax_{c} + b

xc3(λ(xcx1)+y1)2+axc+b=0\therefore x_{c}^3 - (\lambda(x_{c}-x_{1}) + y_{1})^2 + ax_{c} + b = 0

Let me put it another way:

x3(λ(xx1)+y1)2+ax+b=0x^3 - (\lambda(x-x_{1}) + y_{1})^2 + ax + b = 0

This equation has three roots, one of them is xcx_{c}.
What’s the other two roots? Yes, they are: x1,x1x_{1},x_{1}(since tangent at G(x1,y1)G(x_{1},y_{1})).
Let’s focus on the coefficient of x2x^2:

x3(λ(xx1)+y1)2+ax+b=0\because x^3 - (\lambda(x-x_{1}) + y_{1})^2 + ax + b = 0

...λ2x2+...=0... - \lambda^2x^2 + ... = 0

the coefficient of x2x^2 is λ2\lambda^2. On the other hand, since three roots are:x1,x1,xcx_{1},x_{1},x_{c},

(xx1)(xx1)(xxc)=0(x-x_{1})(x-x_{1})(x-x_{c})=0

...(x1+x1+xc)x2+...=0... - (x_{1}+x_{1}+x_{c})x^2 + ... = 0

This two coefficient is identical, therefore

λ2=x1+x1+xc\lambda^2=x_{1}+x_{1}+x_{c}

xc=λ2x1x1=λ22x1x_{c}=\lambda^2-x_{1}-x_{1}=\lambda^2-2x_{1}

1.3 Point D(x3,y3)D(x_{3},y_{3}) :

x3=xc=λ2x1x1x_{3}=x_{c}=\lambda^2-x_{1}-x_{1}

y3=yc=(λ(xcx1)+y1)=λ(x1x3)y1y_{3}=-y_{c}= -(\lambda(x_{c}-x_{1}) + y_{1})=\lambda(x_{1}-x_{3}) - y_{1}

where

λ=3x12+a2y1\lambda = {\frac{3x_{1}^2+a}{2y_{1}}}

G(x1,y1)+G(x1,y1)G(x_{1},y_{1}) + G(x_{1},y_{1}):

λ=3x12+a2y1\lambda = {\frac{3x_{1}^2+a}{2y_{1}}}

x3=λ2x1x1x_{3}=\lambda^2-x_{1}-x_{1}

y3=λ(x1x3)y1y_{3}=\lambda(x_{1}-x_{3}) - y_{1}

D(x3,y3)=G+GD(x_{3},y_{3})=G+G

2. Addition(Add two points together):

There are two initial points A(x1,y1)A(x_{1},y_{1}) and B(x2,y2)B(x_{2},y_{2}) on ECEC, how to get D=A+BD = A + B?


Draw a line through AA and BB, and cross ECEC at C(xc,yc)C(x_{c},y_{c}). The vertical line crosses CC, will cross ECEC at D(x3,y3)D(x_{3},y_{3}), which is the result A+BA+B by definition. If AA and BB are on the same vertical line, i.e. x1=x2,y1=y2x_{1}=x_{2},y_{1}=-y_{2}, then A+B=OA+B=\mathcal{O}, where O\mathcal{O} is an infinity point with the following properties(by definition):

G+O=O,O+O=OG+\mathcal{O}=\mathcal{O},\mathcal{O}+\mathcal{O}=\mathcal{O}

Intuitively, O\mathcal{O} is a point faaaar away.

2.1 The slope of the line is determined by two initial points :

λ=dydx=y2y1x2x1\lambda = {\frac{dy}{dx}} = {\frac{y_{2}-y_{1}}{x_{2}-x_{1}}}

2.2 Point C(xc,yc)C(x_{c},y_{c}):

ycy1xcx1=λ\because {\frac{y_{c}-y_{1}}{x_{c}-x_{1}}} = \lambda

ycy1=λ(xcx1)\therefore y_{c}-y_{1} = \lambda(x_{c}-x_{1})

yc=λ(xcx1)+y1\therefore y_{c} = \lambda(x_{c}-x_{1}) + y_{1}

y2=x3+ax+b\because y^2 = x^3 + ax + b

yc2=(λ(xcx1)+y1)2=xc3+axc+b\therefore y_{c}^2 = (\lambda(x_{c}-x_{1}) + y_{1})^2 = x_{c}^3 + ax_{c} + b

xc3(λ(xcx1)+y1)2+axc+b=0\therefore x_{c}^3 - (\lambda(x_{c}-x_{1}) + y_{1})^2 + ax_{c} + b = 0

Let me put it another way:

x3(λ(xx1)+y1)2+ax+b=0x^3 - (\lambda(x-x_{1}) + y_{1})^2 + ax + b = 0

This equation has three roots, one of them is xcx_{c}.
What’s the other two roots? Yes, they are: x1,x2x_{1},x_{2}.
Let’s focus on the coefficient of x2x^2:

x3(λ(xx1)+y1)2+ax+b=0\because x^3 - (\lambda(x-x_{1}) + y_{1})^2 + ax + b = 0

...λ2x2+...=0... - \lambda^2x^2 + ... = 0

the coefficient of x2x^2 is λ2\lambda^2. On the other hand, since three roots are:x1,x2,xcx_{1},x_{2},x_{c},

(xx1)(xx2)(xxc)=0(x-x_{1})(x-x_{2})(x-x_{c})=0

...(x1+x2+xc)x2+...=0... - (x_{1}+x_{2}+x_{c})x^2 + ... = 0

This two coefficient is identical, therefore

λ2=x1+x2+xc\lambda^2=x_{1}+x_{2}+x_{c}

xc=λ2x1x2x_{c}=\lambda^2-x_{1}-x_{2}

Reference: Explicit Addition Formulae

2.3 Point D(x3,y3)D(x_{3},y_{3}) :

x3=xc=λ2x1x2x_{3}=x_{c}=\lambda^2-x_{1}-x_{2}

y3=yc=(λ(xcx1)+y1)=λ(x1x3)y1y_{3}=-y_{c}= -(\lambda(x_{c}-x_{1}) + y_{1})= \lambda(x_{1}-x_{3}) - y_{1}

where

λ=y2y1x2x1\lambda = {\frac{y_{2}-y_{1}}{x_{2}-x_{1}}}

A(x1,y1)+B(x2,y2)A(x_{1},y_{1}) + B(x_{2},y_{2}):

λ=y2y1x2x1\lambda = {\frac{y_{2}-y_{1}}{x_{2}-x_{1}}}

x3=λ2x1x2x_{3}=\lambda^2-x_{1}-x_{2}

y3=λ(x1x3)y1y_{3}=\lambda(x_{1}-x_{3}) - y_{1}

D(x3,y3)=A+BD(x_{3},y_{3})=A+B

II. Intuition About Elliptic Curve: mod

With mod, elliptic curve is no longer a curve, instead it is turned into a group of discrete points. With mod(P), the result D will be capped by P, therefore we can control the magnitude of the output.


In Figure 1.2, we start from an initial point G(3,10), i.e. the point labeled 1, use EC multiplication and get the rest points in the group. EC multiplication, which is based on EC double and EC addition, will be discussed latter. Let's go over some details of `mod` first.

1. mod: Basics

Let’s see some examples:

x mod P:x \space mod \space P:

1 mod 23=22-1 \space mod \space 23 = 22

0 mod 23=00 \space mod \space 23 = 0

1 mod 23=11 \space mod \space 23 = 1

2 mod 23=22 \space mod \space 23 = 2

......

22 mod 23=2222 \space mod \space 23 = 22

23 mod 23=023 \space mod \space 23 = 0

24 mod 23=124 \space mod \space 23 = 1

25 mod 23=225 \space mod \space 23 = 2

......

2. mod: Properties

x+y mod P=(x mod P+y mod P) mod Px+y \space mod \space P = (x \space mod \space P + y\space mod \space P)\space mod \space P

xy mod P=((x mod P)(y mod P)) mod Pxy \space mod \space P = ((x \space mod \space P) (y\space mod \space P))\space mod \space P

Why? Let’s see an example:

x=25,y=30,P=23x=25,y=30,P=23

25+30 mod 23=(23+2)+(23+7) mod 23=(232+2+7) mod 2325+30\space mod \space 23 = (23+2) +(23+7)\space mod \space 23=(\bcancel{23*2}+2+7)\space mod \space 23

=2+7 mod 23=(25 mod 23+30 mod 23) mod 23=2+7\space mod \space 23=(25\space mod \space 23+30\space mod \space 23)\space mod \space 23

Similarly,

2530 mod 23=(23+2)(23+7) mod 23=(2323+232+237+27) mod 2325*30\space mod \space 23 = (23+2) * (23+7)\space mod \space 23=(\bcancel{23*23}+\bcancel{23*2}+\bcancel{23*7}+2*7)\space mod \space 23

=27 mod 23=(25 mod 2330 mod 23) mod 23=2*7\space mod \space 23=(25\space mod \space 23*30\space mod \space 23)\space mod \space 23

When mod, only remainders matter.

3. mod: Inverse

Sometimes, we need to caculate 1A mod P{\frac{1}{A}}\space mod\space P, i.e. modular inverse. As we know, if AB=1A*B = 1, BB is the inverse of AA. The definition of modular inverses is similar.
If both A and BA\space and\space B are integers and AB mod P=1A*B\space mod \space P=1, BB is the modular inverse of AA. Or state in an other way: 1A mod P=B{\frac{1}{A}}\space mod\space P=B.

3.1 One Improtant Property

Note: If AA does not coprime to PP, i.e. if AA shares at least one prime factor with PP, AA has no modular inverse (mod PP). This is why secp256k1 chooses a prime PP, which we will discuss later.

An example:

A=6,P=8(they share one prime factor 2)A=6, P=8(they\space share\space one\space prime\space factor\space 2)

60 mod 8=0=026*0 \space mod \space 8=0=0*2

61 mod 8=2=126*1 \space mod \space 8=2=1*2

62 mod 8=4=226*2 \space mod \space 8=4=2*2

63 mod 8=2=126*3 \space mod \space 8=2=1*2

64 mod 8=0=026*4 \space mod \space 8=0=0*2

......

A more general case:

A=nk,P=mk(they share one prime factor k)A=n*k, P=m*k(they\space share\space one\space prime\space factor\space k)

AB=nBk\because A*B=nB*k

AB mod P=nBk mod (mk)\therefore A*B\space mod \space P=nB*k \space mod \space (m*k)

The reault must be something like tkt*k, where tt is an integer.

3.2 Calculate Modular Inverses

If AA coprimes to PP, how to find it’s modular inverse BB? We can use Extend Euclidean Algorithm.

  • An example (A=7,P=23A=7,P=23):
n R ×\times 23 ×\times 7 t
23=1*23+0 23 1\color{green} 1 0\color{green} 0 0
7=0+1*7 7 0\color{orange} 0 1\color{orange} 1 1
23=3*7+2 or 2=23- 3\color{magenta} 3*7 3\color{magenta} 3 2 1\color{green} 1- 3\color{magenta} 3* 0\color{orange} 0= 1\color{blue} 1 0\color{green} 0- 3\color{magenta} 3* 1\color{orange} 1= 3\color{blue} -3 2
7=3*2+1 or 1=7- 3\color{red} 3*2 3\color{red} 3 1 0\color{orange} 0- 3\color{red} 3* 1\color{blue} 1=-3 1\color{orange} 1- 3\color{red} 3*( 3\color{blue} -3)=10 3

From the last line of the above table, we have

1=(3)23+1071=(-3) * 23 + 10 * 7

107=323+1\therefore 10 * 7 = 3 * 23 +1

107 mod 23=1\therefore 10 * 7\space mod\space 23 = 1

B=10\therefore B=10

  • General cases(it’s a loop until R=1 therefore B=atB=a_{t}):
n R ×\timesP ×\timesA t
R0R_{0}=1*PP+0 R0=PR_{0}=P p0=1\color{green}p_{0}=1 a0=0\color{green}a_{0}=0 0
R1R_{1}=0+1*AA R1=AR_{1}=A p1=0\color{orange}p_{1}=0 a1=1\color{orange}a_{1}=1 1
R2=R0R_{2}=R_{0}- n2\color{magenta}n_{2}*R1R_{1} n2\color{magenta}n_{2} R2R_{2} p0\color{green} p_{0}- n2\color{magenta}n_{2}* p1\color{orange}p_{1}= p2\color{blue}p_{2} a0\color{green}a_{0}- n2\color{magenta}n_{2}* a1\color{orange}a_{1}= a2\color{blue}a_{2} 2
1=Rt2R_{t-2}- nt\color{red}n_{t}*Rt1R_{t-1} nt\color{red}n_{t} 1 pt2\color{orange}p_{t-2}- nt\color{red}n_{t}* pt1\color{blue}p_{t-1}=ptp_{t} at2\color{orange}a_{t-2}- nt\color{red}n_{t}*( at1\color{blue}a_{t-1})=ata_{t} t

JavaScript:

Python:

Reference: Modular inverses, Extend Euclidean Algorithm, Elliptic Curve Cryptography, HTML, JavaScript, Python

4. mod: Elliptic Curve

Recall: We need to caculate λ\lambda, x3x_{3} and y3y_{3}. This time let’s put modPmod P at the end of x3x_{3} and y3y_{3}

4.1 Double a point(Add a point to itself)

From initial point G(x1,y1)G(x_{1},y_{1}):

λ=3x12+a2y1\lambda = {\frac{3x_{1}^2+a}{2y_{1}}}

x3=λ2x1x1 mod Px_{3}=\lambda^2-x_{1}-x_{1}\color{blue}\space mod\space P

y3=λ(x1x3)y1 mod Py_{3}=\lambda(x_{1}-x_{3}) - y_{1}\color{blue}\space mod\space P

D(x3,y3)=G+GD(x_{3},y_{3})=G+G

Based on the properties of mod and modular inverse,

x3=(λ2 mod Px1 mod Px1 mod P) mod Px_{3}=(\lambda^2{\color{blue}\space mod\space P}-x_{1}{\color{blue}\space mod\space P}-x_{1}{\color{blue}\space mod\space P})\color{blue}\space mod\space P

x3=(λ mod Pλ mod Px1 mod Px1 mod P) mod Px_{3}=(\lambda{\color{blue}\space mod\space P} * \lambda{\color{blue}\space mod\space P}-x_{1}{\color{blue}\space mod\space P}-x_{1}{\color{blue}\space mod\space P})\color{blue}\space mod\space P

Or,

x3=(λ mod Pλ mod Px1x1) mod Px_{3}=(\lambda{\color{blue}\space mod\space P} * \lambda{\color{blue}\space mod\space P}-x_{1}-x_{1})\color{blue}\space mod\space P

Where,

λ mod P=3x12+a2y1 mod P=((3x12+a) mod P12y1 mod P) mod P\lambda{\color{blue}\space mod\space P} = {\frac{3x_{1}^2+a}{2y_{1}}}{\color{blue}\space mod\space P} = ((3x_{1}^2+a){\color{blue}\space mod\space P} * {\frac{1}{2y_{1}}}{\color{blue}\space mod\space P})\color{blue}\space mod\space P

=((3x12+a) mod P2y1 inverse mod P) mod P= ((3x_{1}^2+a){\color{blue}\space mod\space P} * 2y_{1}{\color{blue}\space inverse\space mod\space P})\color{blue}\space mod\space P

And,

y3=(λ mod P(x1x3)y1) mod Py_{3}=(\lambda{\color{blue}\space mod\space P} * (x_{1}-x_{3}) - y_{1})\color{blue}\space mod\space P

Python:

4.2 Addition

From initial points A(x1,y1)A(x_{1},y_{1}) and B(x2,y2)B(x_{2},y_{2}):

λ mod P=y2y1x2x1 mod P=((y2y1) mod P1x2x1 mod P) mod P\lambda{\color{blue}\space mod\space P} = {\frac{y_{2}-y_{1}}{x_{2}-x_{1}}}{\color{blue}\space mod\space P} = ((y_{2}-y_{1}){\color{blue}\space mod\space P} * {\frac{1}{x_{2}-x_{1}}}{\color{blue}\space mod\space P}){\color{blue}\space mod\space P}

=((y2y1) mod P(x2x1) inverse mod P) mod P= ((y_{2}-y_{1}){\color{blue}\space mod\space P} * (x_{2}-x_{1}) {\color{blue}\space inverse\space mod\space P}){\color{blue}\space mod\space P}

And

x3=(λ mod Pλ mod Px1x2) mod Px_{3}=(\lambda{\color{blue}\space mod\space P} * \lambda{\color{blue}\space mod\space P}-x_{1}-x_{2})\color{blue} \space mod\space P

y3=(λ mod P(x1x3)y1) mod Py_{3}=(\lambda{\color{blue}\space mod\space P} * (x_{1}-x_{3}) - y_{1}) \color{blue} \space mod\space P

D(x3,y3)=A+BD(x_{3},y_{3})=A+B

Python code:

4.3 Multiplication

Multiplication, or scalar multiplication, is defined as add a point to itself many times. From a initial point G(x1,y1)G(x_{1},y_{1}):

2G=G+G2*G = G+G

3G=G+G+G3*G = G+G+G

......

NG=G+G+...+GNN*G = \underbrace{G+G+...+G}_{\text{N}}

In practice, N is usually very large, say

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFB673C211660358AAD66B17B368CD0364141\text{FFFFFFFFFFFFFFFFFFFFFFFFFFFFFB673C211660358AAD66B17B368CD0364141}

In decimal, it’s

115792089237316195423570985008687907452837564279074904382605163141518161494337115792089237316195423570985008687907452837564279074904382605163141518161494337

If we use the above method to calculate N*G, it will take a looooong time to get the result. How long specifically? Let’s estimate it. At the end of 2018, multi-core GHz processors are capable of processing over 100 billion instructions per second. There are about 4.2 billion active internet users around the world. Our unverse is around 13.8 billion years old. Even if all active internet users work together since the birth of the universe, until now we’ve only finished

12.6606833790440597×1047\frac{1}{2.6606833790440597\times 10^{47}}

Fortunatly, we have another alternative method:

2G=G+G2G = G+G

4G=2G+2G4G = 2G+2G

23G=22G+22G2^{3}G = 2^{2}G+2^{2}G

......

2m0+m1+...+mnG=2m0G+2m1G+...+2mnG2^{m_{0}+m_{1}+...+m_{n}} * G = 2^{m_{0}}G+2^{m_{1}}G+...+2^{m_{n}}G

......

In binary, NN is

1111111111...0101000001256\underbrace{1111111111...0101000001}_{\text{256}}

So,

N=2256+2255+...+29+27+1N=2^{256}+2^{255}+...+2^{9}+2^{7}+1

Actually, if we are going to use this method, we still need to prove ++ is associative, since ++ is not ordinary plus it’s one dot on eclliptic curve plus another dot. It’s a little bit tricky here, let me show you an example:
How to prove the associativity? Silverman and Tate offered us a geometric proof in their textbook Rational Points on Elliptic Curves. The proof is very elegant, so I quoted it here.

Python code(binary method):

  • An example: a=1,b=1,P=23,x1=3,y1=10a=1,b=1,P=23,x_{1}=3,y_{1}=10.
    The initial point G(0,1)G(0,1) is a generating point. 1G,2G,...,27G1*G,2*G,...,27*G are labeled in Figure 2.1. Notice, point 27 is right above point 1. Recall EC addition, what will happen if AA and BB are on the same vertical line? A+B=OA+B=\mathcal{O}. That is to say, infinit point O\mathcal{O} is 28th point in this group genrated by GG. Actually, this group only have 28 points and they can all be generated by multiply GG with 1,2,...,281,2,...,28. More details will be discussed in the next section.

Reference: Elliptic Curve Cryptography, Python 2.7 Code