TYPE 0x0203 · HASH FAMILY
TAGGED_HASH
BIP-340 tagged hash verification. Computes SHA256(SHA256(tag) || SHA256(tag) || preimage) and compares to an expected hash. The tag_hash field IS SHA256(tag) already.
Hash InvertibleLadder Diagram
Fields
| Field | Data Type | Size | Side | Description |
|---|---|---|---|---|
| tag_hash | HASH256 | 32 B | Conditions | SHA-256 of the tag string (pre-hashed for efficiency) |
| expected_hash | HASH256 | 32 B | Conditions | Expected tagged hash result |
| preimage | PREIMAGE | var | Witness | Data to hash with the tag. Length is unconstrained — CSHA256 consumes the field's full byte length. |
PubkeyCountForBlock = 0. The pre-E-022 layout also echoed tag_hash and expected_hash in the witness; both were unused by the evaluator (a 64 B silent embedding channel) and have been removed. TAGGED_HASH_WITNESS = {1, [PREIMAGE]}.
Wire Format Breakdown
Conditions side (committed in the rung leaf):
0x0203
0
2
HASH256[0] · 32B
HASH256[1] · 32B
= 72 bytes
Witness side (in input witness):
0x0203
0
1
PREIMAGE · var
≈ 4 + 1 + len bytes
Total (conditions + witness)
≈ 77 + len bytes
Two condition HASH256 fields: tag_hash (= SHA256(tag)) and expected_hash (the BIP-340 result to match). The witness carries only the PREIMAGE.
Evaluation Logic
1.
Collect all HASH256 fields from the merged conditions+witness block, and locate the PREIMAGE field. If fewer than 2 HASH256 fields, or PREIMAGE missing → ERROR
2.
The first HASH256 (in field order) is tag_hash; the second is expected_hash. Both must be exactly 32 B; otherwise → ERROR
3.
Compute SHA256(tag_hash || tag_hash || PREIMAGE) using
CSHA256 with three sequential Write calls. The PREIMAGE length is unconstrained — the full byte run is consumed.
4.
memcmp the 32-byte result against expected_hash. Equal → SATISFIED; differs → UNSATISFIED
Return Values
| Condition | Result |
|---|---|
| Fewer than 2 HASH256 fields, or PREIMAGE missing | ERROR |
| Either HASH256 field not exactly 32 B | ERROR |
| SHA256(tag_hash || tag_hash || PREIMAGE) ≠ expected_hash | UNSATISFIED |
| SHA256(tag_hash || tag_hash || PREIMAGE) = expected_hash | SATISFIED |
JSON Wire Format
Conditions (committed in the rung leaf)
{
"type": "TAGGED_HASH",
"inverted": false,
"fields": [
{ "type": "HASH256", "hex": "a1b2c3...32 bytes (tag_hash)" },
{ "type": "HASH256", "hex": "d4e5f6...32 bytes (expected)" }
]
}Witness (input)
{
"type": "TAGGED_HASH",
"inverted": false,
"fields": [
{ "type": "PREIMAGE", "hex": "deadbeef... (variable-length preimage)" }
]
}Use Cases
Domain-Separated Commitments
The tag provides domain separation, ensuring that a preimage valid in one context cannot be replayed in another. Different tags produce entirely different hashes from the same data.
BIP-340 Challenge Verification
Schnorr signature challenges use tagged hashes with the "BIP0340/challenge" tag. This block can verify that a specific challenge was correctly constructed from its components.
Taproot-Compatible Tagged Hashing
Taproot uses tagged hashes extensively (TapLeaf, TapBranch, TapTweak). This block enables on-chain verification of taproot tree construction and tweak derivation.