Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
keccakf1600_trace.cpp
Go to the documentation of this file.
2
3#include <array>
4#include <cstddef>
5#include <cstdint>
6#include <memory>
7
18
19namespace bb::avm2::tracegen {
20using C = Column;
21
22namespace {
23
24// Mapping 2-dimensional array indices of state inputs to columns.
25constexpr std::array<std::array<C, 5>, 5> STATE_IN_COLS = {
26 {
27 {
28 C::keccakf1600_state_in_00,
29 C::keccakf1600_state_in_01,
30 C::keccakf1600_state_in_02,
31 C::keccakf1600_state_in_03,
32 C::keccakf1600_state_in_04,
33 },
34 {
35 C::keccakf1600_state_in_10,
36 C::keccakf1600_state_in_11,
37 C::keccakf1600_state_in_12,
38 C::keccakf1600_state_in_13,
39 C::keccakf1600_state_in_14,
40 },
41 {
42 C::keccakf1600_state_in_20,
43 C::keccakf1600_state_in_21,
44 C::keccakf1600_state_in_22,
45 C::keccakf1600_state_in_23,
46 C::keccakf1600_state_in_24,
47 },
48 {
49 C::keccakf1600_state_in_30,
50 C::keccakf1600_state_in_31,
51 C::keccakf1600_state_in_32,
52 C::keccakf1600_state_in_33,
53 C::keccakf1600_state_in_34,
54 },
55 {
56 C::keccakf1600_state_in_40,
57 C::keccakf1600_state_in_41,
58 C::keccakf1600_state_in_42,
59 C::keccakf1600_state_in_43,
60 C::keccakf1600_state_in_44,
61 },
62 },
63};
64
65// Mapping 2-dimensional array indices of theta xor intermediate value columns.
66constexpr std::array<std::array<C, 4>, 5> THETA_XOR_COLS = {
67 {
68 {
69 C::keccakf1600_theta_xor_01,
70 C::keccakf1600_theta_xor_02,
71 C::keccakf1600_theta_xor_03,
72 C::keccakf1600_theta_xor_row_0,
73 },
74 {
75 C::keccakf1600_theta_xor_11,
76 C::keccakf1600_theta_xor_12,
77 C::keccakf1600_theta_xor_13,
78 C::keccakf1600_theta_xor_row_1,
79 },
80 {
81 C::keccakf1600_theta_xor_21,
82 C::keccakf1600_theta_xor_22,
83 C::keccakf1600_theta_xor_23,
84 C::keccakf1600_theta_xor_row_2,
85 },
86 {
87 C::keccakf1600_theta_xor_31,
88 C::keccakf1600_theta_xor_32,
89 C::keccakf1600_theta_xor_33,
90 C::keccakf1600_theta_xor_row_3,
91 },
92 {
93 C::keccakf1600_theta_xor_41,
94 C::keccakf1600_theta_xor_42,
95 C::keccakf1600_theta_xor_43,
96 C::keccakf1600_theta_xor_row_4,
97 },
98 },
99};
100
101// Mapping indices of theta_xor_row_rotl1 to their columns.
102constexpr std::array<C, 5> THETA_XOR_ROW_ROTL1_COLS = {
103 {
104 C::keccakf1600_theta_xor_row_rotl1_0,
105 C::keccakf1600_theta_xor_row_rotl1_1,
106 C::keccakf1600_theta_xor_row_rotl1_2,
107 C::keccakf1600_theta_xor_row_rotl1_3,
108 C::keccakf1600_theta_xor_row_rotl1_4,
109 },
110};
111
112// Mapping indices of theta_xor_row_msb to their columns.
113constexpr std::array<C, 5> THETA_XOR_ROW_MSB_COLS = {
114 {
115 C::keccakf1600_theta_xor_row_msb_0,
116 C::keccakf1600_theta_xor_row_msb_1,
117 C::keccakf1600_theta_xor_row_msb_2,
118 C::keccakf1600_theta_xor_row_msb_3,
119 C::keccakf1600_theta_xor_row_msb_4,
120 },
121};
122
123// Mapping indices of theta_xor_row_low63 to their columns.
124constexpr std::array<C, 5> THETA_XOR_ROW_LOW63_COLS = {
125 {
126 C::keccakf1600_theta_xor_row_low63_0,
127 C::keccakf1600_theta_xor_row_low63_1,
128 C::keccakf1600_theta_xor_row_low63_2,
129 C::keccakf1600_theta_xor_row_low63_3,
130 C::keccakf1600_theta_xor_row_low63_4,
131 },
132};
133
134// Mapping indices of theta_combined_xor to their columns.
135constexpr std::array<C, 5> THETA_COMBINED_XOR_COLS = {
136 {
137 C::keccakf1600_theta_combined_xor_0,
138 C::keccakf1600_theta_combined_xor_1,
139 C::keccakf1600_theta_combined_xor_2,
140 C::keccakf1600_theta_combined_xor_3,
141 C::keccakf1600_theta_combined_xor_4,
142 },
143};
144
145// Mapping indices of state_theta to their columns.
146constexpr std::array<std::array<C, 5>, 5> STATE_THETA_COLS = {
147 {
148 {
149 C::keccakf1600_state_theta_00,
150 C::keccakf1600_state_theta_01,
151 C::keccakf1600_state_theta_02,
152 C::keccakf1600_state_theta_03,
153 C::keccakf1600_state_theta_04,
154 },
155 {
156 C::keccakf1600_state_theta_10,
157 C::keccakf1600_state_theta_11,
158 C::keccakf1600_state_theta_12,
159 C::keccakf1600_state_theta_13,
160 C::keccakf1600_state_theta_14,
161 },
162 {
163 C::keccakf1600_state_theta_20,
164 C::keccakf1600_state_theta_21,
165 C::keccakf1600_state_theta_22,
166 C::keccakf1600_state_theta_23,
167 C::keccakf1600_state_theta_24,
168 },
169 {
170 C::keccakf1600_state_theta_30,
171 C::keccakf1600_state_theta_31,
172 C::keccakf1600_state_theta_32,
173 C::keccakf1600_state_theta_33,
174 C::keccakf1600_state_theta_34,
175 },
176 {
177 C::keccakf1600_state_theta_40,
178 C::keccakf1600_state_theta_41,
179 C::keccakf1600_state_theta_42,
180 C::keccakf1600_state_theta_43,
181 C::keccakf1600_state_theta_44,
182 },
183 },
184};
185
186// Mapping indices of state_theta_hi to their columns.
187// As index 00 is not used here, we flatten the list and start with 01.
188constexpr std::array<C, 24> STATE_THETA_HI_COLS = {
189 {
190 C::keccakf1600_state_theta_hi_01, C::keccakf1600_state_theta_hi_02, C::keccakf1600_state_theta_hi_03,
191 C::keccakf1600_state_theta_hi_04, C::keccakf1600_state_theta_hi_10, C::keccakf1600_state_theta_hi_11,
192 C::keccakf1600_state_theta_hi_12, C::keccakf1600_state_theta_hi_13, C::keccakf1600_state_theta_hi_14,
193 C::keccakf1600_state_theta_hi_20, C::keccakf1600_state_theta_hi_21, C::keccakf1600_state_theta_hi_22,
194 C::keccakf1600_state_theta_hi_23, C::keccakf1600_state_theta_hi_24, C::keccakf1600_state_theta_hi_30,
195 C::keccakf1600_state_theta_hi_31, C::keccakf1600_state_theta_hi_32, C::keccakf1600_state_theta_hi_33,
196 C::keccakf1600_state_theta_hi_34, C::keccakf1600_state_theta_hi_40, C::keccakf1600_state_theta_hi_41,
197 C::keccakf1600_state_theta_hi_42, C::keccakf1600_state_theta_hi_43, C::keccakf1600_state_theta_hi_44,
198 },
199};
200
201// Mapping indices of state_theta_low to their columns.
202// As index 00 is not used here, we flatten the list and start with 01.
203constexpr std::array<C, 24> STATE_THETA_LOW_COLS = {
204 {
205 C::keccakf1600_state_theta_low_01, C::keccakf1600_state_theta_low_02, C::keccakf1600_state_theta_low_03,
206 C::keccakf1600_state_theta_low_04, C::keccakf1600_state_theta_low_10, C::keccakf1600_state_theta_low_11,
207 C::keccakf1600_state_theta_low_12, C::keccakf1600_state_theta_low_13, C::keccakf1600_state_theta_low_14,
208 C::keccakf1600_state_theta_low_20, C::keccakf1600_state_theta_low_21, C::keccakf1600_state_theta_low_22,
209 C::keccakf1600_state_theta_low_23, C::keccakf1600_state_theta_low_24, C::keccakf1600_state_theta_low_30,
210 C::keccakf1600_state_theta_low_31, C::keccakf1600_state_theta_low_32, C::keccakf1600_state_theta_low_33,
211 C::keccakf1600_state_theta_low_34, C::keccakf1600_state_theta_low_40, C::keccakf1600_state_theta_low_41,
212 C::keccakf1600_state_theta_low_42, C::keccakf1600_state_theta_low_43, C::keccakf1600_state_theta_low_44,
213 },
214};
215
216// Mapping indices of state_rho to their columns.
217// As index 00 is not used here, we flatten the list and start with 01.
218constexpr std::array<C, 24> STATE_RHO_COLS = {
219 {
220 C::keccakf1600_state_rho_01, C::keccakf1600_state_rho_02, C::keccakf1600_state_rho_03,
221 C::keccakf1600_state_rho_04, C::keccakf1600_state_rho_10, C::keccakf1600_state_rho_11,
222 C::keccakf1600_state_rho_12, C::keccakf1600_state_rho_13, C::keccakf1600_state_rho_14,
223 C::keccakf1600_state_rho_20, C::keccakf1600_state_rho_21, C::keccakf1600_state_rho_22,
224 C::keccakf1600_state_rho_23, C::keccakf1600_state_rho_24, C::keccakf1600_state_rho_30,
225 C::keccakf1600_state_rho_31, C::keccakf1600_state_rho_32, C::keccakf1600_state_rho_33,
226 C::keccakf1600_state_rho_34, C::keccakf1600_state_rho_40, C::keccakf1600_state_rho_41,
227 C::keccakf1600_state_rho_42, C::keccakf1600_state_rho_43, C::keccakf1600_state_rho_44,
228 },
229};
230
231// Mapping indices of rho rotation constants and the corresponding constant columns.
232// As index 00 is not used here, we flatten the list and start with 01.
233constexpr std::array<C, 24> RHO_ROTATION_LEN_COLS = {
234 {
235 C::keccakf1600_rot_64_min_len_01, C::keccakf1600_rot_len_02, C::keccakf1600_rot_64_min_len_03,
236 C::keccakf1600_rot_len_04, C::keccakf1600_rot_len_10, C::keccakf1600_rot_64_min_len_11,
237 C::keccakf1600_rot_len_12, C::keccakf1600_rot_64_min_len_13, C::keccakf1600_rot_len_14,
238 C::keccakf1600_rot_64_min_len_20, C::keccakf1600_rot_len_21, C::keccakf1600_rot_64_min_len_22,
239 C::keccakf1600_rot_len_23, C::keccakf1600_rot_64_min_len_24, C::keccakf1600_rot_len_30,
240 C::keccakf1600_rot_64_min_len_31, C::keccakf1600_rot_len_32, C::keccakf1600_rot_len_33,
241 C::keccakf1600_rot_64_min_len_34, C::keccakf1600_rot_len_40, C::keccakf1600_rot_len_41,
242 C::keccakf1600_rot_64_min_len_42, C::keccakf1600_rot_len_43, C::keccakf1600_rot_len_44,
243 },
244};
245
246// Mapping indices of "pi not" values to their columns
247constexpr std::array<std::array<C, 5>, 5> STATE_PI_NOT_COLS = {
248 {
249 {
250 C::keccakf1600_state_pi_not_00,
251 C::keccakf1600_state_pi_not_01,
252 C::keccakf1600_state_pi_not_02,
253 C::keccakf1600_state_pi_not_03,
254 C::keccakf1600_state_pi_not_04,
255 },
256 {
257 C::keccakf1600_state_pi_not_10,
258 C::keccakf1600_state_pi_not_11,
259 C::keccakf1600_state_pi_not_12,
260 C::keccakf1600_state_pi_not_13,
261 C::keccakf1600_state_pi_not_14,
262 },
263 {
264 C::keccakf1600_state_pi_not_20,
265 C::keccakf1600_state_pi_not_21,
266 C::keccakf1600_state_pi_not_22,
267 C::keccakf1600_state_pi_not_23,
268 C::keccakf1600_state_pi_not_24,
269 },
270 {
271 C::keccakf1600_state_pi_not_30,
272 C::keccakf1600_state_pi_not_31,
273 C::keccakf1600_state_pi_not_32,
274 C::keccakf1600_state_pi_not_33,
275 C::keccakf1600_state_pi_not_34,
276 },
277 {
278 C::keccakf1600_state_pi_not_40,
279 C::keccakf1600_state_pi_not_41,
280 C::keccakf1600_state_pi_not_42,
281 C::keccakf1600_state_pi_not_43,
282 C::keccakf1600_state_pi_not_44,
283 },
284 },
285};
286
287// Mapping indices of "pi and" values to their columns
288constexpr std::array<std::array<C, 5>, 5> STATE_PI_AND_COLS = {
289 {
290 {
291 C::keccakf1600_state_pi_and_00,
292 C::keccakf1600_state_pi_and_01,
293 C::keccakf1600_state_pi_and_02,
294 C::keccakf1600_state_pi_and_03,
295 C::keccakf1600_state_pi_and_04,
296 },
297 {
298 C::keccakf1600_state_pi_and_10,
299 C::keccakf1600_state_pi_and_11,
300 C::keccakf1600_state_pi_and_12,
301 C::keccakf1600_state_pi_and_13,
302 C::keccakf1600_state_pi_and_14,
303 },
304 {
305 C::keccakf1600_state_pi_and_20,
306 C::keccakf1600_state_pi_and_21,
307 C::keccakf1600_state_pi_and_22,
308 C::keccakf1600_state_pi_and_23,
309 C::keccakf1600_state_pi_and_24,
310 },
311 {
312 C::keccakf1600_state_pi_and_30,
313 C::keccakf1600_state_pi_and_31,
314 C::keccakf1600_state_pi_and_32,
315 C::keccakf1600_state_pi_and_33,
316 C::keccakf1600_state_pi_and_34,
317 },
318 {
319 C::keccakf1600_state_pi_and_40,
320 C::keccakf1600_state_pi_and_41,
321 C::keccakf1600_state_pi_and_42,
322 C::keccakf1600_state_pi_and_43,
323 C::keccakf1600_state_pi_and_44,
324 },
325 },
326};
327
328// Mapping indices of chi values to their columns
329constexpr std::array<std::array<C, 5>, 5> STATE_CHI_COLS = {
330 {
331 {
332 C::keccakf1600_state_chi_00,
333 C::keccakf1600_state_chi_01,
334 C::keccakf1600_state_chi_02,
335 C::keccakf1600_state_chi_03,
336 C::keccakf1600_state_chi_04,
337 },
338 {
339 C::keccakf1600_state_chi_10,
340 C::keccakf1600_state_chi_11,
341 C::keccakf1600_state_chi_12,
342 C::keccakf1600_state_chi_13,
343 C::keccakf1600_state_chi_14,
344 },
345 {
346 C::keccakf1600_state_chi_20,
347 C::keccakf1600_state_chi_21,
348 C::keccakf1600_state_chi_22,
349 C::keccakf1600_state_chi_23,
350 C::keccakf1600_state_chi_24,
351 },
352 {
353 C::keccakf1600_state_chi_30,
354 C::keccakf1600_state_chi_31,
355 C::keccakf1600_state_chi_32,
356 C::keccakf1600_state_chi_33,
357 C::keccakf1600_state_chi_34,
358 },
359 {
360 C::keccakf1600_state_chi_40,
361 C::keccakf1600_state_chi_41,
362 C::keccakf1600_state_chi_42,
363 C::keccakf1600_state_chi_43,
364 C::keccakf1600_state_chi_44,
365 },
366 },
367};
368
369// Mapping 1-dimensional array indices of read/write memory slice values to columns.
370constexpr std::array<C, AVM_KECCAKF1600_STATE_SIZE> MEM_VAL_COLS = {
371 {
372 C::keccak_memory_val00, C::keccak_memory_val01, C::keccak_memory_val02, C::keccak_memory_val03,
373 C::keccak_memory_val04, C::keccak_memory_val10, C::keccak_memory_val11, C::keccak_memory_val12,
374 C::keccak_memory_val13, C::keccak_memory_val14, C::keccak_memory_val20, C::keccak_memory_val21,
375 C::keccak_memory_val22, C::keccak_memory_val23, C::keccak_memory_val24, C::keccak_memory_val30,
376 C::keccak_memory_val31, C::keccak_memory_val32, C::keccak_memory_val33, C::keccak_memory_val34,
377 C::keccak_memory_val40, C::keccak_memory_val41, C::keccak_memory_val42, C::keccak_memory_val43,
378 C::keccak_memory_val44,
379 },
380};
381
382// Populate a memory slice read or write operation for the Keccak permutation.
383void process_single_slice(const simulation::KeccakF1600Event& event, bool write, uint32_t& row, TraceContainer& trace)
384{
386 single_tag_errors.fill(false);
388 tags.fill(MemoryTag::U64);
389
390 // The effective number of rows to populate. In case of a tag error, we only populate
391 // the rows up to where the tag error occurred.
392 size_t num_rows = AVM_KECCAKF1600_STATE_SIZE;
393
394 // The relevant state and read/write memory values depending on read/write boolean.
395 std::array<std::array<FF, 5>, 5> state_ff;
396 if (write) {
397 for (size_t i = 0; i < 5; i++) {
398 for (size_t j = 0; j < 5; j++) {
399 state_ff[i][j] = event.rounds[AVM_KECCAKF1600_NUM_ROUNDS - 1].state_chi[i][j];
400 }
401 }
402 state_ff[0][0] = event.rounds[AVM_KECCAKF1600_NUM_ROUNDS - 1].state_iota_00;
403 } else {
404 // While reading we need to check the tag for each slice value.
405 for (size_t k = 0; k < AVM_KECCAKF1600_STATE_SIZE; k++) {
406 const size_t i = k / 5;
407 const size_t j = k % 5;
408 const auto& mem_val = event.src_mem_values[i][j];
409 state_ff[i][j] = mem_val.as_ff();
410 tags[k] = mem_val.get_tag();
411 if (tags[k] != MemoryTag::U64) {
412 single_tag_errors.at(k) = true;
413 num_rows = k + 1;
414 break;
415 }
416 }
417 }
418
420 tag_errors.fill(single_tag_errors.at(num_rows - 1));
421
422 MemoryAddress addr = write ? event.dst_addr : event.src_addr;
423
424 for (size_t i = 0; i < num_rows; i++) {
425
426 trace.set(
427 row,
428 { {
429 { C::keccak_memory_sel, 1 },
430 { C::keccak_memory_clk, event.execution_clk },
431 { C::keccak_memory_ctr, i + 1 },
432 { C::keccak_memory_ctr_inv, FF(i + 1).invert() },
433 { C::keccak_memory_ctr_min_state_size_inv,
434 i == AVM_KECCAKF1600_STATE_SIZE - 1 ? 1 : (FF(i + 1) - FF(AVM_KECCAKF1600_STATE_SIZE)).invert() },
435 { C::keccak_memory_start_read, (i == 0 && !write) ? 1 : 0 },
436 { C::keccak_memory_start_write, (i == 0 && write) ? 1 : 0 },
437 { C::keccak_memory_ctr_end, i == AVM_KECCAKF1600_STATE_SIZE - 1 ? 1 : 0 },
438 { C::keccak_memory_last, (i == AVM_KECCAKF1600_STATE_SIZE - 1) || single_tag_errors.at(i) ? 1 : 0 },
439 { C::keccak_memory_rw, write ? 1 : 0 },
440 { C::keccak_memory_addr, addr + i },
441 { C::keccak_memory_space_id, event.space_id },
442 { C::keccak_memory_tag, static_cast<uint8_t>(tags[i]) },
443 { C::keccak_memory_tag_min_u64_inv,
444 single_tag_errors.at(i)
445 ? (FF(static_cast<uint8_t>(tags[i])) - FF(static_cast<uint8_t>(MemoryTag::U64))).invert()
446 : 1 },
447 { C::keccak_memory_single_tag_error, single_tag_errors.at(i) ? 1 : 0 },
448 { C::keccak_memory_tag_error, tag_errors.at(i) ? 1 : 0 },
449 { C::keccak_memory_num_rounds, AVM_KECCAKF1600_NUM_ROUNDS },
450 } });
451
452 // We get a "triangle" when shifting values to their columns from val00 bottom-up.
453 for (size_t j = i; j < num_rows; j++) {
454 trace.set(MEM_VAL_COLS.at(j - i), row, state_ff[j / 5][j % 5]);
455 }
456
457 row++;
458 }
459}
460
461} // namespace
462
465{
466 trace.set(C::keccakf1600_last, 0, 1);
467
468 uint32_t row = 1;
469 for (const auto& event : events) {
470 const bool out_of_range = event.src_out_of_range || event.dst_out_of_range;
471 const bool error = out_of_range || event.tag_error;
472
473 for (size_t round_idx = 0; round_idx == 0 || (!error && round_idx < AVM_KECCAKF1600_NUM_ROUNDS); round_idx++) {
474 const auto& round_data = event.rounds[round_idx];
475
476 // Setting the selector, xor operation id, and operation id, round, round cst
477 trace.set(row,
478 { {
479 { C::keccakf1600_sel, 1 },
480 { C::keccakf1600_clk, event.execution_clk },
481 { C::keccakf1600_bitwise_xor_op_id, static_cast<uint8_t>(BitwiseOperation::XOR) },
482 { C::keccakf1600_bitwise_and_op_id, static_cast<uint8_t>(BitwiseOperation::AND) },
483 { C::keccakf1600_tag_u64, static_cast<uint8_t>(MemoryTag::U64) },
484 { C::keccakf1600_round, round_idx + 1 }, // round is 1-indexed
485 { C::keccakf1600_round_cst, simulation::keccak_round_constants[round_idx] },
486 { C::keccakf1600_thirty_two, AVM_MEMORY_NUM_BITS },
487 } });
488
489 // Setting the rotation length constants
490 // If the constant is <= 32, we set it in the column.
491 // Otherwise, we set 64 - constant.
492 for (size_t k = 1; k < 25; k++) {
493 const size_t i = k / 5;
494 const size_t j = k % 5;
495 const auto rotation_len = simulation::keccak_rotation_len[i][j];
496 const auto value = rotation_len <= 32 ? rotation_len : 64 - rotation_len;
497 trace.set(RHO_ROTATION_LEN_COLS.at(k - 1), row, value);
498 }
499
500 // Selectors start and last.
501 // src_address required on first row
502 if (round_idx == 0) {
503 trace.set(row,
504 { {
505 { C::keccakf1600_start, 1 },
506 { C::keccakf1600_src_addr, event.src_addr },
507 { C::keccakf1600_src_out_of_range_error, event.src_out_of_range ? 1 : 0 },
508 { C::keccakf1600_dst_out_of_range_error, event.dst_out_of_range ? 1 : 0 },
509 { C::keccakf1600_src_abs_diff, event.src_abs_diff },
510 { C::keccakf1600_dst_abs_diff, event.dst_abs_diff },
511 { C::keccakf1600_tag_error, event.tag_error ? 1 : 0 },
512 { C::keccakf1600_sel_slice_read, out_of_range ? 0 : 1 },
513 { C::keccakf1600_error, error ? 1 : 0 },
514 { C::keccakf1600_last,
515 error ? 1 : 0 }, // We set last at the initial row when there is an error.
516 // Note that the loop will stop after the initial round.
517 } });
518
519 } else if (round_idx == AVM_KECCAKF1600_NUM_ROUNDS - 1) {
520 trace.set(row,
521 { {
522 { C::keccakf1600_last, 1 },
523 { C::keccakf1600_sel_slice_write, error ? 0 : 1 },
524 } });
525 };
526
527 // dst_address, sel_no_error, space_id are required at every row as we propagate
528 // for the slice memory write lookup.
529 trace.set(row,
530 { {
531 { C::keccakf1600_dst_addr, event.dst_addr },
532 { C::keccakf1600_sel_no_error, error ? 0 : 1 },
533 { C::keccakf1600_space_id, event.space_id },
534 { C::keccakf1600_round_inv, FF(round_idx + 1).invert() },
535 } });
536
537 // When no out-of-range value occured but a tag value error, we
538 // need to set the initial state values in the first round.
539 if (!out_of_range && event.tag_error && round_idx == 0) {
540 for (size_t i = 0; i < 5; i++) {
541 for (size_t j = 0; j < 5; j++) {
542 // In simulation we set src_mem_values[i][j] to be the memory value when
543 // tag is U64, otherwise we set it to zero.
544 trace.set(STATE_IN_COLS[i][j], row, event.src_mem_values[i][j]);
545 }
546 }
547 }
548
549 // When there is no error we set state values completely.
550 if (!error) {
551 // Setting state inputs in their corresponding colums
552 for (size_t i = 0; i < 5; i++) {
553 for (size_t j = 0; j < 5; j++) {
554 trace.set(STATE_IN_COLS[i][j], row, round_data.state[i][j]);
555 }
556 }
557
558 // Setting theta xor values to their corresponding columns
559 for (size_t i = 0; i < 5; i++) {
560 for (size_t j = 0; j < 4; j++) {
561 trace.set(THETA_XOR_COLS[i][j], row, round_data.theta_xor[i][j]);
562 }
563 }
564
565 // Setting theta xor final values left rotated by 1
566 // and the msb and low 63 bits values.
567 // Setting theta_combined_xor values
568 for (size_t i = 0; i < 5; i++) {
569 const auto theta_xor_row_rotl1 = round_data.theta_xor_row_rotl1[i];
570 const auto theta_xor_row_msb = theta_xor_row_rotl1 & 1; // lsb of of the rotated value
571 const auto theta_xor_row_low63 = theta_xor_row_rotl1 >> 1; // 63 high bits of the rotated value
572
573 trace.set(row,
574 { {
575 { THETA_XOR_ROW_ROTL1_COLS[i], theta_xor_row_rotl1 },
576 { THETA_XOR_ROW_MSB_COLS[i], theta_xor_row_msb },
577 { THETA_XOR_ROW_LOW63_COLS[i], theta_xor_row_low63 },
578 { THETA_COMBINED_XOR_COLS[i], round_data.theta_combined_xor[i] },
579 } });
580 }
581
582 // Setting state_theta values
583 for (size_t i = 0; i < 5; i++) {
584 for (size_t j = 0; j < 5; j++) {
585 trace.set(STATE_THETA_COLS[i][j], row, round_data.state_theta[i][j]);
586 }
587 }
588
589 // Setting state_theta_hi and state_theta_low and state_rho values.
590 // We loop the flatten index k from 1 to 25 and compute
591 // 2-dimensional indices i = k/5 and j = k%5
592 // Note that intermediate states at index (0,0) are omitted because they are not involved
593 // in constraints.
594 for (size_t k = 1; k < 25; k++) {
595 const size_t i = k / 5;
596 const size_t j = k % 5;
597 const size_t low_num_bits = 64 - simulation::keccak_rotation_len[i][j];
598 const auto state_theta_val = round_data.state_theta[i][j];
599 const auto state_theta_hi = state_theta_val >> low_num_bits;
600 const auto state_theta_low = state_theta_val & ((1ULL << low_num_bits) - 1);
601
602 trace.set(row,
603 { {
604 { STATE_THETA_HI_COLS[k - 1], state_theta_hi },
605 { STATE_THETA_LOW_COLS[k - 1], state_theta_low },
606 { STATE_RHO_COLS[k - 1], round_data.state_rho[i][j] },
607 } });
608 }
609
610 // Setting "pi not", "pi and", and "chi" values
611 for (size_t i = 0; i < 5; i++) {
612 for (size_t j = 0; j < 5; j++) {
613 trace.set(row,
614 { {
615 { STATE_PI_NOT_COLS[i][j], round_data.state_pi_not[i][j] },
616 { STATE_PI_AND_COLS[i][j], round_data.state_pi_and[i][j] },
617 { STATE_CHI_COLS[i][j], round_data.state_chi[i][j] },
618 } });
619 }
620 }
621
622 // Setting iota_00
623 trace.set(C::keccakf1600_state_iota_00, row, round_data.state_iota_00);
624 }
625 row++;
626 }
627 }
628}
629
632{
633 trace.set(0,
634 { {
635 { C::keccak_memory_last, 1 },
636 { C::keccak_memory_ctr_end, 1 },
637 } });
638
639 uint32_t row = 1;
640 for (const auto& event : events) {
641 // Skip the event if there is an out of range error.
642 // Namely, in this case the lookups to the memory slice are inactive.
643 if (!event.src_out_of_range && !event.dst_out_of_range) {
644 process_single_slice(event, /* write */ false, row, trace);
645
646 // Write to memory slice is only active if there is no tag error.
647 if (!event.tag_error) {
648 process_single_slice(event, /* write */ true, row, trace);
649 }
650 }
651 }
652}
653
656 // Theta XOR values
658 .add<lookup_keccakf1600_theta_xor_02_settings, InteractionType::LookupSequential>()
660 .add<lookup_keccakf1600_theta_xor_row_0_settings, InteractionType::LookupSequential>()
662 .add<lookup_keccakf1600_theta_xor_12_settings, InteractionType::LookupSequential>()
664 .add<lookup_keccakf1600_theta_xor_row_1_settings, InteractionType::LookupSequential>()
666 .add<lookup_keccakf1600_theta_xor_22_settings, InteractionType::LookupSequential>()
668 .add<lookup_keccakf1600_theta_xor_row_2_settings, InteractionType::LookupSequential>()
670 .add<lookup_keccakf1600_theta_xor_32_settings, InteractionType::LookupSequential>()
672 .add<lookup_keccakf1600_theta_xor_row_3_settings, InteractionType::LookupSequential>()
674 .add<lookup_keccakf1600_theta_xor_42_settings, InteractionType::LookupSequential>()
676 .add<lookup_keccakf1600_theta_xor_row_4_settings, InteractionType::LookupSequential>()
677 // Theta XOR combined values
679 .add<lookup_keccakf1600_theta_combined_xor_1_settings, InteractionType::LookupSequential>()
681 .add<lookup_keccakf1600_theta_combined_xor_3_settings, InteractionType::LookupSequential>()
683 // State Theta final values
684 .add<lookup_keccakf1600_state_theta_00_settings, InteractionType::LookupSequential>()
686 .add<lookup_keccakf1600_state_theta_02_settings, InteractionType::LookupSequential>()
688 .add<lookup_keccakf1600_state_theta_04_settings, InteractionType::LookupSequential>()
690 .add<lookup_keccakf1600_state_theta_11_settings, InteractionType::LookupSequential>()
692 .add<lookup_keccakf1600_state_theta_13_settings, InteractionType::LookupSequential>()
694 .add<lookup_keccakf1600_state_theta_20_settings, InteractionType::LookupSequential>()
696 .add<lookup_keccakf1600_state_theta_22_settings, InteractionType::LookupSequential>()
698 .add<lookup_keccakf1600_state_theta_24_settings, InteractionType::LookupSequential>()
700 .add<lookup_keccakf1600_state_theta_31_settings, InteractionType::LookupSequential>()
702 .add<lookup_keccakf1600_state_theta_33_settings, InteractionType::LookupSequential>()
704 .add<lookup_keccakf1600_state_theta_40_settings, InteractionType::LookupSequential>()
706 .add<lookup_keccakf1600_state_theta_42_settings, InteractionType::LookupSequential>()
708 .add<lookup_keccakf1600_state_theta_44_settings, InteractionType::LookupSequential>()
709 // Range check on some state theta limbs
711 .add<lookup_keccakf1600_theta_limb_02_range_settings, InteractionType::LookupGeneric>()
713 .add<lookup_keccakf1600_theta_limb_04_range_settings, InteractionType::LookupGeneric>()
715 .add<lookup_keccakf1600_theta_limb_11_range_settings, InteractionType::LookupGeneric>()
717 .add<lookup_keccakf1600_theta_limb_13_range_settings, InteractionType::LookupGeneric>()
719 .add<lookup_keccakf1600_theta_limb_20_range_settings, InteractionType::LookupGeneric>()
721 .add<lookup_keccakf1600_theta_limb_22_range_settings, InteractionType::LookupGeneric>()
723 .add<lookup_keccakf1600_theta_limb_24_range_settings, InteractionType::LookupGeneric>()
725 .add<lookup_keccakf1600_theta_limb_31_range_settings, InteractionType::LookupGeneric>()
727 .add<lookup_keccakf1600_theta_limb_33_range_settings, InteractionType::LookupGeneric>()
729 .add<lookup_keccakf1600_theta_limb_40_range_settings, InteractionType::LookupGeneric>()
731 .add<lookup_keccakf1600_theta_limb_42_range_settings, InteractionType::LookupGeneric>()
733 .add<lookup_keccakf1600_theta_limb_44_range_settings, InteractionType::LookupGeneric>()
734 // "pi and" values
736 .add<lookup_keccakf1600_state_pi_and_01_settings, InteractionType::LookupSequential>()
738 .add<lookup_keccakf1600_state_pi_and_03_settings, InteractionType::LookupSequential>()
740 .add<lookup_keccakf1600_state_pi_and_10_settings, InteractionType::LookupSequential>()
742 .add<lookup_keccakf1600_state_pi_and_12_settings, InteractionType::LookupSequential>()
744 .add<lookup_keccakf1600_state_pi_and_14_settings, InteractionType::LookupSequential>()
746 .add<lookup_keccakf1600_state_pi_and_21_settings, InteractionType::LookupSequential>()
748 .add<lookup_keccakf1600_state_pi_and_23_settings, InteractionType::LookupSequential>()
750 .add<lookup_keccakf1600_state_pi_and_30_settings, InteractionType::LookupSequential>()
752 .add<lookup_keccakf1600_state_pi_and_32_settings, InteractionType::LookupSequential>()
754 .add<lookup_keccakf1600_state_pi_and_34_settings, InteractionType::LookupSequential>()
756 .add<lookup_keccakf1600_state_pi_and_41_settings, InteractionType::LookupSequential>()
758 .add<lookup_keccakf1600_state_pi_and_43_settings, InteractionType::LookupSequential>()
760 // chi values
761 .add<lookup_keccakf1600_state_chi_00_settings, InteractionType::LookupSequential>()
763 .add<lookup_keccakf1600_state_chi_02_settings, InteractionType::LookupSequential>()
765 .add<lookup_keccakf1600_state_chi_04_settings, InteractionType::LookupSequential>()
767 .add<lookup_keccakf1600_state_chi_11_settings, InteractionType::LookupSequential>()
769 .add<lookup_keccakf1600_state_chi_13_settings, InteractionType::LookupSequential>()
771 .add<lookup_keccakf1600_state_chi_20_settings, InteractionType::LookupSequential>()
773 .add<lookup_keccakf1600_state_chi_22_settings, InteractionType::LookupSequential>()
775 .add<lookup_keccakf1600_state_chi_24_settings, InteractionType::LookupSequential>()
777 .add<lookup_keccakf1600_state_chi_31_settings, InteractionType::LookupSequential>()
779 .add<lookup_keccakf1600_state_chi_33_settings, InteractionType::LookupSequential>()
781 .add<lookup_keccakf1600_state_chi_40_settings, InteractionType::LookupSequential>()
783 .add<lookup_keccakf1600_state_chi_42_settings, InteractionType::LookupSequential>()
785 .add<lookup_keccakf1600_state_chi_44_settings, InteractionType::LookupSequential>()
786 // iota_00
788 // round constants lookup
789 .add<lookup_keccakf1600_round_cst_settings, InteractionType::LookupIntoIndexedByClk>()
790 // Memory slices permutations
792 .add<perm_keccakf1600_write_to_slice_settings, InteractionType::Permutation>()
793 // Range check for slice memory ranges.
794 // Range checks are de-duplicated and therefore we can't use the interaction builder
795 // LookupIntoDynamicTableSequential.
797 .add<lookup_keccakf1600_dst_abs_diff_positive_settings, InteractionType::LookupGeneric>();
798
799} // namespace bb::avm2::tracegen
#define AVM_KECCAKF1600_STATE_SIZE
#define AVM_KECCAKF1600_NUM_ROUNDS
#define AVM_MEMORY_NUM_BITS
InteractionDefinition & add(auto &&... args)
void process_memory_slices(const simulation::EventEmitterInterface< simulation::KeccakF1600Event >::Container &events, TraceContainer &trace)
static const InteractionDefinition interactions
void process_permutation(const simulation::EventEmitterInterface< simulation::KeccakF1600Event >::Container &events, TraceContainer &trace)
void set(Column col, uint32_t row, const FF &value)
TestTraceContainer trace
constexpr std::array< uint64_t, 24 > keccak_round_constants
constexpr std::array< std::array< uint8_t, 5 >, 5 > keccak_rotation_len
lookup_settings< lookup_keccakf1600_theta_xor_23_settings_ > lookup_keccakf1600_theta_xor_23_settings
lookup_settings< lookup_keccakf1600_theta_limb_10_range_settings_ > lookup_keccakf1600_theta_limb_10_range_settings
lookup_settings< lookup_keccakf1600_state_theta_34_settings_ > lookup_keccakf1600_state_theta_34_settings
lookup_settings< lookup_keccakf1600_theta_limb_12_range_settings_ > lookup_keccakf1600_theta_limb_12_range_settings
lookup_settings< lookup_keccakf1600_state_theta_32_settings_ > lookup_keccakf1600_state_theta_32_settings
lookup_settings< lookup_keccakf1600_theta_limb_01_range_settings_ > lookup_keccakf1600_theta_limb_01_range_settings
permutation_settings< perm_keccakf1600_read_to_slice_settings_ > perm_keccakf1600_read_to_slice_settings
lookup_settings< lookup_keccakf1600_theta_xor_31_settings_ > lookup_keccakf1600_theta_xor_31_settings
lookup_settings< lookup_keccakf1600_theta_xor_13_settings_ > lookup_keccakf1600_theta_xor_13_settings
lookup_settings< lookup_keccakf1600_theta_xor_03_settings_ > lookup_keccakf1600_theta_xor_03_settings
lookup_settings< lookup_keccakf1600_state_theta_03_settings_ > lookup_keccakf1600_state_theta_03_settings
lookup_settings< lookup_keccakf1600_theta_limb_30_range_settings_ > lookup_keccakf1600_theta_limb_30_range_settings
lookup_settings< lookup_keccakf1600_state_pi_and_11_settings_ > lookup_keccakf1600_state_pi_and_11_settings
lookup_settings< lookup_keccakf1600_state_theta_21_settings_ > lookup_keccakf1600_state_theta_21_settings
lookup_settings< lookup_keccakf1600_state_chi_41_settings_ > lookup_keccakf1600_state_chi_41_settings
lookup_settings< lookup_keccakf1600_src_abs_diff_positive_settings_ > lookup_keccakf1600_src_abs_diff_positive_settings
lookup_settings< lookup_keccakf1600_state_chi_23_settings_ > lookup_keccakf1600_state_chi_23_settings
lookup_settings< lookup_keccakf1600_theta_limb_21_range_settings_ > lookup_keccakf1600_theta_limb_21_range_settings
lookup_settings< lookup_keccakf1600_state_pi_and_20_settings_ > lookup_keccakf1600_state_pi_and_20_settings
lookup_settings< lookup_keccakf1600_state_chi_43_settings_ > lookup_keccakf1600_state_chi_43_settings
lookup_settings< lookup_keccakf1600_state_chi_03_settings_ > lookup_keccakf1600_state_chi_03_settings
lookup_settings< lookup_keccakf1600_theta_limb_43_range_settings_ > lookup_keccakf1600_theta_limb_43_range_settings
lookup_settings< lookup_keccakf1600_state_pi_and_31_settings_ > lookup_keccakf1600_state_pi_and_31_settings
lookup_settings< lookup_keccakf1600_state_theta_01_settings_ > lookup_keccakf1600_state_theta_01_settings
lookup_settings< lookup_keccakf1600_state_chi_01_settings_ > lookup_keccakf1600_state_chi_01_settings
lookup_settings< lookup_keccakf1600_theta_combined_xor_2_settings_ > lookup_keccakf1600_theta_combined_xor_2_settings
lookup_settings< lookup_keccakf1600_state_pi_and_02_settings_ > lookup_keccakf1600_state_pi_and_02_settings
lookup_settings< lookup_keccakf1600_state_chi_21_settings_ > lookup_keccakf1600_state_chi_21_settings
lookup_settings< lookup_keccakf1600_state_chi_34_settings_ > lookup_keccakf1600_state_chi_34_settings
lookup_settings< lookup_keccakf1600_state_theta_43_settings_ > lookup_keccakf1600_state_theta_43_settings
lookup_settings< lookup_keccakf1600_state_iota_00_settings_ > lookup_keccakf1600_state_iota_00_settings
lookup_settings< lookup_keccakf1600_state_chi_12_settings_ > lookup_keccakf1600_state_chi_12_settings
lookup_settings< lookup_keccakf1600_state_chi_32_settings_ > lookup_keccakf1600_state_chi_32_settings
lookup_settings< lookup_keccakf1600_theta_limb_34_range_settings_ > lookup_keccakf1600_theta_limb_34_range_settings
lookup_settings< lookup_keccakf1600_state_pi_and_22_settings_ > lookup_keccakf1600_state_pi_and_22_settings
lookup_settings< lookup_keccakf1600_theta_xor_21_settings_ > lookup_keccakf1600_theta_xor_21_settings
lookup_settings< lookup_keccakf1600_theta_limb_14_range_settings_ > lookup_keccakf1600_theta_limb_14_range_settings
lookup_settings< lookup_keccakf1600_theta_limb_32_range_settings_ > lookup_keccakf1600_theta_limb_32_range_settings
lookup_settings< lookup_keccakf1600_theta_combined_xor_4_settings_ > lookup_keccakf1600_theta_combined_xor_4_settings
lookup_settings< lookup_keccakf1600_state_theta_14_settings_ > lookup_keccakf1600_state_theta_14_settings
lookup_settings< lookup_keccakf1600_theta_xor_41_settings_ > lookup_keccakf1600_theta_xor_41_settings
lookup_settings< lookup_keccakf1600_state_pi_and_24_settings_ > lookup_keccakf1600_state_pi_and_24_settings
lookup_settings< lookup_keccakf1600_theta_xor_43_settings_ > lookup_keccakf1600_theta_xor_43_settings
lookup_settings< lookup_keccakf1600_state_pi_and_13_settings_ > lookup_keccakf1600_state_pi_and_13_settings
lookup_settings< lookup_keccakf1600_theta_combined_xor_0_settings_ > lookup_keccakf1600_theta_combined_xor_0_settings
lookup_settings< lookup_keccakf1600_state_theta_23_settings_ > lookup_keccakf1600_state_theta_23_settings
lookup_settings< lookup_keccakf1600_state_pi_and_04_settings_ > lookup_keccakf1600_state_pi_and_04_settings
lookup_settings< lookup_keccakf1600_theta_limb_41_range_settings_ > lookup_keccakf1600_theta_limb_41_range_settings
lookup_settings< lookup_keccakf1600_state_theta_30_settings_ > lookup_keccakf1600_state_theta_30_settings
lookup_settings< lookup_keccakf1600_theta_xor_33_settings_ > lookup_keccakf1600_theta_xor_33_settings
lookup_settings< lookup_keccakf1600_theta_limb_03_range_settings_ > lookup_keccakf1600_theta_limb_03_range_settings
lookup_settings< lookup_keccakf1600_state_pi_and_00_settings_ > lookup_keccakf1600_state_pi_and_00_settings
lookup_settings< lookup_keccakf1600_state_theta_10_settings_ > lookup_keccakf1600_state_theta_10_settings
lookup_settings< lookup_keccakf1600_state_theta_41_settings_ > lookup_keccakf1600_state_theta_41_settings
lookup_settings< lookup_keccakf1600_state_chi_10_settings_ > lookup_keccakf1600_state_chi_10_settings
lookup_settings< lookup_keccakf1600_theta_xor_01_settings_ > lookup_keccakf1600_theta_xor_01_settings
lookup_settings< lookup_keccakf1600_state_chi_14_settings_ > lookup_keccakf1600_state_chi_14_settings
lookup_settings< lookup_keccakf1600_state_pi_and_42_settings_ > lookup_keccakf1600_state_pi_and_42_settings
lookup_settings< lookup_keccakf1600_state_pi_and_44_settings_ > lookup_keccakf1600_state_pi_and_44_settings
uint32_t MemoryAddress
lookup_settings< lookup_keccakf1600_state_theta_12_settings_ > lookup_keccakf1600_state_theta_12_settings
lookup_settings< lookup_keccakf1600_state_pi_and_33_settings_ > lookup_keccakf1600_state_pi_and_33_settings
lookup_settings< lookup_keccakf1600_theta_limb_23_range_settings_ > lookup_keccakf1600_theta_limb_23_range_settings
lookup_settings< lookup_keccakf1600_state_chi_30_settings_ > lookup_keccakf1600_state_chi_30_settings
AvmFlavorSettings::FF FF
Definition field.hpp:10
lookup_settings< lookup_keccakf1600_state_pi_and_40_settings_ > lookup_keccakf1600_state_pi_and_40_settings
lookup_settings< lookup_keccakf1600_theta_xor_11_settings_ > lookup_keccakf1600_theta_xor_11_settings
void write(B &buf, field2< base_field, Params > const &value)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
simulation::PublicDataTreeReadWriteEvent event