Tagged Hashes

In the last section we tweaked a key with hash(P || contract).

That plain hash() was a simplification. Taproot never uses a bare SHA256. It always uses a tagged hash.

Tagged hashes are used everywhere in the Taproot and Schnorr specification, so this is the first tool we need.

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.

That matters because Taproot hashes a lot of similar-looking things. A leaf, a branch, a tweak and a signature challenge are all 32 bytes of data going into SHA256. Without tags, a hash made for one job could be replayed as another.

How Do Tagged Hashes Work?

Creating tagged hashes is straightforward and involves two steps:

  1. Prefix the data you want to hash with the tag tag = sha256(TagName) || sha256(TagName).
  2. Hash as normal: tagged_hash("TagName", data) = sha256(tag + data).
SVG Image

Why is the tag hashed twice ?

You might wonder why the tag is repeated in step 3: (Repeat tag_hash).

It's a speed trick.

  • sha256(TagName) is 32 bytes
  • Repeating it gives 64 bytes
  • A SHA256 block is also 64 bytes

So tag || tag fills exactly one block. The tag never changes, so an implementation can compute that first block once, save the internal state, and start every tagged hash from there.

The BIP340 specification makes the same point: the doubled tag is a fixed 64-byte constant matching the SHA256 block size, so optimized implementations can run as plain SHA256 with a modified initial state.

Programming Exercise: Implement a tagged hash function

Complete the implementation of the tagged_hash function in Python.

Solution code

The tags used in Taproot

Every tag belongs to a specific BIP. Keeping that straight will save you a lot of confusion later.

BIP340: Schnorr signatures

tagwhere you'll meet it
BIP0340/auxnonce generation
BIP0340/noncenonce generation
BIP0340/challengethe e in s = k + e·d

BIP341: Taproot

tagwhere you'll meet it
TapTweakThe Taproot Tweak
TapLeafThe Script Tree
TapBranchThe Script Tree
TapSighashThe Signature Message

Notice how many of them there are. That's the reason tagging exists: TapLeaf and TapBranch both hash 32 byte values inside the same tree, and the tag is the only thing keeping them apart.

Don't worry if you're still confused, we'll explore where each of these tags is used in the following chapters.

Suggest Edits