From 'Mastering bitcoin' -

checksum = SHA256(SHA256(prefix+data))

The 'data' is, for example, an address, which was calculated using SHA256 and then RIPEMD160. Why do we need double hashing when calculating the checksum?


Satoshi standardized on using double-SHA256 for 32-byte hashes, and SHA256+RIPEMD160 (each once) for 20-byte hashes, presumably because of (likely misguided) concern about certain attacks (like length extension attacks, which only apply when hashing secret data), and then used those everywhere:

  • P2PKH scriptPubKeys use SHA256+RIPEMD160 of the public key
  • P2PKH address checksums use truncated double-SHA256 of the payload
  • Transaction hashes (txids) use double-SHA256
  • Block hashes (and equivalently, proof of work) use double-SHA256
  • The transaction Merkle tree uses double-SHA256 to compute the next layer.
  • P2P network packets use truncated double-SHA256 of the payload as checksum.
  • The message being ECDSA signed to authorize transactions (sighash) is the double-SHA256 hash of a variant of the serialization of a transaction.

To the best of my knowledge, none of these use cases actually benefit at all from double hashing.

Later additions at first copied this practice, presumably because the rationale wasn't that well understood, and continuing with the same approach was easiest to convince people was safe:

  • P2SH addresses (BIP13) use truncated double-SHA256 as a checksum.
  • P2SH scriptPubKeys (BIP16) use SHA256+RIPEMD160 of the script.
  • WIF ("wallet import format") private keys also use truncated double-SHA256 as a checksum.
  • The same is true for the extended key xpub and xprv formats (BIP32). The derivation algorithm for keys there uses HMAC-SHA512 (which for that purpose is similar to double-SHA512).
  • P2WPKH scriptPubKeys use SHA256+RIPEMD160 hashes of the public key (BIP141)
  • Witness transaction identifiers (wtxids) use double-SHA256 like normal txids do (BIP141).
  • The witness Merkle tree uses the same double-SHA256 based hashing as the transaction tree (BIP141).
  • The message being ECDSA signed for authorizing witness v0 scripts is the double-SHA256 hash of a different message scheme (BIP143).

In more modern additions, it is no longer used:

  • P2WSH scriptPubKeys use a single SHA256 hash of the public key (BIP141).
  • Bech32 and Bech32m address encoding (used for native P2WPKH, P2WSH, and soon, P2TR) addresses use a checksum based on error correction codes, not hashing (BIP173 and BIP350).
  • The upcoming taproot softfork will introduce P2TR scriptPubKeys, which combine public keys and scripts, in a scheme which involves multiple hashing steps, but they are all single-SHA256 (with a tag prefixed to them to guarantee uniquenesss). The same is true for the message being (Schnorr) signed, and the hash inside the signature algorithm. (BIP340, BIP341, BIP342).

In addition, various places where no cryptographically-sized hash is needed have been using other hash functions too:

  • In the (now deprecated) server-side Bloom filtering protocol, MurmurHash3 was used to determine filter positions (BIP37).
  • In client-side compact block filtering, SipHash-2-4 is used to determine filter positions (BIP158).
  • In the compact block P2P protocol extension, SipHash-2-4 is used to generate short (48-bit) transaction identifiers (BIP152).

Disclaimer: I'm a co-author of several proposals mentioned here, and may have forgotten other extensions.

  • Thanks! But why do you say that "none of these use cases actually benefit at all from double hashing"? Double hash does solve the length extension attack, doesn't it? Oct 11 '21 at 22:27
  • 1
    Length extension is not relevant for any of these use cases. It applies in settings where someone uses a hash directly as a MAC mechanism to authenticate secret data (proper solutions like HMAC prevent it). All these use cases are hashes of public data. Oct 11 '21 at 22:30

Prevents some types of attacks.

Satoshi wanted to build something for the ages and was trying to prevent any and all attacks.

See here for details Why are hashes in the bitcoin protocol typically computed twice (double computed)?

  • I'm aware of that, but I don't understand what it has to do with checksum. The checksum is there to make sure you copy/type the data correctly, no? Oct 9 '21 at 16:12
  • 2
    Ah, ok. Yes, for checksum I don't see it making any sense. Maybe double-sha was a primitive at that point so just used out of habit/convenience. Slightly wasteful if true.
    – Paul Otto
    Oct 11 '21 at 9:34

Here's an answer from Zooko in 2011 that explains it is a convention used to "not have to think" about length extension attacks: https://crypto.stackexchange.com/questions/779/hashing-or-encrypting-twice-to-increase-security/884#884

  • An attack here is finding another address with the same hash (thus the same checksum). 1- How can someone use that for his favor? 2- Isn't finding another address with the same checksum, more or less as easy as mining a block? Oct 10 '21 at 2:57
  • Note that length extension attacks only apply when hashing secret data. In the case of hashing public data like addresses or blocks or transactions in Bitcoin, they are irrelevant. Oct 11 '21 at 21:40

Just convention, there’s no possible justification.

  • @af7313 so you agree with this answer? Oct 11 '21 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.