where in the Bitcoin Protocol is SHA256(SHA256(x)) performed and why?


Bitcoin uses double hashing almost everywhere it hashes in one of two variants:

  • RIPEMD160(SHA256(x)) called Hash160 which produces a 160 bit output

    • hashing the public key to generate part of a Bitcoin addresses
  • SHA256(SHA256(x)) called Hash256 which produces a 256 bit output

    • generating the checksum in a Bitcoin address
    • hashing the block in a merkle tree
    • linking transaction outputs and inputs
    • hash of the block header (and thus the proof of work and the link to the previous block)

It seems like Satoshi chose Hash256 whenever collisions are a problem, and Hash160 when only (multi target) second pre-images matter. This is consistent with a goal of achieving 128 bits of security.

You need a 2*n bit hash to achieve n bit collision resistance, and you need a t*n bit hash to achieve n bit second pre-image resistance. If we assume a conservative 4 billion targets, and a 128 bit security level, this leads to 256 bit hashes for collision resistance and 160 bit hashes for multi-target second-preimages.

So why does he hash twice? I suspect it's in order to prevent length-extension attacks.

SHA-2, like all Merkle-Damgard hashes suffers from a property called "length-extension". This allows an attacker who knows H(x) to calculate H(x||y) without knowing x. This is usually not a problem, but there are some uses where it totally breaks the security. The most relevant example is using H(k||m) as MAC, where an attacker can easily calculate a MAC for m||m'. I don't think Bitcoin ever uses hashes in a way that would suffer from length extensions, but I guess Satoshi went with the safe choice of preventing it everywhere.

To avoid this property, Ferguson and Schneier suggested using SHA256d = SHA256(SHA256(x)) which avoids length-extension attacks. This construction has some minor weaknesses (not relevant to bitcoin), so I wouldn't recommend it for new protocols, and would use HMAC with constant key, or truncated SHA512 instead.

Some related reading:

  • This is a great answer. You know what you're talking about. Unfortunately, a lot do not, they think they do and consequently their answers mislead. I assumed the hash of the block header is a simple SHA256 but no, it's a double SHA256. I found that out only when I couldn't understand the discrepancy between my computation and existing computation of the block header hash. How very frustrating listening to half wits on the web who are clueless and cause loss of time and energy. What a bummer.
    – andrewz
    Sep 12 at 1:15

Here's the main hashing function:

template<typename T1>
inline uint256 Hash(const T1 pbegin, const T1 pend)
    static unsigned char pblank[1];
    uint256 hash1;
    SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
    uint256 hash2;
    SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
    return hash2;

I'd say anyplace that calls that uses SHA256 twice.

As for why, see this.


We perform SHA-256d on extended RIPEMD-160 hash, running SHA-256 on it twice. We take the first 4 bytes of our SHA-256d hash as our checksum, and append it to the end of our extended RIPEMD-160 hash. After converting the result to base58, we finally have our Bitcoin address.


Hashing the block in a Merkle tree and with two rounds of SHA256 increases in security, so both function would have to be broken to undo the hash.


Senders specify a locking script and recipients specify an unlocking script. These stacked hashes confirm proof of work by the sending UTXO and legitimatecy of the recipient to receive the transaction.

  • This doesn't make sense and doesn't answer the question
    – MeshCollider
    Aug 13 '18 at 0:30

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.