2 *****************************************************************************
4 Implementation of interfaces for Merkle tree.
8 *****************************************************************************
9 * @author This file is part of libsnark, developed by SCIPR Lab
10 * and contributors (see AUTHORS).
11 * @copyright MIT license (see LICENSE file)
12 *****************************************************************************/
14 #ifndef MERKLE_TREE_TCC
15 #define MERKLE_TREE_TCC
18 #include <libff/common/profiling.hpp>
19 #include <libff/common/utils.hpp>
24 template<typename HashT>
25 typename HashT::hash_value_type two_to_one_CRH(
26 const typename HashT::hash_value_type &l,
27 const typename HashT::hash_value_type &r)
29 typename HashT::hash_value_type new_input;
30 new_input.insert(new_input.end(), l.begin(), l.end());
31 new_input.insert(new_input.end(), r.begin(), r.end());
34 const size_t digest_size = HashT::get_digest_len();
36 assert(l.size() == digest_size);
37 assert(r.size() == digest_size);
39 return HashT::get_hash(new_input);
42 template<typename HashT>
43 merkle_tree<HashT>::merkle_tree(const size_t depth, const size_t value_size)
44 : depth(depth), value_size(value_size)
46 assert(depth < sizeof(size_t) * 8);
48 digest_size = HashT::get_digest_len();
49 assert(value_size <= digest_size);
51 hash_value_type last(digest_size);
52 hash_defaults.reserve(depth + 1);
53 hash_defaults.emplace_back(last);
54 for (size_t i = 0; i < depth; ++i) {
55 last = two_to_one_CRH<HashT>(last, last);
56 hash_defaults.emplace_back(last);
59 std::reverse(hash_defaults.begin(), hash_defaults.end());
62 template<typename HashT>
63 merkle_tree<HashT>::merkle_tree(
65 const size_t value_size,
66 const std::vector<libff::bit_vector> &contents_as_vector)
67 : merkle_tree<HashT>(depth, value_size)
69 assert(libff::log2(contents_as_vector.size()) <= depth);
70 for (size_t address = 0; address < contents_as_vector.size(); ++address) {
71 const size_t idx = address + (1ul << depth) - 1;
72 values[idx] = contents_as_vector[address];
73 hashes[idx] = contents_as_vector[address];
74 hashes[idx].resize(digest_size);
77 size_t idx_begin = (1ul << depth) - 1;
78 size_t idx_end = contents_as_vector.size() + ((1ul << depth) - 1);
80 for (int layer = depth; layer > 0; --layer) {
81 for (size_t idx = idx_begin; idx < idx_end; idx += 2) {
82 // this is sound, because idx_begin is always a left child
83 hash_value_type l = hashes[idx];
85 (idx + 1 < idx_end ? hashes[idx + 1] : hash_defaults[layer]);
87 hash_value_type h = two_to_one_CRH<HashT>(l, r);
88 hashes[(idx - 1) / 2] = h;
91 idx_begin = (idx_begin - 1) / 2;
92 idx_end = (idx_end - 1) / 2;
96 template<typename HashT>
97 merkle_tree<HashT>::merkle_tree(
99 const size_t value_size,
100 const std::map<size_t, libff::bit_vector> &contents)
101 : merkle_tree<HashT>(depth, value_size)
104 if (!contents.empty()) {
105 assert(contents.rbegin()->first < 1ul << depth);
107 for (auto it = contents.begin(); it != contents.end(); ++it) {
108 const size_t address = it->first;
109 const libff::bit_vector value = it->second;
110 const size_t idx = address + (1ul << depth) - 1;
112 values[address] = value;
114 hashes[idx].resize(digest_size);
117 auto last_it = hashes.end();
119 for (int layer = depth; layer > 0; --layer) {
120 auto next_last_it = hashes.begin();
122 for (auto it = hashes.begin(); it != last_it; ++it) {
123 const size_t idx = it->first;
124 const hash_value_type hash = it->second;
127 // this is the right child of its parent and by invariant we
128 // are missing the left child
129 hashes[(idx - 1) / 2] =
130 two_to_one_CRH<HashT>(hash_defaults[layer], hash);
132 if (std::next(it) == last_it ||
133 std::next(it)->first != idx + 1) {
134 // this is the left child of its parent and is missing
136 hashes[(idx - 1) / 2] =
137 two_to_one_CRH<HashT>(hash, hash_defaults[layer]);
139 // typical case: this is the left child of the parent
140 // and adjacent to it there is a right child
141 hashes[(idx - 1) / 2] =
142 two_to_one_CRH<HashT>(hash, std::next(it)->second);
148 last_it = next_last_it;
153 template<typename HashT>
154 libff::bit_vector merkle_tree<HashT>::get_value(const size_t address) const
156 assert(libff::log2(address) <= depth);
158 auto it = values.find(address);
159 libff::bit_vector padded_result =
160 (it == values.end() ? libff::bit_vector(digest_size) : it->second);
161 padded_result.resize(value_size);
163 return padded_result;
166 template<typename HashT>
167 void merkle_tree<HashT>::set_value(
168 const size_t address, const libff::bit_vector &value)
170 assert(libff::log2(address) <= depth);
171 size_t idx = address + (1ul << depth) - 1;
173 assert(value.size() == value_size);
174 values[address] = value;
176 hashes[idx].resize(digest_size);
178 for (int layer = depth - 1; layer >= 0; --layer) {
181 auto it = hashes.find(2 * idx + 1);
183 (it == hashes.end() ? hash_defaults[layer + 1] : it->second);
185 it = hashes.find(2 * idx + 2);
187 (it == hashes.end() ? hash_defaults[layer + 1] : it->second);
189 hash_value_type h = two_to_one_CRH<HashT>(l, r);
194 template<typename HashT>
195 typename HashT::hash_value_type merkle_tree<HashT>::get_root() const
197 auto it = hashes.find(0);
198 return (it == hashes.end() ? hash_defaults[0] : it->second);
201 template<typename HashT>
202 typename HashT::merkle_authentication_path_type merkle_tree<HashT>::get_path(
203 const size_t address) const
205 typename HashT::merkle_authentication_path_type result(depth);
206 assert(libff::log2(address) <= depth);
207 size_t idx = address + (1ul << depth) - 1;
209 for (size_t layer = depth; layer > 0; --layer) {
210 size_t sibling_idx = ((idx + 1) ^ 1) - 1;
211 auto it = hashes.find(sibling_idx);
212 if (layer == depth) {
213 auto it2 = values.find(sibling_idx - ((1ul << depth) - 1));
215 (it2 == values.end() ? libff::bit_vector(value_size, false)
217 result[layer - 1].resize(digest_size);
220 (it == hashes.end() ? hash_defaults[layer] : it->second);
229 template<typename HashT> void merkle_tree<HashT>::dump() const
231 for (size_t i = 0; i < 1ul << depth; ++i) {
232 auto it = values.find(i);
233 printf("[%zu] -> ", i);
234 const libff::bit_vector value =
235 (it == values.end() ? libff::bit_vector(value_size) : it->second);
236 for (bool b : value) {
237 printf("%d", b ? 1 : 0);
244 } // namespace libsnark
246 #endif // MERKLE_TREE_TCC