Summary
Fix the first byte of scriptPathControlBlocks[1] in the p2mr_different_version_leaves
test vector. The control block incorrectly uses 0xC1 (leafVersion 192) instead of 0xFB
(leafVersion 250) for a leaf explicitly declared with "leafVersion": 250.
Problem
The P2MR control block’s first byte encodes both the leaf version and parity bit:
0controlBlock[0] = (leafVersion & 0xfe) | parityBit
For P2MR, the parity bit is always 1. So:
- leafVersion 192 (0xC0) →
0xC1 - leafVersion 250 (0xFA) →
0xFB
The test vector defines two leaves:
0{ "id": 0, "leafVersion": 192, "script": "...OP_CHECKSIG" }
1{ "id": 1, "leafVersion": 250, "script": "06424950333431" }
But the current control block for leaf1 starts with 0xC1:
0scriptPathControlBlocks[1] = "c1 8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7"
1 ^^
2 0xC1 → leafVersion = 0xC0 = 192 ✗ (should be 250)
This is incorrect because a verifier would extract leafVersion = 0xC1 & 0xFE = 0xC0 = 192
from this byte, then compute tapleafHash(script, version=192) which produces a
completely different hash than the correct tapleafHash(script, version=250), making
it impossible to reconstruct the correct Merkle root.
Fix
Change the first byte from 0xC1 to 0xFB:
0scriptPathControlBlocks[1] = "fb 8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7"
1 ^^
2 0xFB → leafVersion = 0xFA = 250 ✓
Verification:
0tapleafHash(script="06424950333431", version=250) = f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a
1sibling = leafHash[0] = 8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7
2
3tapBranchHash(f224a923..., 8ad69ec7...) → hashes are sorted internally
4→ 6c2dc106ab816b73f9d07e3cd1ef2c8c1256f519748e0813e4edd2405d277bef = merkleRoot ✓
Changes
p2mr_different_version_leaves: changescriptPathControlBlocks[1]first byte fromc1tofb