Skip to content

Commit e33b2c6

Browse files
committed
Taproot tagged hash impl (unoptimized) with authoritative test vector.
1 parent e52a0f1 commit e33b2c6

3 files changed

Lines changed: 29 additions & 1 deletion

File tree

include/bitcoin/system/hash/functions.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ INLINE hash_digest bitcoin_hash2(const data_slice& left,
133133
template <typename Type>
134134
INLINE data_chunk bitcoin_chunk(const Type& data) NOEXCEPT;
135135

136+
/// Taproot tagged hashing.
137+
INLINE hash_digest tagged_hash(const std::string& tag,
138+
const data_slice& message) NOEXCEPT;
139+
136140
/// Merkle root from a bitcoin_hash set [chain].
137141
INLINE hash_digest merkle_root(hashes&& set) NOEXCEPT;
138142

include/bitcoin/system/impl/hash/functions.ipp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,21 @@ INLINE data_chunk bitcoin_chunk(const Type& data) NOEXCEPT
183183
return accumulator<sha256>::double_hash_chunk(data);
184184
}
185185

186-
/// Merkle root from a bitcoin_hash set [chain].
186+
// Taproot tagged hash.
187+
// TODO: this is not optimized, use precomputed state state for known tags.
188+
// TODO: set the consteval mid-state computation for each into a constexpr.
189+
INLINE hash_digest tagged_hash(const std::string& tag,
190+
const data_slice& message) NOEXCEPT
191+
{
192+
const auto hash = sha256_hash(tag);
193+
accumulator<sha256> context{};
194+
context.write(hash);
195+
context.write(hash);
196+
context.write(message.size(), message.data());
197+
return context.flush();
198+
}
199+
200+
// Merkle root from a bitcoin_hash set [chain].
187201
INLINE hash_digest merkle_root(hashes&& set) NOEXCEPT
188202
{
189203
return sha256::merkle_root(std::move(set));

test/hash/functions.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,16 @@ BOOST_AUTO_TEST_CASE(functions__bitcoin__null_one__expected)
317317
BOOST_CHECK_EQUAL(bitcoin_chunk(to_chunk(null_hash)), to_chunk(expected));
318318
}
319319

320+
// taproot tags
321+
// ----------------------------------------------------------------------------
322+
323+
BOOST_AUTO_TEST_CASE(tagged_hash_test)
324+
{
325+
// Test vector from secp256k1.
326+
constexpr auto expected = base16_array("047a5e17b58647c13cc6ebc0aa583b62fb1643326877406ce276559a3bde55b3");
327+
BOOST_REQUIRE_EQUAL(tagged_hash("tag", "msg"), expected);
328+
}
329+
320330
// merkle_root
321331
// ----------------------------------------------------------------------------
322332

0 commit comments

Comments
 (0)