Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
merkle_check_trace.cpp
Go to the documentation of this file.
2
3#include <cstddef>
4#include <cstdint>
5#include <optional>
6
11
12namespace bb::avm2::tracegen {
13
15
32{
33 using C = Column;
34
35 // Skip 0th row since this gadget has shifts
36 uint32_t row = 1;
37
38 for (const auto& event : events) {
39 const size_t full_path_len = event.sibling_path.size();
40
41 // Iterate over the path starting at the leaf.
42 // Root is not included in the path.
43 // For the current level, gather info about the current pair of nodes
44 // being hashed along with the path-length remaining after this level
45 // to complete the merkle check.
46
47 const bool write = event.new_leaf_value.has_value();
48 assert(write == event.new_root.has_value());
49
50 FF read_node = event.leaf_value;
51 FF write_node = event.new_leaf_value.value_or(FF(0));
52 uint64_t current_index_in_layer = event.leaf_index;
53
54 const FF& root = event.root;
55 const FF new_root = event.new_root.value_or(FF(0));
56
57 for (size_t i = 0; i < full_path_len; ++i) {
58 const FF& sibling = event.sibling_path[i];
59
60 // path-length decrements by 1 for each level until it reaches 1
61 const size_t path_len = full_path_len - i;
62
63 // end == 1 at last iteration, i.e., i == full_path_len - 1 equivalently to path_len == 1
64 const bool end = path_len == 1;
65 const bool start = i == 0; // First row in the chain is a start row
66 const bool index_is_even = current_index_in_layer % 2 == 0;
67 const FF read_left_node = index_is_even ? read_node : sibling;
68 const FF read_right_node = index_is_even ? sibling : read_node;
69 const FF read_output_hash = Poseidon2::hash({ read_left_node, read_right_node });
70
71 // Read and Write
72 trace.set(row,
73 { { { C::merkle_check_sel, 1 },
74 { C::merkle_check_read_node, read_node },
75 { C::merkle_check_index, current_index_in_layer },
76 { C::merkle_check_path_len, path_len },
77 // Guarantees that path_len - 1 never underflows as path_len is always >= 1
78 { C::merkle_check_path_len_min_one_inv, path_len - 1 }, // Will be inverted in batch later
79 { C::merkle_check_read_root, root },
80 { C::merkle_check_sibling, sibling },
81 { C::merkle_check_start, start ? 1 : 0 },
82 { C::merkle_check_end, end ? 1 : 0 },
83 { C::merkle_check_index_is_even, index_is_even ? 1 : 0 },
84 { C::merkle_check_read_left_node, read_left_node },
85 { C::merkle_check_read_right_node, read_right_node },
86 { C::merkle_check_read_output_hash, read_output_hash } } });
87
88 // Update the current/target node value for the next iteration
89 read_node = read_output_hash;
90 current_index_in_layer >>= 1;
91
92 // Write only.
93 if (write) {
94 // Only active when write is on.
95 const FF write_left_node = index_is_even ? write_node : sibling;
96 const FF write_right_node = index_is_even ? sibling : write_node;
97 const FF write_output_hash = Poseidon2::hash({ write_left_node, write_right_node });
98
99 trace.set(row,
100 { { { C::merkle_check_write, 1 },
101 { C::merkle_check_write_root, new_root },
102 { C::merkle_check_write_node, write_node },
103 { C::merkle_check_write_left_node, write_left_node },
104 { C::merkle_check_write_right_node, write_right_node },
105 { C::merkle_check_write_output_hash, write_output_hash } } });
106
107 // Update the current/target node value for the next iteration
108 write_node = write_output_hash;
109 }
110
111 row++;
112 }
113
114 assert(current_index_in_layer == 0);
115 assert(read_node == root);
116 assert(write_node == new_root);
117 }
118
119 // Batch invert the columns.
120 trace.invert_columns({ { C::merkle_check_path_len_min_one_inv } });
121}
122
126 .add<lookup_merkle_check_merkle_poseidon2_write_settings, InteractionType::LookupSequential>();
127
128} // namespace bb::avm2::tracegen
InteractionDefinition & add(auto &&... args)
void process(const simulation::EventEmitterInterface< simulation::MerkleCheckEvent >::Container &events, TraceContainer &trace)
Trace generation for the MerkleCheck gadget. It handles both READ and WRITE MerkleCheck events....
static const InteractionDefinition interactions
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
TestTraceContainer trace
lookup_settings< lookup_merkle_check_merkle_poseidon2_read_settings_ > lookup_merkle_check_merkle_poseidon2_read_settings
AvmFlavorSettings::FF FF
Definition field.hpp:10
void write(std::vector< uint8_t > &buf, Chonk::VerificationKey const &vk)
Definition chonk.hpp:366
simulation::PublicDataTreeReadWriteEvent event