From 29ec54fad6466c81e2f38bd24ae18cc5886997d6 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 12 Jun 2021 19:23:31 +0100 Subject: [PATCH] ZIP 244 hashAuthDataRoot computation --- src/primitives/block.cpp | 44 ++++++++++++++++++++++++++++++++++++++++ src/primitives/block.h | 5 +++++ 2 files changed, 49 insertions(+) diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp index 3e685b6c3..a40f46457 100644 --- a/src/primitives/block.cpp +++ b/src/primitives/block.cpp @@ -10,6 +10,9 @@ #include "utilstrencodings.h" #include "crypto/common.h" +const unsigned char ZCASH_AUTH_DATA_HASH_PERSONALIZATION[BLAKE2bPersonalBytes] = + {'Z','c','a','s','h','A','u','t','h','D','a','t','H','a','s','h'}; + uint256 CBlockHeader::GetHash() const { return SerializeHash(*this); @@ -109,6 +112,47 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector& vMer return hash; } +static uint64_t next_pow2(uint64_t x) +{ + x -= 1; + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + x |= (x >> 32); + return x + 1; +} + +uint256 CBlock::BuildAuthDataMerkleTree() const +{ + std::vector tree; + auto perfectSize = next_pow2(vtx.size()); + tree.reserve(perfectSize * 2); // Safe upper bound for the number of total nodes. + + // Add the leaves to the tree. v1-v4 transactions will append empty leaves. + for (auto &tx : vtx) { + tree.push_back(tx.GetAuthDigest()); + } + // Append empty leaves until we get a perfect tree. + tree.insert(tree.end(), perfectSize - vtx.size(), uint256()); + + int j = 0; + for (int layerWidth = tree.size(); layerWidth > 1; layerWidth = (layerWidth + 1) / 2) { + for (int i = 0; i < layerWidth; i += 2) { + CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_AUTH_DATA_HASH_PERSONALIZATION); + ss << tree[j + i]; + ss << tree[j + i + 1]; + tree.push_back(ss.GetHash()); + } + + // Move to the next layer. + j += layerWidth; + } + + return (tree.empty() ? uint256() : tree.back()); +} + std::string CBlock::ToString() const { std::stringstream s; diff --git a/src/primitives/block.h b/src/primitives/block.h index c4464c68d..dfba56833 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -134,6 +134,11 @@ public: std::vector GetMerkleBranch(int nIndex) const; static uint256 CheckMerkleBranch(uint256 hash, const std::vector& vMerkleBranch, int nIndex); + + // Build the authorizing data Merkle tree for this block and return its + // root. + uint256 BuildAuthDataMerkleTree() const; + std::string ToString() const; };