34 static constexpr size_t kLength = kSHA256DigestSize;
35 uint8_t data[kLength];
37 bool operator==(
const Digest& y)
const {
38 return memcmp(data, y.data, kLength) == 0;
43 sha.Update(L.data, kLength);
44 sha.Update(R.data, kLength);
46 sha.DigestData(output.data);
90 explicit MerkleTree(
size_t n) : n_(n), layers_(2 * n) {}
92 void set_leaf(
size_t pos,
const Digest& leaf) {
93 check(pos < n_,
"Invalid position for leaf in Merkle tree");
94 layers_[pos + n_] = leaf;
98 for (
size_t i = n_; i-- > 1;) {
99 layers_[i] = Digest::hash2(layers_[2 * i], layers_[2 * i + 1]);
107 size_t generate_proof(
Digest proof[],
size_t pos)
const {
109 *proof++ = layers_[pos + n_];
110 for (pos += n_; pos > 1; pos >>= 1) {
111 *proof++ = layers_[pos ^ 1];
113 return (proof - begin);
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) {}
158 bool verify_proof(
const Digest* proof,
size_t pos)
const {
160 for (pos += n_; pos > 1; pos >>= 1) {
161 t = (pos & 1) ? Digest::hash2(*proof++, t) : Digest::hash2(t, *proof++);
166 bool verify_compressed_proof(
const Digest* proof,
size_t proof_len,
168 const size_t pos[],
size_t np)
const {
171 std::vector<Digest> layers(2 * n_,
Digest{});
172 std::vector<bool> defined(2 * n_,
false);
175 std::vector<bool> tree = compressed_merkle_proof_tree(n_, pos, np);
179 for (
size_t i = n_; i-- > 1;) {
181 size_t child = 2 * i;
187 if (sz >= proof_len) {
190 layers[child] = proof[sz++];
191 defined[child] =
true;
198 for (
size_t ip = 0; ip < np; ++ip) {
199 size_t l = pos[ip] + n_;
200 layers[l] = leaves[ip];
205 for (
size_t i = n_; i-- > 1;) {
206 if (defined[2 * i] && defined[2 * i + 1]) {
207 layers[i] = Digest::hash2(layers[2 * i], layers[2 * i + 1]);
212 return (defined[1] && (root_ == layers[1]));