barretenberg
Loading...
Searching...
No Matches
hash_path.hpp
1#pragma once
2#include "barretenberg/stdlib/primitives/field/field.hpp"
3#include "hash.hpp"
4#include <algorithm>
5#include <vector>
6
7namespace proof_system::plonk::stdlib::merkle_tree {
8
9using namespace barretenberg;
10
11using fr_hash_path = std::vector<std::pair<fr, fr>>;
12using fr_sibling_path = std::vector<fr>;
13template <typename Ctx> using hash_path = std::vector<std::pair<field_t<Ctx>, field_t<Ctx>>>;
14
15inline fr_hash_path get_new_hash_path(fr_hash_path const& old_path, uint128_t index, fr const& value)
16{
17 fr_hash_path path = old_path;
18 fr current = value;
19 for (size_t i = 0; i < old_path.size(); ++i) {
20 bool path_bit = static_cast<bool>(index & 0x1);
21 if (path_bit) {
22 path[i].second = current;
23 } else {
24 path[i].first = current;
25 }
26 current = hash_pair_native(path[i].first, path[i].second);
27 index /= 2;
28 }
29 return path;
30}
31
32inline fr_hash_path get_random_hash_path(size_t const& tree_depth)
33{
34 fr_hash_path path;
35 for (size_t i = 0; i < tree_depth; ++i) {
36 path.push_back(std::make_pair(fr::random_element(), fr::random_element()));
37 }
38 return path;
39}
40
41template <typename Ctx> inline hash_path<Ctx> create_witness_hash_path(Ctx& ctx, fr_hash_path const& input)
42{
43 hash_path<Ctx> result;
44 std::transform(input.begin(), input.end(), std::back_inserter(result), [&](auto const& v) {
45 return std::make_pair(field_t(witness_t(&ctx, v.first)), field_t(witness_t(&ctx, v.second)));
46 });
47 return result;
48}
49
50inline fr get_hash_path_root(fr_hash_path const& input)
51{
52 return hash_pair_native(input[input.size() - 1].first, input[input.size() - 1].second);
53}
54
55inline fr zero_hash_at_height(size_t height)
56{
57 auto current = fr(0);
58 for (size_t i = 0; i < height; ++i) {
59 current = hash_pair_native(current, current);
60 }
61 return current;
62}
63
64} // namespace proof_system::plonk::stdlib::merkle_tree
65
66// We add to std namespace as fr_hash_path is actually a std::vector, and this is the only way
67// to achieve effective ADL.
68namespace std {
69template <typename Ctx>
70inline std::ostream& operator<<(std::ostream& os, proof_system::plonk::stdlib::merkle_tree::hash_path<Ctx> const& path)
71{
72 os << "[\n";
73 for (size_t i = 0; i < path.size(); ++i) {
74 os << " (" << i << ": " << path[i].first << ", " << path[i].second << ")\n";
75 }
76 os << "]\n";
77 return os;
78}
79
80inline std::ostream& operator<<(std::ostream& os, proof_system::plonk::stdlib::merkle_tree::fr_hash_path const& path)
81{
82 os << "[\n";
83 for (size_t i = 0; i < path.size(); ++i) {
84 os << " (" << i << ": " << path[i].first << ", " << path[i].second << ")\n";
85 }
86 os << "]\n";
87 return os;
88}
89} // namespace std
Definition: field.hpp:10
constexpr_utils defines some helper methods that perform some stl-equivalent operations but in a cons...
Definition: constexpr_utils.hpp:16