Skip to content

Commit dee8943

Browse files
Abstract out ComputeTapbranchHash
1 parent 8e3fc99 commit dee8943

File tree

4 files changed

+24
-14
lines changed

4 files changed

+24
-14
lines changed

src/script/interpreter.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,6 +1830,17 @@ uint256 ComputeTapleafHash(uint8_t leaf_version, Span<const unsigned char> scrip
18301830
return (HashWriter{HASHER_TAPLEAF} << leaf_version << CompactSizeWriter(script.size()) << script).GetSHA256();
18311831
}
18321832

1833+
uint256 ComputeTapbranchHash(Span<const unsigned char> a, Span<const unsigned char> b)
1834+
{
1835+
HashWriter ss_branch{HASHER_TAPBRANCH};
1836+
if (std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end())) {
1837+
ss_branch << a << b;
1838+
} else {
1839+
ss_branch << b << a;
1840+
}
1841+
return ss_branch.GetSHA256();
1842+
}
1843+
18331844
uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint256& tapleaf_hash)
18341845
{
18351846
assert(control.size() >= TAPROOT_CONTROL_BASE_SIZE);
@@ -1839,14 +1850,8 @@ uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint25
18391850
const int path_len = (control.size() - TAPROOT_CONTROL_BASE_SIZE) / TAPROOT_CONTROL_NODE_SIZE;
18401851
uint256 k = tapleaf_hash;
18411852
for (int i = 0; i < path_len; ++i) {
1842-
HashWriter ss_branch{HASHER_TAPBRANCH};
18431853
Span node{Span{control}.subspan(TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * i, TAPROOT_CONTROL_NODE_SIZE)};
1844-
if (std::lexicographical_compare(k.begin(), k.end(), node.begin(), node.end())) {
1845-
ss_branch << k << node;
1846-
} else {
1847-
ss_branch << node << k;
1848-
}
1849-
k = ss_branch.GetSHA256();
1854+
k = ComputeTapbranchHash(k, node);
18501855
}
18511856
return k;
18521857
}

src/script/interpreter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,9 @@ class DeferringSignatureChecker : public BaseSignatureChecker
334334

335335
/** Compute the BIP341 tapleaf hash from leaf version & script. */
336336
uint256 ComputeTapleafHash(uint8_t leaf_version, Span<const unsigned char> script);
337+
/** Compute the BIP341 tapbranch hash from two branches.
338+
* Spans must be 32 bytes each. */
339+
uint256 ComputeTapbranchHash(Span<const unsigned char> a, Span<const unsigned char> b);
337340
/** Compute the BIP341 taproot script tree Merkle root from control block and leaf hash.
338341
* Requires control block to have valid length (33 + k*32, with k in {0,1,..,128}). */
339342
uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint256& tapleaf_hash);

src/script/standard.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,7 @@ bool IsValidDestination(const CTxDestination& dest) {
370370
leaf.merkle_branch.push_back(a.hash);
371371
ret.leaves.emplace_back(std::move(leaf));
372372
}
373-
/* Lexicographically sort a and b's hash, and compute parent hash. */
374-
if (a.hash < b.hash) {
375-
ret.hash = (HashWriter{HASHER_TAPBRANCH} << a.hash << b.hash).GetSHA256();
376-
} else {
377-
ret.hash = (HashWriter{HASHER_TAPBRANCH} << b.hash << a.hash).GetSHA256();
378-
}
373+
ret.hash = ComputeTapbranchHash(a.hash, b.hash);
379374
return ret;
380375
}
381376

@@ -607,7 +602,7 @@ std::optional<std::vector<std::tuple<int, std::vector<unsigned char>, int>>> Inf
607602
node.done = true;
608603
stack.pop_back();
609604
} else if (node.sub[0]->done && !node.sub[1]->done && !node.sub[1]->explored && !node.sub[1]->hash.IsNull() &&
610-
(HashWriter{HASHER_TAPBRANCH} << node.sub[1]->hash << node.sub[1]->hash).GetSHA256() == node.hash) {
605+
ComputeTapbranchHash(node.sub[1]->hash, node.sub[1]->hash) == node.hash) {
611606
// Whenever there are nodes with two identical subtrees under it, we run into a problem:
612607
// the control blocks for the leaves underneath those will be identical as well, and thus
613608
// they will all be matched to the same path in the tree. The result is that at the location

src/test/script_tests.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,7 +1817,14 @@ BOOST_AUTO_TEST_CASE(bip341_keypath_test_vectors)
18171817
}
18181818

18191819
}
1820+
}
18201821

1822+
BOOST_AUTO_TEST_CASE(compute_tapbranch)
1823+
{
1824+
uint256 hash1 = uint256S("8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7");
1825+
uint256 hash2 = uint256S("f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a");
1826+
uint256 result = uint256S("a64c5b7b943315f9b805d7a7296bedfcfd08919270a1f7a1466e98f8693d8cd9");
1827+
BOOST_CHECK_EQUAL(ComputeTapbranchHash(hash1, hash2), result);
18211828
}
18221829

18231830
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)