ZIP 244 hashAuthDataRoot computation
This commit is contained in:
parent
0b8a348c2b
commit
29ec54fad6
|
@ -10,6 +10,9 @@
|
||||||
#include "utilstrencodings.h"
|
#include "utilstrencodings.h"
|
||||||
#include "crypto/common.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
|
uint256 CBlockHeader::GetHash() const
|
||||||
{
|
{
|
||||||
return SerializeHash(*this);
|
return SerializeHash(*this);
|
||||||
|
@ -109,6 +112,47 @@ uint256 CBlock::CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMer
|
||||||
return hash;
|
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<uint256> 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::string CBlock::ToString() const
|
||||||
{
|
{
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
|
|
|
@ -134,6 +134,11 @@ public:
|
||||||
|
|
||||||
std::vector<uint256> GetMerkleBranch(int nIndex) const;
|
std::vector<uint256> GetMerkleBranch(int nIndex) const;
|
||||||
static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
|
static uint256 CheckMerkleBranch(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex);
|
||||||
|
|
||||||
|
// Build the authorizing data Merkle tree for this block and return its
|
||||||
|
// root.
|
||||||
|
uint256 BuildAuthDataMerkleTree() const;
|
||||||
|
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue