Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
poseidon2_trace.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <array>
5#include <cstddef>
6#include <cstdint>
7
14
16
17namespace bb::avm2::tracegen {
18
19namespace {
20
21using C = Column;
22using StateCols = std::array<C, 4>;
23
24// This absolute monstrosity is a mapping of the intermediate round columns (round & state) to the "flattened" columns
25// in the trace.
26constexpr std::array<StateCols, Poseidon2Perm::NUM_ROUNDS> intermediate_round_cols = { {
27 // Full rounds
28 { C::poseidon2_perm_T_0_6, C::poseidon2_perm_T_0_5, C::poseidon2_perm_T_0_7, C::poseidon2_perm_T_0_4 },
29 { C::poseidon2_perm_T_1_6, C::poseidon2_perm_T_1_5, C::poseidon2_perm_T_1_7, C::poseidon2_perm_T_1_4 },
30 { C::poseidon2_perm_T_2_6, C::poseidon2_perm_T_2_5, C::poseidon2_perm_T_2_7, C::poseidon2_perm_T_2_4 },
31 { C::poseidon2_perm_T_3_6, C::poseidon2_perm_T_3_5, C::poseidon2_perm_T_3_7, C::poseidon2_perm_T_3_4 },
32 // Partial rounds
33 { C::poseidon2_perm_B_4_0, C::poseidon2_perm_B_4_1, C::poseidon2_perm_B_4_2, C::poseidon2_perm_B_4_3 },
34 { C::poseidon2_perm_B_5_0, C::poseidon2_perm_B_5_1, C::poseidon2_perm_B_5_2, C::poseidon2_perm_B_5_3 },
35 { C::poseidon2_perm_B_6_0, C::poseidon2_perm_B_6_1, C::poseidon2_perm_B_6_2, C::poseidon2_perm_B_6_3 },
36 { C::poseidon2_perm_B_7_0, C::poseidon2_perm_B_7_1, C::poseidon2_perm_B_7_2, C::poseidon2_perm_B_7_3 },
37 { C::poseidon2_perm_B_8_0, C::poseidon2_perm_B_8_1, C::poseidon2_perm_B_8_2, C::poseidon2_perm_B_8_3 },
38 { C::poseidon2_perm_B_9_0, C::poseidon2_perm_B_9_1, C::poseidon2_perm_B_9_2, C::poseidon2_perm_B_9_3 },
39 { C::poseidon2_perm_B_10_0, C::poseidon2_perm_B_10_1, C::poseidon2_perm_B_10_2, C::poseidon2_perm_B_10_3 },
40 { C::poseidon2_perm_B_11_0, C::poseidon2_perm_B_11_1, C::poseidon2_perm_B_11_2, C::poseidon2_perm_B_11_3 },
41 { C::poseidon2_perm_B_12_0, C::poseidon2_perm_B_12_1, C::poseidon2_perm_B_12_2, C::poseidon2_perm_B_12_3 },
42 { C::poseidon2_perm_B_13_0, C::poseidon2_perm_B_13_1, C::poseidon2_perm_B_13_2, C::poseidon2_perm_B_13_3 },
43 { C::poseidon2_perm_B_14_0, C::poseidon2_perm_B_14_1, C::poseidon2_perm_B_14_2, C::poseidon2_perm_B_14_3 },
44 { C::poseidon2_perm_B_15_0, C::poseidon2_perm_B_15_1, C::poseidon2_perm_B_15_2, C::poseidon2_perm_B_15_3 },
45 { C::poseidon2_perm_B_16_0, C::poseidon2_perm_B_16_1, C::poseidon2_perm_B_16_2, C::poseidon2_perm_B_16_3 },
46 { C::poseidon2_perm_B_17_0, C::poseidon2_perm_B_17_1, C::poseidon2_perm_B_17_2, C::poseidon2_perm_B_17_3 },
47 { C::poseidon2_perm_B_18_0, C::poseidon2_perm_B_18_1, C::poseidon2_perm_B_18_2, C::poseidon2_perm_B_18_3 },
48 { C::poseidon2_perm_B_19_0, C::poseidon2_perm_B_19_1, C::poseidon2_perm_B_19_2, C::poseidon2_perm_B_19_3 },
49 { C::poseidon2_perm_B_20_0, C::poseidon2_perm_B_20_1, C::poseidon2_perm_B_20_2, C::poseidon2_perm_B_20_3 },
50 { C::poseidon2_perm_B_21_0, C::poseidon2_perm_B_21_1, C::poseidon2_perm_B_21_2, C::poseidon2_perm_B_21_3 },
51 { C::poseidon2_perm_B_22_0, C::poseidon2_perm_B_22_1, C::poseidon2_perm_B_22_2, C::poseidon2_perm_B_22_3 },
52 { C::poseidon2_perm_B_23_0, C::poseidon2_perm_B_23_1, C::poseidon2_perm_B_23_2, C::poseidon2_perm_B_23_3 },
53 { C::poseidon2_perm_B_24_0, C::poseidon2_perm_B_24_1, C::poseidon2_perm_B_24_2, C::poseidon2_perm_B_24_3 },
54 { C::poseidon2_perm_B_25_0, C::poseidon2_perm_B_25_1, C::poseidon2_perm_B_25_2, C::poseidon2_perm_B_25_3 },
55 { C::poseidon2_perm_B_26_0, C::poseidon2_perm_B_26_1, C::poseidon2_perm_B_26_2, C::poseidon2_perm_B_26_3 },
56 { C::poseidon2_perm_B_27_0, C::poseidon2_perm_B_27_1, C::poseidon2_perm_B_27_2, C::poseidon2_perm_B_27_3 },
57 { C::poseidon2_perm_B_28_0, C::poseidon2_perm_B_28_1, C::poseidon2_perm_B_28_2, C::poseidon2_perm_B_28_3 },
58 { C::poseidon2_perm_B_29_0, C::poseidon2_perm_B_29_1, C::poseidon2_perm_B_29_2, C::poseidon2_perm_B_29_3 },
59 { C::poseidon2_perm_B_30_0, C::poseidon2_perm_B_30_1, C::poseidon2_perm_B_30_2, C::poseidon2_perm_B_30_3 },
60 { C::poseidon2_perm_B_31_0, C::poseidon2_perm_B_31_1, C::poseidon2_perm_B_31_2, C::poseidon2_perm_B_31_3 },
61 { C::poseidon2_perm_B_32_0, C::poseidon2_perm_B_32_1, C::poseidon2_perm_B_32_2, C::poseidon2_perm_B_32_3 },
62 { C::poseidon2_perm_B_33_0, C::poseidon2_perm_B_33_1, C::poseidon2_perm_B_33_2, C::poseidon2_perm_B_33_3 },
63 { C::poseidon2_perm_B_34_0, C::poseidon2_perm_B_34_1, C::poseidon2_perm_B_34_2, C::poseidon2_perm_B_34_3 },
64 { C::poseidon2_perm_B_35_0, C::poseidon2_perm_B_35_1, C::poseidon2_perm_B_35_2, C::poseidon2_perm_B_35_3 },
65 { C::poseidon2_perm_B_36_0, C::poseidon2_perm_B_36_1, C::poseidon2_perm_B_36_2, C::poseidon2_perm_B_36_3 },
66 { C::poseidon2_perm_B_37_0, C::poseidon2_perm_B_37_1, C::poseidon2_perm_B_37_2, C::poseidon2_perm_B_37_3 },
67 { C::poseidon2_perm_B_38_0, C::poseidon2_perm_B_38_1, C::poseidon2_perm_B_38_2, C::poseidon2_perm_B_38_3 },
68 { C::poseidon2_perm_B_39_0, C::poseidon2_perm_B_39_1, C::poseidon2_perm_B_39_2, C::poseidon2_perm_B_39_3 },
69 { C::poseidon2_perm_B_40_0, C::poseidon2_perm_B_40_1, C::poseidon2_perm_B_40_2, C::poseidon2_perm_B_40_3 },
70 { C::poseidon2_perm_B_41_0, C::poseidon2_perm_B_41_1, C::poseidon2_perm_B_41_2, C::poseidon2_perm_B_41_3 },
71 { C::poseidon2_perm_B_42_0, C::poseidon2_perm_B_42_1, C::poseidon2_perm_B_42_2, C::poseidon2_perm_B_42_3 },
72 { C::poseidon2_perm_B_43_0, C::poseidon2_perm_B_43_1, C::poseidon2_perm_B_43_2, C::poseidon2_perm_B_43_3 },
73 { C::poseidon2_perm_B_44_0, C::poseidon2_perm_B_44_1, C::poseidon2_perm_B_44_2, C::poseidon2_perm_B_44_3 },
74 { C::poseidon2_perm_B_45_0, C::poseidon2_perm_B_45_1, C::poseidon2_perm_B_45_2, C::poseidon2_perm_B_45_3 },
75 { C::poseidon2_perm_B_46_0, C::poseidon2_perm_B_46_1, C::poseidon2_perm_B_46_2, C::poseidon2_perm_B_46_3 },
76 { C::poseidon2_perm_B_47_0, C::poseidon2_perm_B_47_1, C::poseidon2_perm_B_47_2, C::poseidon2_perm_B_47_3 },
77 { C::poseidon2_perm_B_48_0, C::poseidon2_perm_B_48_1, C::poseidon2_perm_B_48_2, C::poseidon2_perm_B_48_3 },
78 { C::poseidon2_perm_B_49_0, C::poseidon2_perm_B_49_1, C::poseidon2_perm_B_49_2, C::poseidon2_perm_B_49_3 },
79 { C::poseidon2_perm_B_50_0, C::poseidon2_perm_B_50_1, C::poseidon2_perm_B_50_2, C::poseidon2_perm_B_50_3 },
80 { C::poseidon2_perm_B_51_0, C::poseidon2_perm_B_51_1, C::poseidon2_perm_B_51_2, C::poseidon2_perm_B_51_3 },
81 { C::poseidon2_perm_B_52_0, C::poseidon2_perm_B_52_1, C::poseidon2_perm_B_52_2, C::poseidon2_perm_B_52_3 },
82 { C::poseidon2_perm_B_53_0, C::poseidon2_perm_B_53_1, C::poseidon2_perm_B_53_2, C::poseidon2_perm_B_53_3 },
83 { C::poseidon2_perm_B_54_0, C::poseidon2_perm_B_54_1, C::poseidon2_perm_B_54_2, C::poseidon2_perm_B_54_3 },
84 { C::poseidon2_perm_B_55_0, C::poseidon2_perm_B_55_1, C::poseidon2_perm_B_55_2, C::poseidon2_perm_B_55_3 },
85 { C::poseidon2_perm_B_56_0, C::poseidon2_perm_B_56_1, C::poseidon2_perm_B_56_2, C::poseidon2_perm_B_56_3 },
86 { C::poseidon2_perm_B_57_0, C::poseidon2_perm_B_57_1, C::poseidon2_perm_B_57_2, C::poseidon2_perm_B_57_3 },
87 { C::poseidon2_perm_B_58_0, C::poseidon2_perm_B_58_1, C::poseidon2_perm_B_58_2, C::poseidon2_perm_B_58_3 },
88 { C::poseidon2_perm_B_59_0, C::poseidon2_perm_B_59_1, C::poseidon2_perm_B_59_2, C::poseidon2_perm_B_59_3 },
89 // Full rounds
90 { C::poseidon2_perm_T_60_6, C::poseidon2_perm_T_60_5, C::poseidon2_perm_T_60_7, C::poseidon2_perm_T_60_4 },
91 { C::poseidon2_perm_T_61_6, C::poseidon2_perm_T_61_5, C::poseidon2_perm_T_61_7, C::poseidon2_perm_T_61_4 },
92 { C::poseidon2_perm_T_62_6, C::poseidon2_perm_T_62_5, C::poseidon2_perm_T_62_7, C::poseidon2_perm_T_62_4 },
93 { C::poseidon2_perm_T_63_6, C::poseidon2_perm_T_63_5, C::poseidon2_perm_T_63_7, C::poseidon2_perm_T_63_4 },
94} };
95
96} // namespace
97
107 TraceContainer& trace)
108{
109 uint32_t row = 1; // We start from row 1 because this trace contains shifted columns.
110 for (const auto& event : hash_events) {
111 auto input_size = event.inputs.size(); // Will be mutated in the loop below.
112 // Simulation guarantees that the number of intermediate states is 1 more than the number of permutation events.
113 const auto num_perm_events = event.intermediate_states.size() - 1;
114 // The padding size is the number of elements to add to the input to make it a multiple of 3.
115 // We have to map the modulo 3 values of input_size: 0 -> 0, 1 -> 2, 2 -> 1 to the padding size
116 // which corresponds to a multiplication by 2 modulo 3.
117 const auto padding_size = (2 * input_size) % 3;
118
119 for (size_t i = 0; i < num_perm_events; i++) {
120 std::array<FF, 3> perm_input = { 0, 0, 0 };
121 auto perm_state = event.intermediate_states[i];
122 const auto& perm_output = event.intermediate_states[i + 1]; // In range by definition of num_perm_events.
123 size_t chunk_size = std::min(input_size, static_cast<size_t>(3));
124 // Mix the input chunk into the previous permutation output state
125 for (size_t j = 0; j < chunk_size; j++) {
126 // Build up the input for the permutation
127 perm_input[j] = event.inputs[(i * 3) + j];
128 // Mix the input chunk into the previous permutation output state
129 perm_state[j] += perm_input[j];
130 }
131 trace.set(row,
132 { {
133 { C::poseidon2_hash_sel, 1 },
134 { C::poseidon2_hash_start, i == 0 ? 1 : 0 },
135 { C::poseidon2_hash_end, i == (num_perm_events - 1) ? 1 : 0 },
136 { C::poseidon2_hash_input_len, event.inputs.size() }, // Cannot use input_size as mutated.
137 { C::poseidon2_hash_padding, padding_size },
138 { C::poseidon2_hash_input_0, perm_input[0] },
139 { C::poseidon2_hash_input_1, perm_input[1] },
140 { C::poseidon2_hash_input_2, perm_input[2] },
141
142 { C::poseidon2_hash_num_perm_rounds_rem, num_perm_events - i },
143 { C::poseidon2_hash_num_perm_rounds_rem_min_one_inv,
144 num_perm_events - i - 1 }, // Will be batch inverted.
145
146 { C::poseidon2_hash_a_0, perm_state[0] },
147 { C::poseidon2_hash_a_1, perm_state[1] },
148 { C::poseidon2_hash_a_2, perm_state[2] },
149 { C::poseidon2_hash_a_3, perm_state[3] },
150
151 { C::poseidon2_hash_b_0, perm_output[0] },
152 { C::poseidon2_hash_b_1, perm_output[1] },
153 { C::poseidon2_hash_b_2, perm_output[2] },
154 { C::poseidon2_hash_b_3, perm_output[3] },
155 { C::poseidon2_hash_output, event.output },
156 } });
157 input_size -= chunk_size;
158 row++;
159 }
160 }
161
162 trace.invert_columns({ { C::poseidon2_hash_num_perm_rounds_rem_min_one_inv } });
163}
164
175 TraceContainer& trace)
176{
177 // Our current state
178 std::array<FF, 4> current_state;
179 // These are where we will store the intermediate values of current_state in the trace.
180 std::array<C, 4> round_state_cols;
181
182 uint32_t row = 0;
183
184 for (const auto& event : perm_events) {
185 // The bulk of this code is a copy of the Poseidon2Permutation::permute function from bb
186 // Note that the functions mutate current_state in place.
187 current_state = event.input;
188
189 // Apply 1st linear layer
191 trace.set(row,
192 { {
193 { C::poseidon2_perm_sel, 1 },
194 { C::poseidon2_perm_a_0, event.input[0] },
195 { C::poseidon2_perm_a_1, event.input[1] },
196 { C::poseidon2_perm_a_2, event.input[2] },
197 { C::poseidon2_perm_a_3, event.input[3] },
198
199 { C::poseidon2_perm_EXT_LAYER_6, current_state[0] },
200 { C::poseidon2_perm_EXT_LAYER_5, current_state[1] },
201 { C::poseidon2_perm_EXT_LAYER_7, current_state[2] },
202 { C::poseidon2_perm_EXT_LAYER_4, current_state[3] },
203
204 } });
205
206 // Perform rounds of the permutation algorithm
207 // Initial external (full) rounds
208 constexpr size_t rounds_f_beginning = Poseidon2Perm::rounds_f / 2;
209 for (size_t i = 0; i < rounds_f_beginning; ++i) {
211 Poseidon2Perm::apply_sbox(current_state);
213 // Store end of round state
214 round_state_cols = intermediate_round_cols[i];
215 trace.set(row,
216 { { { round_state_cols[0], current_state[0] },
217 { round_state_cols[1], current_state[1] },
218 { round_state_cols[2], current_state[2] },
219 { round_state_cols[3], current_state[3] } } });
220 }
221
222 // Internal (partial) rounds
223 const size_t p_end = rounds_f_beginning + Poseidon2Perm::rounds_p;
224 for (size_t i = rounds_f_beginning; i < p_end; ++i) {
225 current_state[0] += Poseidon2Perm::round_constants[i][0];
226 Poseidon2Perm::apply_single_sbox(current_state[0]);
228 // Store end of round state
229 round_state_cols = intermediate_round_cols[i];
230 trace.set(row,
231 { { { round_state_cols[0], current_state[0] },
232 { round_state_cols[1], current_state[1] },
233 { round_state_cols[2], current_state[2] },
234 { round_state_cols[3], current_state[3] } } });
235 }
236
237 // Remaining external (full) rounds
238 for (size_t i = p_end; i < Poseidon2Perm::NUM_ROUNDS; ++i) {
240 Poseidon2Perm::apply_sbox(current_state);
242 round_state_cols = intermediate_round_cols[i];
243 trace.set(row,
244 { { { round_state_cols[0], current_state[0] },
245 { round_state_cols[1], current_state[1] },
246 { round_state_cols[2], current_state[2] },
247 { round_state_cols[3], current_state[3] } } });
248 }
249 // Set the output
250 trace.set(row,
251 { {
252 { C::poseidon2_perm_b_0, current_state[0] },
253 { C::poseidon2_perm_b_1, current_state[1] },
254 { C::poseidon2_perm_b_2, current_state[2] },
255 { C::poseidon2_perm_b_3, current_state[3] },
256
257 } });
258 row++;
259 }
260}
261
272 TraceContainer& trace)
273{
274
275 // We rely on this assertion in circuit for the write memory tag.
276 // Namely, we pass `precomputed.zero` as the tag for the write memory operation.
277 // See the 4 lookups #[POS_WRITE_MEM_0] ... #[POS_WRITE_MEM_3] in poseidon2_mem.pil.
278 static_assert(static_cast<uint8_t>(MemoryTag::FF) == 0);
279
280 uint32_t row = 0;
281
282 for (const auto& event : perm_mem_events) {
283 // Addresses cast to uint64_t to capture overflows
284 const uint64_t src_addr = static_cast<uint64_t>(event.src_address);
285 const uint64_t dst_addr = static_cast<uint64_t>(event.dst_address);
286 // Error Handling, check that the addresses are within the valid range
287 // The max read address is src_addr + 3 since 4 input elements are read
288 // The max write address is dst_addr + 3 since 4 output elements are written
289 const bool src_out_of_range_err = src_addr + 3 > AVM_HIGHEST_MEM_ADDRESS;
290 const bool dst_out_of_range_err = dst_addr + 3 > AVM_HIGHEST_MEM_ADDRESS;
291 const bool should_read_mem = !(src_out_of_range_err || dst_out_of_range_err);
292
293 // Error Handling, check that the input tags are valid
294 bool invalid_tag =
295 std::ranges::any_of(event.input, [](const auto& input) { return input.get_tag() != MemoryTag::FF; });
296
297 FF batch_tag_inv = 0;
298
299 // No need to use batch inversion because in the happy path we do not perform any field inversion.
300 if (invalid_tag) {
301 uint32_t target_tag = static_cast<uint32_t>(MemoryTag::FF);
302 FF batched_tag_check = 0;
303 // Performs the batched tag check described in the circuit.
304 // see
305 // https://github.com/AztecProtocol/aztec-packages/blob/next/barretenberg/cpp/pil/vm2/docs/recipes.md#batching-comparison-of-n-bit-numbers
306 for (uint32_t i = 0; i < event.input.size(); i++) {
307 uint32_t exponent = 3 * i;
308 uint32_t current_tag = static_cast<uint32_t>(event.input[i].get_tag());
309 batched_tag_check += (FF(current_tag) - FF(target_tag)) * FF((1 << exponent));
310 }
311 batch_tag_inv = batched_tag_check.invert();
312 }
313
314 const bool err = src_out_of_range_err || dst_out_of_range_err || invalid_tag;
315
316 trace.set(row,
317 { {
318 { C::poseidon2_perm_mem_sel, 1 },
319 { C::poseidon2_perm_mem_execution_clk, event.execution_clk },
320 { C::poseidon2_perm_mem_space_id, event.space_id },
321 { C::poseidon2_perm_mem_max_mem_addr, AVM_HIGHEST_MEM_ADDRESS },
322 // Error Handling
323 { C::poseidon2_perm_mem_sel_src_out_of_range_err, src_out_of_range_err ? 1 : 0 },
324 { C::poseidon2_perm_mem_sel_dst_out_of_range_err, dst_out_of_range_err ? 1 : 0 },
325 { C::poseidon2_perm_mem_sel_invalid_tag_err, invalid_tag ? 1 : 0 },
326 { C::poseidon2_perm_mem_batch_tag_inv, batch_tag_inv },
327 { C::poseidon2_perm_mem_err, err ? 1 : 0 },
328 // Mem Ops
329 { C::poseidon2_perm_mem_sel_should_read_mem, should_read_mem ? 1 : 0 },
330 // Read Addresses
331 { C::poseidon2_perm_mem_read_address_0_, src_addr },
332 { C::poseidon2_perm_mem_read_address_1_, src_addr + 1 },
333 { C::poseidon2_perm_mem_read_address_2_, src_addr + 2 },
334 { C::poseidon2_perm_mem_read_address_3_, src_addr + 3 },
335 // Write Addresses
336 { C::poseidon2_perm_mem_write_address_0_, dst_addr },
337 { C::poseidon2_perm_mem_write_address_1_, dst_addr + 1 },
338 { C::poseidon2_perm_mem_write_address_2_, dst_addr + 2 },
339 { C::poseidon2_perm_mem_write_address_3_, dst_addr + 3 },
340 // Inputs
341 { C::poseidon2_perm_mem_input_0_, event.input[0].as_ff() },
342 { C::poseidon2_perm_mem_input_1_, event.input[1].as_ff() },
343 { C::poseidon2_perm_mem_input_2_, event.input[2].as_ff() },
344 { C::poseidon2_perm_mem_input_3_, event.input[3].as_ff() },
345 // Input Tags
346 { C::poseidon2_perm_mem_input_tag_0_, static_cast<uint8_t>(event.input[0].get_tag()) },
347 { C::poseidon2_perm_mem_input_tag_1_, static_cast<uint8_t>(event.input[1].get_tag()) },
348 { C::poseidon2_perm_mem_input_tag_2_, static_cast<uint8_t>(event.input[2].get_tag()) },
349 { C::poseidon2_perm_mem_input_tag_3_, static_cast<uint8_t>(event.input[3].get_tag()) },
350 // Outputs
351 { C::poseidon2_perm_mem_sel_should_exec, !err ? 1 : 0 },
352 { C::poseidon2_perm_mem_output_0_, event.output[0] },
353 { C::poseidon2_perm_mem_output_1_, event.output[1] },
354 { C::poseidon2_perm_mem_output_2_, event.output[2] },
355 { C::poseidon2_perm_mem_output_3_, event.output[3] },
356 } });
357 row++;
358 }
359}
360
364 // Poseidon2 Memory to Permutation Subtrace
365 .add<lookup_poseidon2_mem_input_output_poseidon2_perm_settings, InteractionType::LookupSequential>()
366 // Lookups to Greater Than Subtrace
368 .add<lookup_poseidon2_mem_check_dst_addr_in_range_settings, InteractionType::LookupGeneric>(C::gt_sel);
369
370} // namespace bb::avm2::tracegen
#define AVM_HIGHEST_MEM_ADDRESS
InteractionDefinition & add(auto &&... args)
static const InteractionDefinition interactions
void process_permutation(const simulation::EventEmitterInterface< simulation::Poseidon2PermutationEvent >::Container &perm_events, TraceContainer &trace)
Processes the permutation events for the Poseidon2 permutation function. It populates the columns for...
void process_permutation_with_memory(const simulation::EventEmitterInterface< simulation::Poseidon2PermutationMemoryEvent >::Container &perm_mem_events, TraceContainer &trace)
Processes the events for the Poseidon2 memory-aware permutation function. It populates the columns fo...
void process_hash(const simulation::EventEmitterInterface< simulation::Poseidon2HashEvent >::Container &hash_events, TraceContainer &trace)
Processes the hash events for the Poseidon2 hash function. It populates the columns for the poseidon2...
Applies the Poseidon2 permutation function from https://eprint.iacr.org/2023/323.
static constexpr void apply_single_sbox(FF &input)
S-box: x -> x^5.
static constexpr void matrix_multiplication_internal(State &input)
static constexpr void matrix_multiplication_external(State &input)
static constexpr void add_round_constants(State &input, const RoundConstants &rc)
static constexpr void apply_sbox(State &input)
static constexpr RoundConstantsContainer round_constants
uint32_t dst_addr
TestTraceContainer trace
AvmFlavorSettings::FF FF
Definition field.hpp:10
lookup_settings< lookup_poseidon2_hash_poseidon2_perm_settings_ > lookup_poseidon2_hash_poseidon2_perm_settings
lookup_settings< lookup_poseidon2_mem_check_src_addr_in_range_settings_ > lookup_poseidon2_mem_check_src_addr_in_range_settings
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
simulation::PublicDataTreeReadWriteEvent event