Tagged Hashes
Tagged hashes are used throughout the Taproot/Schnorr specification.
Why Do We Use Tagged Hashes?
Their purpose is to ensure that hashes used in one context can’t be used in another.
This means that if you hash the same data in a different context, you won’t get the same hash result.
How Do Tagged Hashes Work?
Creating tagged hashes is straightforward and involves two steps:
- Prefix the data you want to hash with the tag
tag = sha256(TagName) || sha256(TagName)
. - Hash as normal:
tagged_hash("TagName", data) = sha256(tag + data)
.
Programming Exercise: Implement a tagged hash function
Complete the implementation of the tagged_hash
function in Python.
Solution code
You might wonder why we need to hash the tag twice in step 3: (Repeat tag_hash) The BIP 340 specification provides an explanation, which I'll quote here:
"This is a 64-byte long context-specific constant, and the SHA256 block size is also 64 bytes, optimized implementations are possible (identical to SHA256 itself, but with a modified initial state). Using SHA256 of the tag name itself is reasonably simple and efficient for implementations that don't choose to use the optimization."
Tagged Hashes in Taproot
Different tag names are used in different contexts. For example, in Taproot BIP 340, the hash function uses the following tags:
BIP0340/aux
BIP0340/nonce
BIP0340/challenge
TapLeaf
Don't worry if you're still confused, we’ll explore where each of these tags is used in the following chapters.