where in the Bitcoin Protocol is SHA256(SHA256(x)) performed and why?
7 Answers
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:
- Hashing or encrypting twice to increase security? on crypto.SE
- Cryptographic reasoning for double-hash? on bitcointalk
-
My conjecture is the double hashing everywhere was a red-herring to make us think Satoshi was sloppy, lame and take our focus away from a posited valid use case for the
RIPEMD160(SHA256)
. My lengthy and elaborate rationale is in my answer on the related question. Commented Feb 22, 2022 at 10:35
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.
Bitcoin uses double hashing almost everywhere>SHA256[SH256[X]]called Hash256 which produces a 160 bit out.Linking transaction outputs and inputs.Generating the checsum in a bitcoin address.Hashing the block in a merkle tree.
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.
I. To generate a Bitcoin address from an public key:
- run hash function SHA-256 on the key
- run RIPEMD-160 on the key This compresses address size to 160bits and is knows as "double hashing" (HASH160). This gives us the public key hash.
- add a version byte in front of RIPEMD-160 hash and specify our network
- Run a Base58check encode to obtain cheksum.
- Run SHA-256 on RIPEMD-160 twice
- Take first 4bytes of the SHA-256d hash as the checksum and add to end of the extended RIPEMD-160 hash
- convert result to base 58 to obtain Bitcoin address
II. To increase security by making SHA-256 tamper resistant III. On message inputs and outputs
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 Commented Aug 13, 2018 at 0:30