In 1976, Whitfield Diffie and Martin Hellman published a six-page paper that upended the entire field of cryptography.† For centuries, encryption had required both parties to share a secret key in advance—meet in person, exchange code books, use a trusted courier. Diffie and Hellman showed that this wasn't necessary: you could use mathematical trapdoor functions to create "public key" systems where anyone could encrypt a message, but only the holder of a private key could decrypt it. Their paper also introduced the concept of digital signatures—a way to prove authorship without revealing secrets. What they didn't know was that a young mathematician named Ralph Merkle had independently arrived at essentially the same insight a year earlier—his paper, submitted to the Communications of the ACM in 1975, sat in a reviewer's pile for three years because no one understood it.
And neither Diffie, Hellman, nor Merkle knew that the British signals intelligence agency GCHQ had gotten there first. In 1970, a cryptographer named James Ellis wrote an internal paper describing the concept of "non-secret encryption"—what we now call public-key cryptography. Three years later, his colleague Clifford Cocks devised a practical implementation based on the difficulty of factoring large numbers—the same mathematical foundation that RSA would independently discover in 1977. All of it remained classified until 1997. The most consequential idea in modern cryptography was invented three times, on two continents, across a decade—and for most of that time, none of the inventors knew about the others.
From Diffie–Hellman came RSA, then PGP, then the cypherpunks' dream of digital cash. From the cypherpunks—David Chaum, Adam Back, Wei Dai, Hal Finney—came the building blocks that Satoshi Nakamoto assembled into Bitcoin. Every Bitcoin transaction is authorized by a digital signature: a mathematical proof that the holder of a specific private key approved the transfer. But a signature must be over something—it signs a specific message, and any change to that message invalidates the signature. The question is: what message does a Bitcoin signature sign?
The answer is not "the transaction." It can't be, because the transaction contains the signature. Instead, Bitcoin uses a carefully constructed sighash—a digest computed from a modified version of the transaction where the signature itself has been surgically removed. This chapter traces that process byte by byte, using the same Block 170 transaction we parsed in Chapters 1 and 2.
Bitcoin uses double SHA-256 (SHA-256d) as its universal hash function. The txid computation from Chapter 1 is one instance; the sighash computation below is another; block headers, Merkle trees, and address derivation all use the same construction:
\[H(m) = \text{SHA-256}(\text{SHA-256}(m))\]
SHA-256 takes an arbitrary-length input and produces a fixed 256-bit (32-byte) output. Some key properties:
SHA-256 was designed by the NSA and standardized by NIST in 2002, with the current specification being FIPS 180-4.† Despite its provenance, it remains unbroken after nearly a quarter century. Bitcoin relies on all four properties above.
As mentioned in Chapter 1, SHA-256 (like all Merkle–Damgård hash functions) is vulnerable to length-extension attacks: given \(H(m)\) and the length of \(m\), an attacker can compute \(H(m \| pad \| m')\) without knowing \(m\). Applying SHA-256 twice eliminates this:
\[\text{SHA-256}(\text{SHA-256}(m \| \text{pad} \| m')) \neq \text{SHA-256}(\text{SHA-256}(m))\]
The outer hash completely scrambles the intermediate value, breaking the extension chain. This is the same principle behind HMAC, and it costs only one extra hash computation—a negligible overhead.
The length-extension vulnerability has a clean algebraic explanation rooted in semigroup theory—a different algebraic structure from the elliptic curve groups we'll meet in Section 3.4, but one worth understanding on its own terms. The iterated construction exploited by this attack is the Merkle–Damgård construction, independently proposed by Ralph Merkle and Ivan Damgård in 1979 and 1989 respectively.†
SHA-256 processes a message by breaking it into 512-bit blocks \(m_{1}, m_{2}, \ldots, m_{n}\) and iterating a compression function \(f\): \[h_0 = IV, \quad h_i = f(h_{i-1}, m_i), \quad H(m) = h_n\] Here \(IV\) is the initialization vector ("initial hash value" in the standard)—a fixed 256-bit constant built from the fractional parts of the square roots of the first eight primes: \(2, 3, 5, 7, 11, 13, 17, 19\).† Each block \(m_{i}\) induces a state transformation \(f_{m_i} : \{0,1\}^{256} \to \{0,1\}^{256}\). The hash is a left fold—a composition of these transformations applied to a fixed starting point: \[ H(m) = (f_{m_n} \circ \cdots \circ f_{m_1})(IV) \] The set of all such transformations forms a semigroup under composition: it is closed and associative, but unlike elliptic curve groups, the transformations are not generally invertible. There is no "division" that recovers \(h_{i-1}\) from \(h_{i}\).
The vulnerability. The fatal design property is that the hash output is the internal state. There is no finalization step. Knowing \(H(m) = h_{n}\) means knowing the exact state the automaton reached after processing \(m\). An attacker simply continues composing:
\[f_{m'}(h_n) = H(m \| \text{pad} \| m')\]
No knowledge of \(m\) is required—only the state it left behind, which is the published hash.
Why double hashing is a complete fix. \(\text{SHA-256}(\text{SHA-256}(m))\) outputs the internal state of the outer hash computation, not the inner one. To extend the inner chain, an attacker would need \(\text{SHA-256}(m)\)—but they only possess \(\text{SHA-256}(\text{SHA-256}(m))\). Recovering the inner hash requires inverting SHA-256: a preimage attack at cost \(O(2^{256})\). The outer hash severs the semigroup chain completely.
Two kinds of algebraic security. This chapter uses two algebraic structures whose security properties point in opposite directions:
Both structures are algebraic, but they protect different things in different ways. Bitcoin layers them: SHA-256d compresses transaction data into a fixed-size digest; ECDSA proves knowledge of a private key by signing that digest over an elliptic curve group.
When OP_CHECKSIG executes (Chapter 2, Section 2.5), it must compute the message that was signed. For pre-SegWit transactions, this follows the legacy sighash algorithm.
But first, let's see why we need an algorithm at all. The problem is a circular dependency: the signature lives inside the transaction, but it must sign a hash of the transaction. You can't hash the bytes until you know the signature, and you can't produce the signature until you've hashed the bytes:
The algorithm below performs this replacement step by step.
Start with a complete copy of the spending transaction—our Block 170 transaction, all 275 bytes.
Set the scriptSig of every input to empty (zero-length). If the transaction had multiple inputs, each one's scriptSig would become a zero-length field with a varint of 00.
For the input being validated (input 0 in our case), replace the empty scriptSig with the subscript—the scriptPubKey of the UTXO being spent. For our transaction, this is the Block 9 coinbase output's P2PK script:
41 04 11 db 93 e1 dc db 8a 01 6b 49 84 0f 8c 53
bc 1e b6 8a 38 2e 97 b1 48 2e ca d7 b1 48 a6 90
9a 5c b2 e0 ea dd fb 84 cc f9 74 44 64 f8 2e 16
0b fa 9b 8b 64 f9 d4 c0 3f 99 9b 86 43 f6 56 b4
12 a3 ac
This is Satoshi's public key followed by OP_CHECKSIG—the locking script that protects the 50 BTC coinbase output.
Append the SIGHASH flag as a 4-byte little-endian integer. For SIGHASH_ALL (0x01):
01 00 00 00
0100000001c997a5...cd37040000000047 3044...0901ffffffff02 ...outputs...000000000100000001c997a5...cd37040000000043 4104...a3acffffffff02 ...outputs...0000000001000000The modified transaction—with the scriptSig replaced by the subscript and the SIGHASH type appended—is 274 bytes:
01 00 00 00
01
c9 97 a5 e5 6e 10 41 02 fa 20 9c 6a 85 2d d9 06
60 a2 0b 2d 9c 35 24 23 ed ce 25 85 7f cd 37 04
00 00 00 00
43
41 04 11 db 93 e1 dc db 8a 01 6b 49 84 0f 8c 53
bc 1e b6 8a 38 2e 97 b1 48 2e ca d7 b1 48 a6 90
9a 5c b2 e0 ea dd fb 84 cc f9 74 44 64 f8 2e 16
0b fa 9b 8b 64 f9 d4 c0 3f 99 9b 86 43 f6 56 b4
12 a3 ac
ff ff ff ff
02
00 ca 9a 3b 00 00 00 00
43
41 04 ae 1a 62 fe 09 c5 f5 1b 13 90 5f 07 f0 6b
99 a2 f7 15 9b 22 25 f3 74 cd 37 8d 71 30 2f a2
84 14 e7 aa b3 73 97 f5 54 a7 df 5f 14 2c 21 c1
b7 30 3b 8a 06 26 f1 ba de d5 c7 2a 70 4f 7e 6c
d8 4c ac
00 28 6b ee 00 00 00 00
43
41 04 11 db 93 e1 dc db 8a 01 6b 49 84 0f 8c 53
bc 1e b6 8a 38 2e 97 b1 48 2e ca d7 b1 48 a6 90
9a 5c b2 e0 ea dd fb 84 cc f9 74 44 64 f8 2e 16
0b fa 9b 8b 64 f9 d4 c0 3f 99 9b 86 43 f6 56 b4
12 a3 ac
00 00 00 00
01 00 00 00
Compare this to the original transaction from Chapter 1. Two differences:
47304402...0901) has been replaced by the 67-byte scriptPubKey of the UTXO being spent (410411db...a3ac). The varint changed from 48 (72) to 43 (67).01 00 00 00 (SIGHASH_ALL) have been appended after the locktime.Hash the 274-byte preimage with SHA-256d:
\[\begin{aligned} \text{pass 1} &= \text{SHA-256}(\text{preimage}) \\ &= \texttt{4c98270a2b325456} \\ &\quad\; \texttt{4210678c6edff42b} \\ &\quad\; \texttt{5f62c71123387f75} \\ &\quad\; \texttt{f227e04fa6391f3b} \\[6pt] \text{sighash} &= \text{SHA-256}(\text{pass 1}) \\ &= \texttt{7a05c6145f10101e} \\ &\quad\; \texttt{9d6325494245adf1} \\ &\quad\; \texttt{297d80f8f38d4d57} \\ &\quad\; \texttt{6d57cdba220bcb19} \end{aligned}\]Note how completely different the two hashes are: the intermediate value starts with 4c98... and the final sighash starts with 7a05.... Not a single byte in common—this is SHA-256's avalanche effect in action.
This 32-byte sighash is the message that Satoshi's private key signed. The ECDSA signature in the scriptSig—the \((r, s)\) pair we parsed in Chapter 1—is a signature over exactly these 32 bytes.
The sighash and the txid are both SHA-256d hashes of transaction data, but they hash different byte sequences:
The sighash cannot include the signature because the signature is what we're trying to verify. The txid does include the signature—which is why pre-SegWit txids are malleable (Section 3.6).
The last byte of every DER-encoded signature is the SIGHASH flag. Our Block 170 signature uses 0x01 (SIGHASH_ALL), but five other valid flags exist. Before we enumerate them, it helps to understand why there are six in the first place.
A Bitcoin transaction can have many inputs and many outputs. When you sign one of those inputs, your signature does not have to cover the entire transaction. It can be selective—and the SIGHASH flag is how you express that selectivity. Specifically, every signature answers two independent questions:
Now let's walk through what each choice means and—crucially—when you would actually want it.
The default. Your signature covers every output in the transaction: every recipient address, every amount. If anyone changes even one output—redirects a payment, adjusts a value, adds a new recipient—your signature breaks.
This is what you want for an ordinary payment. You're saying: "I authorize spending my coins, and I specify exactly where every satoshi goes. No surprises." Over 99.9% of all Bitcoin signatures use this flag.
Your signature covers the inputs but commits to no outputs at all. In the sighash preimage, the output list is emptied entirely (output count set to zero).
Why would anyone do this? Because sometimes the person authorizing the spend is not the person choosing the destination. Imagine Alice and Bob run a small business together. Alice controls the company's UTXO, but Bob handles payments. Alice signs with SIGHASH_NONE: she authorizes spending the coins but leaves the outputs blank. Bob fills in the recipients and amounts, then broadcasts. Alice trusted Bob to choose wisely—her signature doesn't constrain him.
The danger is obvious: if anyone intercepts this partially-signed transaction before Bob fills it in and broadcasts, they can redirect the funds anywhere. This is a loaded gun with no safety.
The earliest confirmed SIGHASH_NONE transaction on mainnet is 599e47a8...f9ea in Block 178,581 (May 4, 2012).† It is a standard P2PKH transaction with one input (uncompressed key), two outputs, and zero fee. The signer committed to the input but left the outputs unsigned—anyone who intercepted the partially-signed transaction before confirmation could have redirected the funds.
Across the first 800,000 blocks, only 11,367 inputs (0.0009% of all P2PKH signatures) used SIGHASH_NONE—making it the rarest base sighash type by a wide margin.
Your signature covers only the output at the same index as your input. If you're signing input 2, the signature covers output 2—and nothing else. Other outputs can be added, removed, or changed freely.
This is the "I care about my side of the deal" flag. Think of a multi-party transaction where several participants each contribute an input and expect a corresponding output. Alice signs input 0, committing only to output 0 (the payment to her counterparty). Bob signs input 1, committing only to output 1 (his payment). Neither participant's signature constrains the other's output. Each person locks down their own piece of the transaction and leaves the rest open.
The earliest confirmed SIGHASH_SINGLE transaction is e81298f2...0224 in Block 233,999 (May 1, 2013).† It is a P2PKH transaction with one input (16,515,733 sats), one output (25,000 sats), and the remaining 16,490,733 sats (0.165 BTC) lost as fees—likely an accident by someone experimenting with non-standard sighash types. Across 800,000 blocks, only 2,385 inputs ever used bare SIGHASH_SINGLE, making it the rarest of all six standard types.
If an input's index exceeds the number of outputs (e.g., input 1 when there is only 1 output at index 0), the sighash computation does not fail. Instead, Bitcoin Core's SignatureHash() returns the value 1—a 256-bit integer whose 32-byte little-endian encoding is 01 00 00 00 … 00. The signature signs this known constant, meaning anyone can forge a valid signature for that input.
Peter Todd demonstrated this on mainnet in Block 247,939 (July 22, 2013) with transaction 315ac7d4...619f:† two inputs both using SIGHASH_SINGLE, but only one output. Input 0 signs output 0 (valid). Input 1 has no corresponding output and signs the constant hash instead—its signature is forgeable by anyone. Todd created this transaction to prove that alternative implementations (bitcoin-ruby, libbitcoin) incorrectly rejected it, causing a consensus fork from the reference client. As he wrote: "I'll bet if you asked Satoshi himself what he thought would happen, he would say the transaction would be rejected. Sure, it's a bug, yet because Bitcoin relies on 100% consensus, we can't 'fix' that behavior now."
This bug is a consensus rule. It cannot be removed without a hard fork. Wallet software must never create SIGHASH_SINGLE transactions where any input lacks a corresponding output.
Now we come to the second question: who is paying?
Notice something about the three base types above. ALL, NONE, and SINGLE differ in how they treat outputs, but they all treat inputs the same way: the signature commits to every input in the transaction. If someone adds a new input, removes an existing one, or changes the order—any signature using a bare base type breaks.
This means the set of participants is locked. Once you sign, the transaction's input list is frozen. No one else can contribute funds after the fact.
For a standard payment, that's exactly what you want. But what about a transaction that's meant to be collaborative—one where multiple parties independently contribute inputs to achieve a shared goal?
That is what ANYONECANPAY (0x80) enables. It is a single-bit modifier that flips the input dimension: instead of committing to all inputs, your signature commits to only your own input. Everyone else's inputs are excluded from the sighash preimage entirely. Other parties can freely add their own inputs (with their own signatures) without breaking yours.
The name says it all: anyone can pay. Your signature says "I'm putting my coins on the table," but it makes no demands about who else joins the transaction.
ANYONECANPAY is combined with a base type by ORing the high bit: 0x80 | 0x01 = 0x81, 0x80 | 0x02 = 0x82, 0x80 | 0x03 = 0x83. This gives three new flags, for a total of six:
| Flag | Hex | Inputs covered | Outputs covered |
|---|---|---|---|
| ALL | 0x01 | All | All |
| NONE | 0x02 | All | None |
| SINGLE | 0x03 | All | One (matching index) |
| ALL|ANYONECANPAY | 0x81 | Mine only | All |
| NONE|ANYONECANPAY | 0x82 | Mine only | None |
| SINGLE|ANYONECANPAY | 0x83 | Mine only | One (matching index) |
Each of the six combinations enables a distinct class of transaction. The best way to understand them is through concrete scenarios:
ALL (0x01) — Standard payment.NONE (0x02) — Blank check.SINGLE (0x03) — My output only.ALL|ANYONECANPAY (0x81) — Crowdfunding pledge.0x81. The coordinator collects all the pledges, combines them into a single transaction with many inputs all funding the same output, and broadcasts. Every backer's signature remains valid because each committed to the outputs but not to the other backers' inputs. If the goal isn't reached, the coordinator simply never broadcasts—nobody's coins move.NONE|ANYONECANPAY (0x82) — Unconditional donation.SINGLE|ANYONECANPAY (0x83) — Open offer / atomic trade.0x83 and publishes the partial transaction. Bob sees the offer, adds his own input (0.5 BTC worth plus fees), adds an output claiming Alice's UTXO, and broadcasts. Alice's signature is still valid—it never cared about Bob's input or Bob's output, only about her side of the exchange. This enables trustless peer-to-peer trading without an intermediary.A BigQuery analysis of all standard P2PKH inputs across the first 800,000 blocks† reveals how overwhelmingly dominant SIGHASH_ALL is:
| Flag | Hex | Count | Share |
|---|---|---|---|
| SIGHASH_ALL | 0x01 | 1,251,011,783 | 99.913% |
| ALL|ANYONECANPAY | 0x81 | 1,002,042 | 0.080% |
| NONE|ANYONECANPAY | 0x82 | 66,500 | 0.005% |
| SIGHASH_NONE | 0x02 | 11,367 | 0.001% |
| SINGLE|ANYONECANPAY | 0x83 | 3,454 | <0.001% |
| SIGHASH_SINGLE | 0x03 | 2,385 | <0.001% |
Over 1.25 billion inputs used SIGHASH_ALL. The non-default types combined account for fewer than 1.1 million—less than one in a thousand. But notice something in the ranking: the three ANYONECANPAY variants (0x81, 0x82, 0x83) each see more use than their bare counterparts (0x02, 0x03). SIGHASH_NONE has only 11,367 uses, but NONE|ANYONECANPAY has 66,500. Bare SINGLE has 2,385, but SINGLE|ANYONECANPAY has 3,454. The pattern: when people deviate from ALL, they usually want collaborative multi-party inputs, not just flexible outputs.
Of the six sighash combinations, ALL|ANYONECANPAY (0x81) is the most popular non-default flag—over one million uses across Bitcoin's first 800,000 blocks. Its story is the story of Bitcoin's most ambitious attempt at decentralized crowdfunding.
In June 2012, Gregory Maxwell—then a prolific Bitcoin developer and future Blockstream CTO—posted to BitcoinTalk outlining how Bitcoin's sighash flags could implement what economists call a dominant assurance contract.† The idea came from game theorist Alex Tabarrok: a mechanism where pledgers contribute toward a public good, but their money is committed only if the funding goal is reached—otherwise, nobody pays. Maxwell realized that SIGHASH_ALL|ANYONECANPAY was precisely this mechanism, already built into Bitcoin's scripting system from day one.
The concept is elegant:
0x81. The signature commits to all outputs (the funding goal) but only their own input (not other pledgers' inputs).Two years later, Mike Hearn—a former Google engineer and Bitcoin Core developer—turned Maxwell's theoretical sketch into working software. At the Bitcoin 2014 conference in Amsterdam, Hearn announced Lighthouse: a desktop application that let anyone create a crowdfunding campaign on Bitcoin, powered entirely by SIGHASH_ALL|ANYONECANPAY signatures.† Built on the bitcoinj library, Lighthouse presented a user-friendly interface: project creators set a goal and a deadline, pledgers clicked a button to contribute, and the protocol handled the 0x81 signatures invisibly.
Lighthouse was, in many ways, a proof of concept for the idea that Bitcoin's scripting system contained capabilities far beyond simple payments. A Kickstarter without Kickstarter—no intermediary, no platform fee, no counterparty risk. The atomicity was cryptographic, not contractual: either everyone pays and the project is funded, or no one pays and nothing happens.
Several projects were funded through Lighthouse on mainnet during 2014–2015. But the application struggled to gain traction beyond the developer community. The user experience demanded running a full desktop app; the funding campaigns required manual coordination; and the Bitcoin ecosystem at the time was consumed by the block size debate that would eventually tear the community apart.
In January 2016, Mike Hearn published a blog post titled "The resolution of the Bitcoin experiment,"† declaring Bitcoin a failed experiment and selling all his coins. He left the project—and Lighthouse died with his departure. The code remains on GitHub, archived and unmaintained.
But the 0x81 mechanism lives on. On Bitcoin Cash, the Flipstarter platform (2020–present) implemented the same assurance-contract pattern and has successfully funded dozens of BCH development projects.† On Bitcoin itself, the one million 0x81 signatures scattered across the blockchain are a quiet testament to the fact that Satoshi embedded collaborative multi-party transaction capabilities into the protocol from the very first line of code—capabilities that, to this day, most Bitcoin users have never heard of.
Five months after Maxwell's BitcoinTalk post, someone tested the mechanism for real. Block 207,733 (November 13, 2012) contains the earliest confirmed SIGHASH_ALL|ANYONECANPAY transaction on Bitcoin mainnet:†
01000000 02 f6044c0a d485f633 b41f97d0 d793eb28 37ae40f7 38ff6d5f 50fdfd10 528c1d76 01000000 6b 483045 02205853 c7f13957 85bfabb0 3c57e962 eb076ff2 4d8e4e57 3b04db13 b45ed3ed 6ee20221 009dc82a e43be9d4 b1fe2847 754e1d36 dad48ba8 01817d48 5dc529af c516c2dd b481 2103 05584980 367b321f ad7f1c1f 4d5d723d 0ac80c1d 80c8ba12 34396548 364537a ffffffff 9c6af0df 6669bcde d19e317e 25bebc8c 78e48df8 ae1fe02a 7f030818 e71ecd40 01000000 6c 493046 02210082 69c9d7ba 0a7e730d d16f4082 d29e3684 fb7463ba 064fd093 afc170ad 6e038802 2100bc6d 76373916 a3ff6ee4 1b2c7520 01fda3c9 e048bcff 0d81d05b 39ff0f42 17b281 21 03aae303 d8254215 45c5bc7c cd5ac87d d5add3bc c3a432ba 7aa2f266 1699f9f6 59 ffffffff 01 e093 04000000 0000 19 76a914 5c11f917 883b 927eef77 dc57707a eb853f6d 3894 88ac 00000000
Field | Value | Key Detail
Input 0 | 1D9vyX...W87 (200,000 sats) | Sighash: 81
Input 1 | 137Co4...wys (200,000 sats) | Sighash: 81
Output 0 | 19PphS...r83 (300,000 sats) | P2PKH
Fee | 100,000 sats (293 sat/byte) |
This is an assurance contract in the wild. Two parties each contributed 200,000 satoshis, pooled into a single 300,000-sat output (the remaining 100,000 going to fees—high by modern standards, but this was 2012 and the experimenters likely considered it the cost of testing). Each signer committed to the same output but only their own input. The coordinator—whoever assembled and broadcast the final transaction—could not have altered the destination without invalidating both signatures.
Look at the sighash bytes. Input 0's signature ends with ...b4 81, and Input 1's ends with ...b2 81. In both cases, the final byte before the pubkey push is 0x81—not 0x01. That single bit flip in the high nibble (0x80 | 0x01 = 0x81) is the entire difference between "I lock down every input" and "anyone can pay."
Before this transaction was broadcast, it existed as an incomplete artifact—a partially signed transaction with room for more inputs. Here is what it looked like after Pledger A signed but before Pledger B joined:
01000000 Version 1
01 1 input (only Pledger A so far)
f6044c0a d485f633 b41f97d0 d793eb28 Prev txid (Pledger A's UTXO)
37ae40f7 38ff6d5f 50fdfd10 528c1d76
01000000 Prev vout: 1
6b ScriptSig: 107 bytes
48 3045...ddb4 81 72-byte sig, sighash 0x81
21 0305...537a 33-byte compressed pubkey
ffffffff Sequence
01 1 output
e093040000000000 300,000 sats (0.003 BTC)
19 76a914 5c11f917...6d3894 88ac P2PKH to 19PphS...r83
00000000 Locktime
Now Pledger B signs their own input with 0x81 and hands it to the coordinator. The coordinator inserts it:
01000000
02 <-- input count changes: 01 -> 02
[Pledger A's input] 107-byte scriptSig, sighash 0x81
(UNCHANGED -- signature still valid)
[Pledger B's input] 108-byte scriptSig, sighash 0x81
9c6af0df 6669bcde... Prev txid (Pledger B's UTXO)
01000000 Prev vout: 1
6c ScriptSig: 108 bytes
49 3046...b281 73-byte sig, sighash 0x81
21 03aa...f659 33-byte compressed pubkey
ffffffff Sequence
01 e093040000000000 Output (UNCHANGED)
19 76a914...88ac
00000000 Locktime
Now the math works: \(200,000 + 200,000 = 400,000\) input satoshis, covering the \(300,000\)-sat output with \(100,000\) left for fees. The coordinator broadcasts. Block 207,733 confirms it.
Had the coordinator tried to change the output—redirect the 300,000 sats to a different address, or alter the amount—both signatures would have broken, because both committed to all outputs via the ALL half of 0x81. The pledgers trusted no one with the destination; they only left the door open for more contributors.
To see exactly what ALL|ANYONECANPAY does at the byte level, compare it to the standard SIGHASH_ALL preimage from Section 3.2. Recall that the sighash preimage is a modified copy of the transaction, serialized and double-hashed to produce the 32-byte message that gets signed.
With SIGHASH_ALL (0x01), the preimage includes every input and every output:
[version] [input_count=N] [input_0] [input_1] ... [input_N-1]
[output_count=M] [output_0] [output_1] ... [output_M-1]
[locktime] [01000000] <-- sighash type (4 bytes, LE)
With ALL|ANYONECANPAY (0x81), the input list is replaced with only the signer's own input:
[version] [input_count=1] [my_input_only]
[output_count=M] [output_0] [output_1] ... [output_M-1]
[locktime] [81000000] <-- sighash type (4 bytes, LE)
01 regardless of how many inputs the final transaction contains.When the coordinator assembles the final transaction with five pledgers' inputs, each signature validates against a preimage that contains only that pledger's input plus the shared outputs. The signatures are composable—they can be combined in any order, and adding a sixth pledger doesn't invalidate the first five.
The final sighash type field is 81 00 00 00—the four-byte little-endian encoding of \(0x81 = 129\), which is 128 + 1 = ANYONECANPAY | ALL.
The sighash is the 32-byte message. The private key produces an ECDSA signature over it.
The Elliptic Curve Digital Signature Algorithm was proposed by Scott Vanstone in 1992 and standardized as ANSI X9.62 in 1998.† The key insight was that elliptic curve groups offered the same security as RSA and classical DSA but with dramatically smaller keys: a 256-bit elliptic curve key provides comparable security to a 3,072-bit RSA key. This mattered enormously for Bitcoin, where every signature is stored on-chain forever. A 3,072-bit RSA signature would be roughly 384 bytes—five times larger than the 71-byte ECDSA signatures in our Block 170 specimen. Satoshi's choice of ECDSA on secp256k1 was not just a cryptographic decision; it was an economic one.
Before tracing the algorithm, we need the curve parameters.
Bitcoin uses the elliptic curve secp256k1, defined by \(y^{2} = x^{3} + 7\) over a prime field (Chapter 1). The full parameter set:
n = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF EBAAEDCE6AF48A03BBFD25E8CD0364141
This is the number of distinct private keys and the modulus for all signature arithmetic.
79BE667EF9DCBBAC55A06295CE870B07 029BFCDB2DCE28D959F2815B16F81798
Satoshi chose secp256k1 over the more common NIST curves (P-256, etc.). The choice was prescient: secp256k1's parameters are "nothing up my sleeve" numbers derived from simple constants, while the NIST curves use seed values whose origin has never been fully explained. After the 2013 Dual_EC_DRBG scandal revealed that the NSA had backdoored at least one NIST cryptographic standard, Satoshi's distrust of government-selected parameters looked increasingly wise.
Given private key \(d\), message hash \(z\) (the sighash), and curve order \(n\):
The security of ECDSA depends entirely on the nonce \(k\) being:
If the same nonce \(k\) is used to sign two different messages \(z_{1}\) and \(z_{2}\), both signatures will have the same \(r\) value (since \(r = x_{k}G\)). An attacker can then compute: \[ d = \frac{s_1 z_2 - s_2 z_1}{s_2 r_1 - s_1 r_2} \bmod n \] and recover the private key. This is not a theoretical concern: in 2013, a flaw in Android's SecureRandom caused nonce reuse, and attackers drained Bitcoin wallets by recovering private keys from the blockchain.† Sony's PlayStation 3 signing key was also compromised by nonce reuse in 2010.
Bitcoin Core has used deterministic nonces (RFC 6979) since version 0.9.0 (2014), eliminating this risk for compliant wallets.
RFC 6979† (authored by Thomas Pornin, 2013) eliminates the need for a random number generator during signing. Instead of choosing \(k\) randomly, it derives \(k\) deterministically: \[ k = \text{HMAC-DRBG}(d, z) \] where \(d\) is the private key and \(z\) is the message hash. The HMAC-DRBG construction (a deterministic random bit generator using HMAC as its core) produces output that is indistinguishable from random to anyone who doesn't know \(d\).
This has two crucial properties:
This means a hardware wallet with no random number generator at all—no entropy source, no /dev/urandom, nothing—can still produce secure ECDSA signatures. The private key and message provide all the entropy needed.
Given public key \(Q = dG\), message hash \(z\), and signature \((r, s)\):
Substituting \(Q = dG\) and expanding:
\[\begin{aligned} R' &= u_1 G + u_2 Q = z s^{-1} G + r s^{-1} (dG) \\ &= s^{-1}(z + rd)G = s^{-1}(sk)G = kG = R \end{aligned}\]The last step uses \(s = k^{-1}(z + rd)\), so \(sk = z + rd\), hence \(s^{-1}(z+rd) = k\). The verifier reconstructs the original point \(R = kG\) without ever knowing \(k\) or \(d\).
This is the operation that OP_CHECKSIG performs in step 6 (Chapter 2).
Let's connect this abstract algorithm to our actual specimen. When a node validates the Block 170 transaction, OP_CHECKSIG receives:
04 11db93e1… f656b4127a05c6145f10101e… 220bcb19The verifier computes \(u_{1} = z \cdot s^{-1} \pmod{n}\) and \(u_{2} = r \cdot s^{-1} \pmod{n}\) (both 256-bit modular arithmetic), then performs two elliptic curve scalar multiplications and one point addition to get \(R' = u_{1} G + u_{2} Q\). If the \(x\)-coordinate of \(R'\) equals \(r\), the signature is valid. This entire process takes a few milliseconds on modern hardware—and every full node on the Bitcoin network performed exactly this computation when Block 170 arrived in January 2009.
The entire security of Bitcoin rests on the hardness of the elliptic curve discrete logarithm problem: given \(Q = dG\), computing \(d\) is infeasible with classical computers.
Shor's algorithm, running on a sufficiently large quantum computer, could solve the ECDLP in polynomial time—recovering a private key from a public key. This would break every P2PK output on the blockchain (including Satoshi's coins, whose public keys are exposed in the scriptPubKey). P2PKH outputs are partially protected: the public key is hashed, and a quantum attacker would need to break both ECDLP and the hash function. For a comprehensive treatment of the mathematical progression from classical number theory through quantum computing to Shor's algorithm, see The Quantum Threat: A Mathematical Journey from Arithmetic to Shor's Algorithm (Hirschfield, 2026).
Chapter 1 traced the DER structure of our specimen's signature. Here we formalize the encoding rules that apply to every pre-Taproot Bitcoin signature:
Here is our Block 170 specimen's actual DER-encoded signature, byte by byte:
30 44 02 20 4e 45 e1 69 32 b8 af 51 49 61 a1 d3 a1 a2 5f df
3f 4f 77 32 e9 d6 24 c6 c6 15 48 ab 5f b8 cd 41
02 20 18 15 22 ec 8e ca 07 de 48 60 a4 ac dd 12 90 9d
83 1c c5 6c bb ac 46 22 08 22 21 a8 76 8d 1d 09
01
| Bytes | Value | Meaning |
|---|---|---|
30 | SEQUENCE tag | Outer DER container |
44 | 68 (decimal) | Sequence content length |
02 | INTEGER tag | First integer (\(r\)) |
20 | 32 (decimal) | \(r\) is 32 bytes (no padding: 0x4e \(<\) 0x80) |
4e45…cd41 | \(r\) value | 32 bytes |
02 | INTEGER tag | Second integer (\(s\)) |
20 | 32 (decimal) | \(s\) is 32 bytes (no padding: 0x18 \(<\) 0x80) |
1815…1d09 | \(s\) value | 32 bytes |
01 | SIGHASH_ALL | Appended outside DER structure |
The encoding rules:
0x30).0x02).0x80), a leading 0x00 byte is prepended, increasing the length by 1. In our specimen, neither \(r\) (0x4e) nor \(s\) (0x18) has its high bit set, so both are exactly 32 bytes.This variable-length encoding is why the DER signature structure ranges from 70 to 72 bytes: each of \(r\) and \(s\) is 32 or 33 bytes depending on the high bit, plus 6 bytes of DER overhead (tags and lengths). Add the 1-byte SIGHASH flag appended outside the DER structure, and the total data pushed into the scriptSig ranges from 71 to 73 bytes. Our Block 170 specimen has \(r = 32\) bytes and \(s = 32\) bytes (neither has a high bit set), so the DER structure is 70 bytes and the total push is 71 bytes.
In early Bitcoin, the signature parsing was lenient—non-standard DER encodings (extra padding, wrong length bytes) were accepted. This created a malleability vector: anyone could take a valid transaction, re-encode its signature with different padding, and change the txid without invalidating the transaction.
BIP 66† (July 2015) introduced strict DER as a consensus rule: signatures must conform exactly to the DER specification. Non-conforming signatures are now invalid by consensus. This was one of several steps toward reducing transaction malleability, culminating in SegWit.
A transaction's txid is the hash of the entire serialized transaction, including the scriptSig. But the scriptSig contains the signature, and signatures have inherent flexibility:
OP_0 OP_DROP) can be added to the scriptSig without affecting validation.Any of these changes alters the scriptSig bytes, which changes the txid—even though the transaction remains valid and spends the same coins to the same outputs.
Why does this matter? Because other transactions might reference this txid. If Alice sends coins to Bob in transaction A, and Bob immediately spends them in transaction B (which references A's txid as an input), a malleated version of A with a different txid would invalidate B. Bob's transaction points to a txid that no longer exists.
This was not a theoretical problem. In February 2014, the Mt. Gox exchange blamed transaction malleability for the loss of approximately 850,000 BTC (worth $450 million at the time).† While the actual causes of Mt. Gox's collapse were more complex, malleability attacks were real and documented.
The fix came in two stages:
The legacy sighash algorithm has a critical performance flaw: it hashes the entire transaction once per input. For a transaction with \(n\) inputs, this means \(O(n^{2})\) hashing work—each of the \(n\) inputs requires hashing a modified version of the full transaction, including all \(n\) inputs.
For typical transactions (1–5 inputs), this is negligible. But adversarial transactions can exploit it: a transaction with 10,000 inputs requires 100 million hash operations to validate, creating a denial-of-service vector.
BIP 143† (introduced with SegWit) replaces the legacy algorithm with a new sighash that uses precomputed components:
hashPrevouts: SHA-256d of all input outpoints (txid:vout), computed once.hashSequence: SHA-256d of all input sequence numbers, computed once.hashOutputs: SHA-256d of all outputs (value + scriptPubKey), computed once.These three digests are computed once and reused for every input. Each input's sighash then combines the precomputed hashes with the input-specific data (outpoint, script, value, sequence). Total hashing work: \(O(n)\) instead of \(O(n^{2})\).
BIP 143 also fixes another legacy deficiency: the sighash preimage includes the value of the input being spent (in satoshis). The legacy algorithm does not—it only includes the scriptPubKey. This means hardware wallets verifying a legacy transaction must separately look up each input's value, which is impractical. With BIP 143, the value is committed to in the sighash, and the hardware wallet can verify it directly.
We'll see BIP 143 in action in Chapter 8 when we parse our first SegWit transaction.
With Chapters 1, 2, and 3, we have the complete toolkit for parsing Bitcoin transactions:
Part II applies these tools to Bitcoin's historical transaction types, starting with P2PK (the type we've been analyzing) and progressing through P2PKH, P2SH, and bare multisig. Each chapter will introduce a new specimen from the blockchain and parse it with the same byte-by-byte approach—but now you'll understand not just what the bytes mean, but why they're there and how the cryptographic machinery behind them works.
0x01 is called SIGHASH_ALL. What does "all" refer to?hashlib, OpenSSL, or an online calculator). Confirm you get 7a05c614...220bcb19.0x00FF... (first byte \(\geq\) 0x80), write the complete DER INTEGER encoding. How many bytes does it use?01 00 … 00 (32 bytes) when the input index exceeds the output count. Verify: if you know the "message" is always this constant, what does that imply about the security of the signature?L1. Two changes: (1) the scriptSig of the input being signed is replaced with the scriptPubKey of the UTXO being spent (the "subscript"), and (2) the SIGHASH flag is appended as a 4-byte little-endian integer after the locktime.
L2. "All" refers to all inputs and all outputs. The signature commits to the complete transaction structure: every input's outpoint and sequence, and every output's value and scriptPubKey. Changing any of them invalidates the signature.
L3. False. The txid hashes the original complete transaction (including the scriptSig with the signature). The sighash hashes a modified version where the scriptSig is replaced with the subscript and the SIGHASH type is appended. They are different byte sequences and produce different hashes.
L4. The private key is exposed. If two signatures \((r, s_{1})\) and \((r, s_{2})\) share the same \(r\) (which implies the same nonce \(k\)), an attacker can compute \(d = (s_{1} z_{2} - s_{2} z_{1})/(s_{2} r - s_{1} r) \pmod{n}\) and recover the private key.
L5. Because of DER encoding's minimal-encoding rule for integers. Each component (\(r\) and \(s\)) is 32 bytes if its leading byte is \(<\) 0x80, or 33 bytes if the leading byte is \(\geq\) 0x80 (a zero byte is prepended to keep the integer positive). The DER overhead is fixed at 6 bytes (SEQUENCE tag + length, two INTEGER tags + lengths). The SIGHASH flag adds 1 byte outside the DER structure. The total:
| \(r\) | \(s\) | DER | DER + SIGHASH |
|---|---|---|---|
| 32 B | 32 B | 70 B | 71 B |
| 32 B | 33 B | 71 B | 72 B |
| 33 B | 32 B | 71 B | 72 B |
| 33 B | 33 B | 72 B | 73 B |
Our Block 170 specimen has \(r = 32\) bytes and \(s = 32\) bytes, so the scriptSig pushes 71 bytes (70 DER + 1 SIGHASH).
H1. Using Python:
import hashlib
preimage = bytes.fromhex("0100000001c997a5e5...01000000")
h = hashlib.sha256(hashlib.sha256(preimage).digest()).digest()
print(h.hex())
# Expected: 7a05c6145f10101e9d6325494245adf1
# 297d80f8f38d4d576d57cdba220bcb19
(Use the full 274-byte preimage from the chapter.)
H2. For a two-input transaction with SIGHASH_ALL:
00). Append 01000000.01000000.Each input's sighash is computed independently. The preimage differs in which scriptSig is replaced and which is zeroed.
H3. If \(r\) = 00FF... (33 bytes with leading zero):
02 (INTEGER)21 (33 in decimal)00 FF ... (33 bytes, the leading 00 prevents the high bit of FF from making the integer negative)Total: \(2 + 33 = 35\) bytes for this integer. Without the high-bit issue, it would be \(2 + 32 = 34\) bytes.
H4. If the sighash is always the constant 01 00 00 …\ 00, then every signature for this input signs the same "message." This means that any valid signature for this public key on this constant is valid. An attacker who obtains any signature from this key on this message—from any transaction that triggered the bug—can reuse that signature. Worse, the constant is known to everyone, so an attacker can generate a valid signature if they have the private key for any input that uses SIGHASH_SINGLE with an out-of-range index. This effectively makes such inputs "anyone can spend" if any such signature has ever been published.
P1. The sighash computation takes the transaction bytes and performs two modifications: (a) replaces the scriptSig with the subscript (scriptPubKey), and (b) appends the SIGHASH type. The scriptSig contains the DER-encoded signature—but this signature is removed in step (a) and replaced with the subscript. Therefore, the sighash preimage does not contain the signature. The hash of the preimage (the sighash) is then compared against the signature via ECDSA verification.
Dependency chain: sighash \(←\) preimage \(←\) (transaction \(-\) scriptSig \(+\) subscript \(+\) SIGHASH type). The signature is in the scriptSig, which is removed. No circularity.
P2. For the legacy algorithm, each of \(n\) inputs requires:
Total: \(n\) inputs \(\times \) \(O(m)\) per input \(= O(n \cdot m)\). Since \(m \geq O(n)\) (each input contributes at least 41 bytes), this is \(O(n^{2})\) in the worst case.
BIP 143 precomputes hashPrevouts, hashSequence, and hashOutputs—each is a single pass over the transaction data, totaling \(O(m)\). Each input's sighash then combines fixed-size components (the three precomputed hashes plus input-specific data), requiring \(O(1)\) hashing per input. Total: \(O(m) + n \cdot O(1) = O(m)\).
P3. The secp256k1 curve has order \(n\) (a 256-bit prime). For any \(s ∈ [1, n-1]\), define \(s' = n - s\). Then \(s + s' = n \equiv 0 \pmod{n}\), so \(s' ∈ [1, n-1]\).
If \(s \leq n/2\), then \(s' = n - s \geq n/2\). If \(s > n/2\), then \(s' < n/2\). Since \(n\) is odd (it's prime and \(> 2\)), \(n/2\) is not an integer, so \(s \neq n/2\), and exactly one of \(s, s'\) is \(< n/2\).
Both \((r, s)\) and \((r, s')\) are valid signatures because ECDSA verification checks \(x_{R}' = r\) where \(R'\) depends on \(s^{-1}\), and \((n-s)^{-1} = -(s^{-1})\), which merely negates the \(y\)-coordinate of \(R'\) without changing the \(x\)-coordinate.
Requiring \(s \leq n/2\) (the "low-\(s\)" rule) means there is exactly one valid encoding for every signature. A third party cannot flip \(s\) to \(n - s\) to change the scriptSig bytes (and thus the txid) while keeping the signature valid.
C1. Key differences between Schnorr (BIP 340†) and ECDSA:
Linearity matters for multisig because it makes \(n\)-of-\(n\) multisig indistinguishable from a single-key spend on-chain—better privacy and lower fees.
C2. The Mt. Gox incident primarily involved \(s\)-value malleation: attackers took valid withdrawal transactions, flipped \(s\) to \(n - s\) (both valid), re-broadcast the malleated version, and when it confirmed first, the txid changed. Mt. Gox's system tracked withdrawals by txid, so it believed the original transaction had failed and re-issued the withdrawal. This allowed attackers to receive double payouts.
SegWit would have prevented this entirely: the signature moves to the witness, which is excluded from the txid hash. Changing the witness changes the wtxid but not the txid, so Mt. Gox's tracking system would not have been fooled.
However, Mt. Gox's problems went far beyond malleability: poor accounting practices, alleged internal theft by CEO Mark Karpelès (later convicted of data manipulation in Japan), and a years-long undetected hot wallet drain that predated the malleability attacks. Malleability was the visible symptom, not the root cause.
B1. In P2PKH, the scriptPubKey is OP_DUP OP_HASH160 OP_PUSHBYTES_20 <20-byte hash> OP_EQUALVERIFY OP_CHECKSIG (25 bytes). This becomes the subscript in the sighash preimage—instead of the 67-byte P2PK scriptPubKey, the sighash uses the 25-byte P2PKH scriptPubKey. Everything else about the sighash algorithm remains identical. The preimage is shorter because the subscript is shorter.
B2. A P2PKH address encodes three things:
0x00 for mainnet P2PKH).OP_HASH160 applied to the public key.The concatenation (version \(+\) hash \(+\) checksum \(=\) 25 bytes) is then encoded in Base58—a character set that excludes visually ambiguous characters (0/O/I/l)—producing the familiar "1…" addresses:
1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
Chapter 5 traces this derivation byte by byte.