In this article
- TL;DR
- What "SHA-256 was broken" actually means
- How Merkle-Damgård works
- How length extension works
- Running the attack yourself
- Why length extension never reaches Bitcoin
- HMAC, the fix for everyone else
- Why Bitcoin stayed on SHA-256, not SHA-3
- Quantum, Grover, and SHA-256
- Where SHA-256 fails on passwords
- Where SHA-256 lives inside Bitcoin
- The 2026 verdict, by use case
- Further reading
- Disclaimer
TL;DR
I work in the crypto self-custody space, and people regularly send me "SHA-256 is broken" threads asking whether their cold storage is at risk. It is not. The attack behind most of those threads is length extension, and I ran it on 11 October 2026 with a public demo: the forged token passed, and it failed once the verifier hashed twice. Bitcoin is not exposed, because its consensus code hashes public data and its block, transaction and Merkle hashes use double SHA-256. Outside Bitcoin the standard fix is HMAC (RFC 2104). Grover's algorithm (Grover 1996) cuts a SHA-256 preimage search from 2²⁵⁶ to about 2¹²⁸ steps, which in my view stays out of reach.
What "SHA-256 was broken" actually means
A specific attack works against SHA-256 in a specific setting, and the setting gets lost when the news travels. A write-up such as Sylvain Kerkour's shows the attack against a home-made token scheme. By the time the story reaches a Bitcoin holder, it reads "Bitcoin is in danger."
Bitcoin is not in danger. When this comes up, the person asking usually holds coins in cold storage, and the cold storage is fine. The thing that should worry them is how SHA-256 gets misused in ordinary web software.
The attack is called length extension. It is real, and you can run it yourself in a few minutes. Every other "SHA-256 broken" claim I have seen falls into one of three groups: length extension, which does not reach Bitcoin; reduced-step academic cryptanalysis, which does not reach the full function; or SHA-256 used for password storage, which is a design failure, not an algorithm failure.
You can run the attack yourself against a deliberately vulnerable demo, then watch it fail when the verifier switches to Bitcoin's double hash. The steps are in the section on running the attack.
How Merkle-Damgård works
SHA-256 belongs to the SHA-2 family, and every member uses the Merkle-Damgård construction. Understanding it takes a minute, and that minute makes length extension obvious.
A Merkle-Damgård hash pads the message and cuts it into fixed blocks, 512 bits (64 bytes) for SHA-256 (FIPS 180-4). It starts from a fixed initial state, then runs a compression function on each block that mixes the block into the state. After the final block, SHA-256 outputs the state directly as the digest.
That last sentence is the whole problem. The digest is the internal state at the end of the computation. If you know Hash(message), you know the state the compression function reached after message and its padding. You can resume from there.
Length extension exploits exactly that. Given Hash(secret || message), you hold the state reached after secret || message || padding. You resume from that state, append any extra data, and produce a valid hash for the longer input. You never learn secret.
Other designs close this door. SHA-3 (Keccak) uses a sponge and outputs only part of its internal state (FIPS 202). SHA-512/256 truncates the SHA-512 state to 256 bits (FIPS 180-4). BLAKE2 marks the last block with a finalization flag (BLAKE2 paper), and BLAKE3's ROOT flag "prevent[s] length extension" (BLAKE3 specification). SHA-256, the function Bitcoin runs on, has none of these.
Most "SHA-256 is broken" headlines rest on this one structural fact.
How length extension works
The textbook example is a web server that signs API requests as SHA-256(secret || params) and sends the signature with the request:
GET /api?user=alice&role=user&sig=a3f1...
The server checks a request by recomputing SHA-256(secret || "user=alice&role=user") and comparing it with sig. The construction looks fine to anyone who has not studied Merkle-Damgård padding.
The attacker captures one valid (params, sig) pair. They guess the byte length of secret, trying each candidate length in turn. They compute the padding SHA-256 appended to secret || params before the final block: a 1 bit, zeros, then the message length as a 64-bit number (RFC 6234 §4.1). Then they load the captured sig as the SHA-256 state, because that signature is the state after secret || params || padding. From there they keep hashing &role=admin or any other extension and output the result as the forged signature.
The attacker sends:
GET /api?user=alice&role=user[padding bytes]&role=admin&sig=<forged>
The server computes SHA-256(secret || "user=alice&role=user[padding]&role=admin") and gets exactly the forged signature, because the attacker continued the same computation from the same state. The attacker is now admin.
The best-known real case is Thai Duong and Juliano Rizzo's 2009 Flickr API advisory. Flickr signed API calls as MD5 of an 8-byte shared secret followed by the parameters, and the pair showed that an attacker could "send valid arbitrary requests on behalf of any application using Flickr's API". The hash there was MD5, not SHA-256, but the attack is the same, and the advisory says it "works on all Merkle-Damgård hash ... such as MD0-MD5 and SHA0-SHA2". The advisory credits the idea to earlier work, including Gene Tsudik's 1992 paper on message authentication with one-way hash functions.
You need one valid (params, sig) pair and the byte length of the secret. That is the entire attack surface. The developer chose the wrong construction; the SHA-256 algorithm itself did what it promises.
Running the attack yourself
The steps in the HowTo block at the top of this page use magodo/sha256-length-extension-attack-demo, a small Go project. Its server program signs and verifies SHA-256(secret || message), and its attack program forges an extension from a captured hash and a guessed secret length.
I ran it on 11 October 2026 with Go 1.25.12. With the secret 123 and the message user=magodo, the attack program produced a 72-byte forged message ending in &role=admin and a new hash. The server accepted it with exit code 0. The same forgery against a server started with a different secret was rejected.
Then I changed the demo server to hash its SHA-256 output a second time, which is Bitcoin's SHA256d. The same attack produced a hash the server rejected with "invalid hash". The outer hash runs over a fixed 32-byte input, so the attacker has no usable state to extend. That one edit is what Bitcoin does for every block header hash, every transaction ID and every Merkle node.
If you prefer other tools, eid3t1c/Hash_Extender does the same forgery in Python for MD4, MD5, SHA-1, SHA-256 and SHA-512, and iagox86/hash_extender is an older C tool whose repository dates from 2012. Sylvain Kerkour's write-up, dated 24 February 2026, walks through the state recovery byte by byte in Rust.
In my view, watching the forgery pass and then fail against SHA-256(SHA-256(...)) builds more intuition than a diagram of Merkle-Damgård, and it costs you a few minutes.
Why length extension never reaches Bitcoin
Bitcoin computes SHA-256(SHA-256(x)), called SHA256d, for its most important hashes. Block headers are hashed with SHA256(SHA256()), and miners search for a header whose hash is at or below the target (developer reference). Transaction IDs are the SHA256(SHA256()) of the raw transaction (developer reference). Merkle roots pair and double-hash those IDs. Bitcoin Core implements all of this in one class, CHash256, "Bitcoin's 256-bit hash (double SHA-256)" (src/hash.h).
Not every Bitcoin hash is doubled. A P2WSH output commits to a single SHA-256 of its script (BIP 141), and Taproot's Schnorr signatures use tagged hashes of the form SHA256(SHA256(tag) || SHA256(tag) || x) (BIP 340). Those are still safe from length extension, because length extension only forges a MAC built from a secret prefix. These consensus hashes run over public data such as transactions, scripts and keys. Anyone can already compute the hash of any public input, so there is nothing for an extension to forge.
SHA256d adds a second layer. The outer SHA-256 runs over the 32-byte output of the inner one. Someone who knows SHA256d(x) holds the final state of the outer hash, and extending it only gives SHA-256(inner digest || padding || extra), which is not the double hash of any longer input. To get at the inner state, they would have to invert the outer SHA-256, which NIST rates at 256 bits of preimage resistance (SP 800-107 Rev. 1).
Where did SHA256d come from? Zooko, who launched the Tahoe-LAFS storage project, wrote in 2011 that Ferguson and Schneier proposed SHA-256d in Practical Cryptography (2003) to make SHA-256 immune to length extension, and that Tahoe-LAFS used it "for everything" from its launch in 2006. The Bitcoin whitepaper only says the proof-of-work hashes "such as with SHA-256" and gives no reason for doubling. So we cannot prove Satoshi chose SHA256d to stop length extension. The technical fact stands either way: the attack behind the "SHA-256 is broken" headlines does not apply to Bitcoin's consensus hashing.
HMAC, the fix for everyone else
Most software developers will never write SHA256d. They will write HMAC.
HMAC, published by the IETF as RFC 2104 in February 1997 and standardised by NIST as FIPS 198-1, is the standard keyed wrapper for any iterated hash. Given a hash function H such as SHA-256, it is defined as:
HMAC(key, message) = H( (key ⊕ opad) || H( (key ⊕ ipad) || message ) )
ipad is the byte 0x36 and opad the byte 0x5C, each repeated to the block length (RFC 2104). The inner hash absorbs the message. The outer hash hashes the inner result under a different key derivative, so an attacker never sees a state that ends with the message.
The construction looks like SHA256d but takes a key as a first-class input and works with any underlying hash. You meet it all over production systems. TLS 1.3 derives its keys with HKDF (RFC 8446 §7.1), and HKDF is built on HMAC (RFC 5869). The JWT algorithm HS256 is "HMAC using SHA-256" (RFC 7518). AWS Signature Version 4 signs API requests with HMAC-SHA256() (AWS documentation).
If your code computes hash(secret + message) anywhere, replace it with HMAC. The cost is one extra outer hash. In exchange, length extension no longer forges your MACs.
Why Bitcoin stayed on SHA-256, not SHA-3
SHA-3 (Keccak), published by NIST as FIPS 202 in August 2015, uses the sponge construction. Its designers state that "Keccak does not have the length-extension weakness, hence does not need the HMAC nested construction", so you can compute a MAC by prepending the key to the message (Keccak team). NIST also standardised a dedicated SHA-3 MAC, KMAC, in SP 800-185.
In my view Bitcoin still runs on SHA-256 mostly because of path dependence. Proof of work requires each block header hash to be at or below the target (developer reference), so a new mining hash makes blocks that old nodes reject, which is a hard fork. Wallets, block explorers and signature code would all need changes too, and every SHA-256 mining machine would lose its purpose overnight. SHA-3 is also not faster: the BLAKE2 authors measured SHA3-256 taking about 20% longer than SHA-256 to hash a message on Qualcomm's Krait processor (BLAKE2 paper).
The cryptographic argument for staying put is simpler. Length extension, the one structural weakness of SHA-256, has nothing to forge in Bitcoin's consensus hashing. There is no live problem a migration would fix. My view: SHA-3 would have been a defensible choice in 2009, and in 2026 the cost of switching outweighs the benefit.
Quantum, Grover, and SHA-256
Quantum computers do not break SHA-256. The relevant quantum algorithm against a hash function is Grover's, which finds a marked item among N in about √N steps (Grover 1996). For SHA-256 that turns a preimage search of 2²⁵⁶ classical tries into about 2¹²⁸ quantum steps. In my view 2¹²⁸ sequential quantum steps stays far out of reach.
Shor's algorithm is the one that matters, and it does not touch SHA-256. Shor solves discrete logarithms in polynomial time on a large enough quantum computer (Shor 1995), and the method extends to elliptic curves (Proos and Zalka 2003). That breaks the secp256k1 keys behind Bitcoin's ECDSA and Schnorr signatures. Bitcoin's quantum risk lives in the signatures, not in the hash.
The 2026 quantum picture for Bitcoin, including BIP-360, BIP-361 and Dan Robinson's PACTs proposal at Paradigm, is the subject of two separate posts on this site. See BIP-360/361: Quantum-Resistant Bitcoin and Quantum Computing, Bitcoin, and Google's 2026 Announcement. The short version: SHA-256 is fine, and the signatures need a migration.
Harvest now, decrypt later is a signature problem for Bitcoin, not a hash problem. A public key exposed on chain today could be attacked later with Shor's algorithm. A SHA-256 hash recorded today still needs about 2¹²⁸ Grover steps to invert.
Where SHA-256 fails on passwords
Password storage is the one place where "SHA-256 is insecure" is fair, and length extension has nothing to do with it. SHA-256 is too fast. In the published hashcat v6.2.6 benchmark one Nvidia RTX 4090 computed 21,975.5 million SHA-256 hashes per second (Chick3nman's benchmark). Here is what that rate means for passwords drawn at random from the 95 printable ASCII characters, worked out from that one benchmark figure:
| Password length | Combinations | One RTX 4090, worst case |
|---|---|---|
| 8 characters | 6.6 × 10¹⁵ | about 3.5 days |
| 9 characters | 6.3 × 10¹⁷ | about 11 months |
| 10 characters | 6.0 × 10¹⁹ | about 86 years |
Real passwords are rarely random, and attackers try common words and patterns first, so many fall far faster than the table shows. Attackers also rent many GPUs at once, which divides these times. A salt stops precomputed tables but does not slow a brute-force search of one hash.
Password storage needs a function that is deliberately slow and memory-hard, which takes away most of a GPU's advantage. The OWASP Password Storage Cheat Sheet says to use Argon2id (RFC 9106) with at least 19 MiB of memory, 2 iterations and 1 degree of parallelism, and falls back to scrypt or bcrypt for older stacks.
If you find SHA-256 used for password storage, migrate the user base: OWASP describes re-hashing each password with the new algorithm when the user next logs in. Do not add length-extension defences. The real problem is brute-force speed, and length extension is unrelated to it.
Where SHA-256 lives inside Bitcoin
For Bitcoin specifically, SHA-256 appears in several roles:
| Role | What it does |
|---|---|
| Mining proof-of-work | Miners search for a nonce so that SHA256d(block header) is at or below the target |
| Block hash | SHA256d of the block header |
| Transaction IDs | TXIDs are SHA256d of the raw transaction |
| Merkle root | Pairs of TXIDs, double-hashed level by level |
| P2PKH and P2WPKH | HASH160 of the public key, which is RIPEMD-160 of SHA-256 |
| P2WSH | Single SHA-256 of the witness script |
| Taproot and Schnorr | Tagged SHA-256 hashes (BIP 340) |
| BIP-39 seed words | The checksum is the first bits of SHA-256 of the entropy |
The SHA256d rows come from the Bitcoin developer reference, HASH160 from Bitcoin Core's CHash160 class (src/hash.h), P2WPKH and P2WSH from BIP 141, tagged hashes from BIP 340 and the checksum from BIP 39. BIP 39 turns the words into a seed with PBKDF2 and HMAC-SHA512, so SHA-256 is not part of that step.
A practical break of SHA-256 would damage most of these roles. None is at practical risk in 2026. The known practical results (length extension, reduced-step collisions, fast brute force of small input spaces) do not reach the full SHA-256 function in any role Bitcoin depends on.
The reduced-step record moved in 2026 but stays far from the full function. A practical collision now reaches 35 of SHA-256's 64 steps (ePrint 2026/1080, CRYPTO 2026), up from 31 steps, and a theoretical collision reaches 37 steps (ePrint 2026/232, EUROCRYPT 2026). Earlier work found a practical semi-free-start collision for 39 steps, in which the attacker also picks the starting state (ePrint 2024/349), and a SAT-solver approach reproduced a 38-step collision with a modified initial value (arXiv 2406.20072).
The relevant comparison is SHA-1. CWI Amsterdam and Google published the first practical collision for full SHA-1 in February 2017 (Stevens et al., Google Security Blog). SHA-256 is not in that state.
The 2026 verdict, by use case
The chain holds. Bitcoin's consensus hashing runs over public data, and its block, transaction and Merkle hashes use SHA256d, so length extension has nothing to forge. As of 11 October 2026 there is no published practical preimage or collision attack on full SHA-256. Mining, TXIDs, Merkle roots, P2PKH and P2WPKH addresses, Taproot signatures and BIP-39 checksums are all secure on the hash side.
Outside Bitcoin, SHA-256 inside HMAC is also secure, as in TLS 1.3 key derivation, JWT HS256 and AWS Signature Version 4. Raw SHA-256 used for content addressing, as the hash inside a digital signature or for archive integrity checks is fine, because length extension needs a secret and a MAC to matter.
Two patterns still fail in 2026, and you should fix them on sight. A home-made MAC of the form Hash(secret || message) can be forged by length extension, so switch to HMAC. Raw SHA-256 password storage, salted or not, lets one GPU try billions of guesses per second, so switch to Argon2id.
Both are construction failures. SHA-256 itself has done its job since NIST published it in FIPS 180-2 in August 2002.
Further reading
This article is part of a small cluster on www.btc2h.com about the cryptographic primitives Bitcoin depends on. Three companion reads:
- BIP-360 / BIP-361: The Quantum-Resistant Bitcoin Migration Plan covers the signature side of the quantum picture, where the real long-term risk lives.
- Quantum Computing, Bitcoin, and Google's 2026 Announcement puts the 2026 quantum-hardware news in context.
- btcrecover tutorial 2026 shows why fast hashing helps when you recover your own wallet password and hurts when you store other people's passwords.
Every source this article relies on is listed with its retrieval date in the sources section of this page. All were read on 11 October 2026.
Disclaimer
This article is educational content for Bitcoin holders and developers. It is not legal, financial, or cryptographic-engineering advice. Real-world cryptographic deployments require formal review by qualified specialists. Do not implement security-critical code from a blog post. For production systems handling secrets, use battle-tested libraries (libsodium, OpenSSL, Bouncy Castle) rather than rolling your own primitives. For legal or compliance questions about cryptographic agility under FINMA, GDPR, or NIS2, consult qualified counsel.
Frequently Asked Questions
Is SHA-256 still secure in 2026?
Hash(secret || message). HMAC defeats it, and so does Bitcoin's double SHA-256 (SHA256d).Can SHA-256 be cracked, reversed, or brute-forced?
Is SHA-256 quantum-resistant?
Why does Bitcoin use double SHA-256?
SHA-256(SHA-256(x)), called SHA256d, for block header hashes, transaction IDs and Merkle roots. Zooko, who launched the Tahoe-LAFS project, credits Ferguson and Schneier's *Practical Cryptography* (2003) with proposing SHA-256d against length-extension attacks. Satoshi never wrote down why Bitcoin uses it; the whitepaper only says SHA-256. The effect is the same either way: the outer hash runs over a fixed 32-byte input, so there is no state to extend.What is a length-extension attack?
Hash(secret || message) and knows the byte length of secret compute Hash(secret || message || padding || extra) for any chosen extra, without ever knowing secret. The BLAKE2 authors list MD5, SHA-1, SHA-256 and SHA-512 as susceptible (BLAKE2 paper). SHA-3, SHA-512/256, BLAKE2 and BLAKE3 are not.HMAC vs SHA-256, what is the difference?
HMAC(key, msg) = H((key ⊕ opad) || H((key ⊕ ipad) || msg)). It produces a MAC that length extension cannot forge. Use HMAC anywhere you authenticate a message with a shared secret. Use raw SHA-256 for content addressing, as the hash inside a signature, or in Merkle trees.