44 static constexpr size_t kLength = kSHA256DigestSize;
45 uint8_t data[kLength];
47 bool operator==(
const Digest& y)
const {
48 return memcmp(data, y.data, kLength) == 0;
53 sha.Update(L.data, kLength);
54 sha.Update(R.data, kLength);
56 sha.DigestData(output.data);
102 explicit MerkleTree(
size_t n) : n_(n), layers_(2 * n) {}
104 void set_leaf(
size_t pos,
const Digest& leaf) {
105 check(pos < n_,
"Invalid position for leaf in Merkle tree");
106 layers_[pos + n_] = leaf;
110 for (
size_t i = n_; i-- > 1;) {
111 layers_[i] = Digest::hash2(layers_[2 * i], layers_[2 * i + 1]);
122 size_t generate_compressed_proof(std::vector<Digest>& proof,
123 const size_t pos[],
size_t np) {
124 std::vector<bool> tree = compressed_merkle_proof_tree(n_, pos, np);
129 for (
size_t i = n_; i-- > 1;) {
131 size_t child = 2 * i;
137 proof.push_back(layers_[child]);
150 std::vector<Digest> layers_;
153class MerkleTreeVerifier {
155 explicit MerkleTreeVerifier(
size_t n,
const Digest& root)
156 : n_(n), root_(root) {}
160 bool verify_compressed_proof(
const Digest* proof,
size_t proof_len,
162 const size_t pos[],
size_t np)
const {
165 std::vector<Digest> layers(2 * n_,
Digest{});
166 std::vector<bool> defined(2 * n_,
false);
169 std::vector<bool> tree = compressed_merkle_proof_tree(n_, pos, np);
173 for (
size_t i = n_; i-- > 1;) {
175 size_t child = 2 * i;
181 if (sz >= proof_len) {
184 layers[child] = proof[sz++];
185 defined[child] =
true;
192 for (
size_t ip = 0; ip < np; ++ip) {
193 size_t l = pos[ip] + n_;
194 layers[l] = leaves[ip];
199 for (
size_t i = n_; i-- > 1;) {
200 if (defined[2 * i] && defined[2 * i + 1]) {
201 layers[i] = Digest::hash2(layers[2 * i], layers[2 * i + 1]);
206 return (defined[1] && (root_ == layers[1]));