Explaining ECDSA calculations
In this post I assume you know what ECDSA is, and how modular arithmetic works. I will also explained why you must never re-use the signing secret.
Notation
k = the signing secret
G = the generator point
x = the private key
Y = the public key point
m = the message
r,s = the signature
R = the point corresponding to the r part of the signature
n = the curve group order
p = the parameter field order
variables
x,y = coordinates
a,b = some integer
P,Q = some point
sign = -1 or +1
Note that x
is sometimes a coordinate and sometimes the private key, I think the context will
make it clear which.
The Curve
y^2 = x^3 + a * x + b ( mod p )
Note that in the rest of the text the a and b don’t refer to the curve parameters.
Operations on numbers
+,-,* all modulo `p`
a / b `a * modularinverse(b,p)`
^ exponentiation
sqrt(a) calculate the square root modulo p
Operations on curve points
P + Q : point addition
P * a : scalar multiplication
P / a : scalar division = P * modularinverse(a, n)
[P] : take the x coordinate of a point
<x,sign>: decompress: calculate y coordinate with the given sign
(P+Q)*a = P*a+Q*a
P*(a+b) = P*a + P*b
Note that the operation P/Q
is very difficult to calculate, this is what the security of ECDSA is based on.
Calculations
the public key Y = G * x
point decompression is the operation of calculating the y coordinate given the x and a sign:
y = sign * sqrt(x^3 + a * x + b)
Signing
(r,s) = ( [G*k], (m+x*r) / k ) ( mod n )
Verification
verify that: R*s == G*m + Y*r
Note that most implementations only verify the x coordinate of R, so in reality the verification
would also appear valid when -R*s==G*m+Y*r
Find pubkey
Find the public key given a message and signature, and also the private key, given the signing secret k
:
R = <r, sign>
Y = (R*s-G*m)/r
x = (sign * s*k-m)/r
Note that this can give 2 possible solutions, depending on the sign of R.
Find the public key given 2 signatures for the same message
Y = (R1*s1-R2*s2)/(r1-r2)
Find privkey
Find the private key given 2 signatures with identical signing secret:
k = (m1-m2)/(s1-s2)
x = (s1*k-m1)/r
This is the attack on ECDSA because of which you should never reuse the k
value.
Similarly, when you know that an implementation used a bad PRNG for generating k
,
you can find other public keys from signatures generated using this same k
value.
When implementing ECDSA, read rfc6979 for a solution: basically you derive k from a hash of the message and the private key.
Things to note
Private key x and private key (x+n) both result in the same public key
I can create a signature (r,s) for a message m, using private key x.
then can calculate a privatekey x' = (-s*k-m)/r
and a publickey Y’ using Y' = (-R*s-G*m)/r
which also verifies that signature.