MASTERING-BITCOIN ยท Interactive Practice | Unit 9 ยท Video 4

The Three Hidden Dangers in Every Bitcoin Signature

IKey Formulas Reference

Formula Name Description
s=kโˆ’1(h+dR)โ€Šmodโ€Šns = k^{-1}(h + dR) \bmod n ECDSA signing equation dd = priv key, kk = nonce, hh = msg hash, RR = x-coord of kGkG
k=h1โˆ’h2s1โˆ’s2โ€Šmodโ€Šnk = \dfrac{h_1 - h_2}{s_1 - s_2} \bmod n Nonce recovery (reused kk) If two signatures share kk, anyone can recover it
d=sโ‹…kโˆ’hRโ€Šmodโ€Šnd = \dfrac{s \cdot k - h}{R} \bmod n Private key recovery Once kk is known, dd falls out
k=HMAC-SHA256(d,h)k = \text{HMAC-SHA256}(d, h) RFC 6979 deterministic nonce Same (d,h)(d, h) โ†’ same kk, different hh โ†’ different kk

IIVisualization 1: The ECDSA Signing Equation

Conceptual question: How does the signing equation s=kโˆ’1(h+dR)โ€Šmodโ€Šns = k^{-1}(h + dR) \bmod n transform inputs into a signature?

Use the sliders below to vary the private key dd, the nonce kk, and the message hash hh. We use the toy modulus n=17n = 17 from the video so the arithmetic is easy to follow. The pretend value of RR is also a small slider (in real ECDSA, RR is the x-coordinate of kโ‹…Gk \cdot G, but for this exercise we treat it as an independent input).

โš™ interactive visualization โ€” coming to this page format soon

Notice: Each different (d,k,h,R)(d, k, h, R) produces a different ss. In real Bitcoin, nn is roughly 22562^{256}, but the structure is identical. The signature pair (R,s)(R, s) is what gets DER-encoded and broadcast on the network.

IIIVisualization 2: The Nonce Reuse Catastrophe

Conceptual question: What exactly leaks when the same kk is used to sign two different messages?

Below, a fixed private key dd signs two messages h1h_1 and h2h_2 using the same nonce kk. The slider lets you change kk. Watch the recovered private key (computed using only the two public signatures) match dd exactly โ€” proving that anyone observing the two signatures can drain the wallet.

โš™ interactive visualization โ€” coming to this page format soon

Reflect: Notice that the attacker never sees dd or kk โ€” only the two signatures (R,s1)(R, s_1) and (R,s2)(R, s_2). The fact that RR is identical in both is the public tell-tale sign of nonce reuse. This is exactly the bug that drained Android wallets in 2013 and cracked the Sony PS3.

IVVisualization 3: Legacy vs BIP143 Sighash Scaling

Conceptual question: How badly does legacy sighash scale, and how much does BIP143 improve it?

The slider below sets the number of inputs NN in a transaction. The plot compares legacy sighash work (โˆN2\propto N^2) against BIP143 sighash work (โˆN\propto N). Watch the gap explode as NN grows.

โš™ interactive visualization โ€” coming to this page format soon

Notice: At N=1000N = 1000, legacy sighash performs roughly a million hashing operations while BIP143 performs about a thousand. That 1000ร— gap is exactly the denial-of-service vector SegWit closed by precomputing hashPrevouts, hashSequence, and hashOutputs once per transaction.

VQuiz Questions

Question 1

Why did Satoshi ship Bitcoin with ECDSA instead of the cleaner Schnorr signature scheme?

โœ… Correct! Patent timing forced the choice.

โŒ Not quite. The reason was not technical superiority โ€” Schnorr is actually cleaner. Think about timing.

Show solution

Solution:

The Schnorr signature scheme was filed as a patent in 1989 and only expired in 2008. By the time Bitcoin launched in 2009, every cryptographic library shipped ECDSA and almost none shipped Schnorr โ€” so Satoshi made the pragmatic choice. Ironically, Schnorr has the cleaner math (linear, with a complete security proof), and Taproot finally activated Schnorr in 2021, closing a loop that opened in 1989.

Question 2

A signer uses the same nonce kk to produce two ECDSA signatures (R,s1)(R, s_1) and (R,s2)(R, s_2) on different message hashes h1โ‰ h2h_1 \ne h_2. Which statement is true?

โœ… Correct! Reused nonce โ†’ full key compromise.

โŒ Not quite. Look at what cancels when you subtract the two signing equations.

Show solution

Solution:

Subtracting the two signing equations: s1โˆ’s2=kโˆ’1(h1โˆ’h2)(modn)s_1 - s_2 = k^{-1}(h_1 - h_2) \pmod n gives the attacker: k=h1โˆ’h2s1โˆ’s2(modn)k = \frac{h_1 - h_2}{s_1 - s_2} \pmod n

Once kk is known, plug it back into either signing equation: d=s1โ‹…kโˆ’h1R(modn)d = \frac{s_1 \cdot k - h_1}{R} \pmod n

Two signatures, four lines of algebra, total compromise. This is exactly the bug that hit Sony PS3 (2010), Android SecureRandom (2013), and Blockchain.info's RNG (2014).

Question 3

True or False: RFC 6979 defends against bad randomness by mixing in more entropy from the operating system.

โœ… Correct! RFC 6979 eliminates randomness rather than adding more.

โŒ Not quite. The RFC 6979 fix is structural, not statistical.

Show solution

Solution: False.

RFC 6979 does the opposite: it removes randomness entirely. The nonce is derived deterministically as k=HMAC-SHA256(d,h)k = \text{HMAC-SHA256}(d, h) so the same private key signing the same message always produces the same kk, and different transactions automatically produce different kk values because the message hash differs.

Optional extra entropy can be mixed in for side-channel resistance, but it is no longer load-bearing โ€” a broken RNG can no longer leak your private key. The deeper lesson: the signing math doesn't care whether kk is random, it cares that kk is unique and unpredictable. Determinism gives you both.

Question 4

Before SegWit, computing the legacy sighash for a transaction with NN inputs cost roughly O(N2)O(N^2) work. BIP143 restructured the sighash to scale linearly. What was the key engineering trick?

โœ… Correct! Precomputed midstates turn quadratic work into linear work.

โŒ Not quite. The hash function and the SIGHASH flags didn't change โ€” the trick is structural reuse.

Show solution

Solution:

BIP143 (shipped with SegWit in 2017) precomputes three midstate hashes once per transaction:

  • hashPrevouts โ€” commits to all input outpoints
  • hashSequence โ€” commits to all sequence numbers
  • hashOutputs โ€” commits to every output

Each input's sighash now references those three precomputed values plus its own small per-input data, so total work is O(N)O(N) instead of O(N2)O(N^2). A 1000-input transaction validates roughly 1000ร— faster, closing the denial-of-service vector that lurked in legacy consensus rules. People remember SegWit for fixing malleability and effectively raising the block size โ€” the sighash redesign is the equally important third win.

Solved: 0 / 4