For anyone wondering how ECDSA is broken mathematically when a nonce ($k$) is reused:
The signature equations for two messages $m_1$ and $m_2$ signed with the same private key $d$ and the same nonce $k$ are: s1=k−1(z1+r⋅d)(modn) s2=k−1(z2+r⋅d)(modn)
where $z_i$ are the message hashes, $r$ is the signature x-coordinate (which is identical for both signatures because $k$ is the same), and $d$ is the private key we want to recover.
By subtracting the two equations: s1−s2=k−1(z1−z2)(modn)
We can compute the nonce $k$ directly: k=(z1−z2)⋅(s1−s2)−1(modn)
Once we recover the nonce $k$, computing the private key $d$ is trivial from either signature: d=r−1(s1⋅k−z1)(modn)
This is why nonce reuse is completely fatal. Even if the nonce isn't fully reused but only biased (e.g. knowing a few bits of $k$ across several signatures), the private key can be recovered in polynomial time using Lattice Reduction (LLL algorithm applied to the Hidden Number Problem).
For anyone wondering how ECDSA is broken mathematically when a nonce ($k$) is reused:
The signature equations for two messages $m_1$ and $m_2$ signed with the same private key $d$ and the same nonce $k$ are:
s1=k−1(z1+r⋅d)(modn)
s2=k−1(z2+r⋅d)(modn)
where $z_i$ are the message hashes, $r$ is the signature x-coordinate (which is identical for both signatures because $k$ is the same), and $d$ is the private key we want to recover.
By subtracting the two equations:
s1−s2=k−1(z1−z2)(modn)
We can compute the nonce $k$ directly:
k=(z1−z2)⋅(s1−s2)−1(modn)
Once we recover the nonce $k$, computing the private key $d$ is trivial from either signature:
d=r−1(s1⋅k−z1)(modn)
This is why nonce reuse is completely fatal. Even if the nonce isn't fully reused but only biased (e.g. knowing a few bits of $k$ across several signatures), the private key can be recovered in polynomial time using Lattice Reduction (LLL algorithm applied to the Hidden Number Problem).