Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
precomputed_trace.cpp
Go to the documentation of this file.
2
3#include <array>
4#include <cstddef>
5#include <cstdint>
6
19
20namespace bb::avm2::tracegen {
21
23{
24 using C = Column;
25
26 // First row.
27 trace.set(C::precomputed_first_row, 0, 1);
28
29 // Clk
30 // TODO: What a waste of 64MB. Can we elegantly have a flag for this?
31 trace.reserve_column(C::precomputed_clk, num_rows);
32 for (uint32_t i = 0; i < num_rows; i++) {
33 trace.set(C::precomputed_clk, i, i);
34 }
35}
36
38{
39 using C = Column;
40
41 // 256 per input (a and b), and 3 different bitwise ops
42 constexpr auto num_rows = 256 * 256 * 3;
43 trace.reserve_column(C::precomputed_sel_bitwise, num_rows);
44 trace.reserve_column(C::precomputed_bitwise_input_a, num_rows);
45 trace.reserve_column(C::precomputed_bitwise_input_b, num_rows);
46 trace.reserve_column(C::precomputed_bitwise_output, num_rows);
47
48 // row # is derived as:
49 // - input_b: bits 0...7 (0 being LSB)
50 // - input_a: bits 8...15
51 // - op_id: bits 16...
52 // In other words, the first 256*256 rows are for op_id 0. Next are for op_id 1, followed by op_id 2.
53 auto row_from_inputs = [](BitwiseOperation op_id, uint32_t input_a, uint32_t input_b) -> uint32_t {
54 return (static_cast<uint32_t>(op_id) << 16) | (input_a << 8) | input_b;
55 };
56 auto compute_operation = [](BitwiseOperation op_id, uint32_t a, uint32_t b) -> uint32_t {
57 switch (op_id) {
59 return a & b;
61 return a | b;
63 return a ^ b;
64 }
65
66 assert(false && "This should not happen");
67 return 0; // Should never happen. To please the compiler.
68 };
69
71 for (uint32_t a = 0; a < 256; a++) {
72 for (uint32_t b = 0; b < 256; b++) {
73 trace.set(row_from_inputs(op_id, a, b),
74 { {
75 { C::precomputed_sel_bitwise, 1 },
76 { C::precomputed_bitwise_op_id, static_cast<uint8_t>(op_id) },
77 { C::precomputed_bitwise_input_a, FF(a) },
78 { C::precomputed_bitwise_input_b, FF(b) },
79 { C::precomputed_bitwise_output, FF(compute_operation(op_id, a, b)) },
80 } });
81 }
82 }
83 }
84}
85
93{
94 using C = Column;
95
96 constexpr auto num_rows = 1 << 8; // 256
97 // Set this selector high for the first 2^8 rows
98 // For these rows, clk will be 0...255
99 trace.reserve_column(C::precomputed_sel_range_8, num_rows);
100 for (uint32_t i = 0; i < num_rows; i++) {
101 trace.set(C::precomputed_sel_range_8, i, 1);
102 }
103}
104
112{
113 using C = Column;
114
115 constexpr auto num_rows = 1 << 16; // 2^16
116 // Set this selector high for the first 2^16 rows
117 // For these rows, clk will be 0...2^16-1
118 trace.reserve_column(C::precomputed_sel_range_16, num_rows);
119 for (uint32_t i = 0; i < num_rows; i++) {
120 trace.set(C::precomputed_sel_range_16, i, 1);
121 }
122}
123
129{
130 using C = Column;
131
132 constexpr auto num_rows = 1 << 8; // 2^8 = 256
133 trace.reserve_column(C::precomputed_power_of_2, num_rows);
134 for (uint32_t i = 0; i < num_rows; i++) {
135 trace.set(C::precomputed_power_of_2, i, uint256_t(1) << uint256_t(i));
136 }
137}
138
140{
141 using C = Column;
142
143 constexpr std::array<uint32_t, 64> round_constants{
144 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
145 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
146 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
147 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
148 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
149 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
150 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
151 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
152 };
153 constexpr auto num_rows = round_constants.size();
154 trace.reserve_column(C::precomputed_sha256_compression_round_constant, num_rows);
155 trace.reserve_column(C::precomputed_sel_sha256_compression, num_rows);
156 for (uint32_t i = 0; i < num_rows; i++) {
157 trace.set(i,
158 { { { C::precomputed_sel_sha256_compression, 1 },
159 { C::precomputed_sha256_compression_round_constant, round_constants[i] } } });
160 }
161}
162
164{
165 using C = Column;
167
168 constexpr uint32_t NUM_TAGS = static_cast<uint32_t>(MemoryTag::MAX) + 1;
169 for (uint32_t i = 0; i < NUM_TAGS; i++) {
170 const auto tag = static_cast<MemoryTag>(i);
171 trace.set(i, // Column number corresponds to MemoryTag enum value.
172 { {
173 { C::precomputed_sel_tag_parameters, 1 },
174 { C::precomputed_tag_byte_length, get_tag_bytes(tag) },
175 { C::precomputed_tag_max_bits, get_tag_bits(tag) },
176 { C::precomputed_tag_max_value, get_tag_max_value(tag) },
177 } });
178 }
179}
180
182{
183 using C = Column;
184 const std::array<Column, NUM_OP_DC_SELECTORS> sel_op_dc_columns = {
185 C::precomputed_sel_op_dc_0, C::precomputed_sel_op_dc_1, C::precomputed_sel_op_dc_2,
186 C::precomputed_sel_op_dc_3, C::precomputed_sel_op_dc_4, C::precomputed_sel_op_dc_5,
187 C::precomputed_sel_op_dc_6, C::precomputed_sel_op_dc_7, C::precomputed_sel_op_dc_8,
188 C::precomputed_sel_op_dc_9, C::precomputed_sel_op_dc_10, C::precomputed_sel_op_dc_11,
189 C::precomputed_sel_op_dc_12, C::precomputed_sel_op_dc_13, C::precomputed_sel_op_dc_14,
190 C::precomputed_sel_op_dc_15, C::precomputed_sel_op_dc_16, C::precomputed_sel_op_dc_17,
191 };
192
193 // First set the selector for this table lookup.
194 constexpr uint32_t num_rows = 1 << 8; // 256
195 constexpr uint32_t num_opcodes = static_cast<uint32_t>(WireOpCode::LAST_OPCODE_SENTINEL);
196 trace.reserve_column(C::precomputed_opcode_out_of_range, num_rows - num_opcodes);
197 for (uint32_t i = num_opcodes; i < num_rows; i++) {
198 trace.set(C::precomputed_opcode_out_of_range, i, 1);
199 }
200
201 for (size_t i = 0; i < NUM_OP_DC_SELECTORS; i++) {
202 trace.reserve_column(sel_op_dc_columns.at(i), num_opcodes);
203 }
204 trace.reserve_column(C::precomputed_exec_opcode, num_opcodes);
205 trace.reserve_column(C::precomputed_instr_size, num_opcodes);
206
207 // Fill the lookup tables with the operand decomposition selectors.
208 for (const auto& [wire_opcode, wire_instruction_spec] : WIRE_INSTRUCTION_SPEC) {
209 for (size_t i = 0; i < NUM_OP_DC_SELECTORS; i++) {
210 trace.set(sel_op_dc_columns.at(i),
211 static_cast<uint32_t>(wire_opcode),
212 wire_instruction_spec.op_dc_selectors.at(i));
213 }
214 trace.set(C::precomputed_exec_opcode,
215 static_cast<uint32_t>(wire_opcode),
216 static_cast<uint32_t>(wire_instruction_spec.exec_opcode));
217 trace.set(C::precomputed_instr_size, static_cast<uint32_t>(wire_opcode), wire_instruction_spec.size_in_bytes);
218
219 if (wire_instruction_spec.tag_operand_idx.has_value()) {
220 trace.set(C::precomputed_sel_has_tag, static_cast<uint32_t>(wire_opcode), 1);
221
222 if (wire_instruction_spec.tag_operand_idx.value() == 2) {
223 trace.set(C::precomputed_sel_tag_is_op2, static_cast<uint32_t>(wire_opcode), 1);
224 }
225 }
226 }
227}
228
230{
231 using C = Column;
232
233 constexpr std::array<Column, AVM_MAX_REGISTERS> MEM_OP_REG_COLUMNS = {
234 Column::precomputed_sel_mem_op_reg_0_, Column::precomputed_sel_mem_op_reg_1_,
235 Column::precomputed_sel_mem_op_reg_2_, Column::precomputed_sel_mem_op_reg_3_,
236 Column::precomputed_sel_mem_op_reg_4_, Column::precomputed_sel_mem_op_reg_5_,
237 };
238 constexpr std::array<Column, AVM_MAX_REGISTERS> RW_COLUMNS = {
239 Column::precomputed_rw_reg_0_, Column::precomputed_rw_reg_1_, Column::precomputed_rw_reg_2_,
240 Column::precomputed_rw_reg_3_, Column::precomputed_rw_reg_4_, Column::precomputed_rw_reg_5_,
241 };
242 constexpr std::array<Column, AVM_MAX_REGISTERS> DO_TAG_CHECK_COLUMNS = {
243 Column::precomputed_sel_tag_check_reg_0_, Column::precomputed_sel_tag_check_reg_1_,
244 Column::precomputed_sel_tag_check_reg_2_, Column::precomputed_sel_tag_check_reg_3_,
245 Column::precomputed_sel_tag_check_reg_4_, Column::precomputed_sel_tag_check_reg_5_,
246 };
247 constexpr std::array<Column, AVM_MAX_REGISTERS> EXPECTED_TAG_COLUMNS = {
248 Column::precomputed_expected_tag_reg_0_, Column::precomputed_expected_tag_reg_1_,
249 Column::precomputed_expected_tag_reg_2_, Column::precomputed_expected_tag_reg_3_,
250 Column::precomputed_expected_tag_reg_4_, Column::precomputed_expected_tag_reg_5_,
251 };
252
253 constexpr std::array<Column, AVM_MAX_OPERANDS> SEL_OP_IS_ADDRESS_COLUMNS = {
254 Column::precomputed_sel_op_is_address_0_, Column::precomputed_sel_op_is_address_1_,
255 Column::precomputed_sel_op_is_address_2_, Column::precomputed_sel_op_is_address_3_,
256 Column::precomputed_sel_op_is_address_4_, Column::precomputed_sel_op_is_address_5_,
257 Column::precomputed_sel_op_is_address_6_,
258 };
259
260 for (const auto& [exec_opcode, exec_instruction_spec] : EXEC_INSTRUCTION_SPEC) {
261 // Basic information.
262 trace.set(static_cast<uint32_t>(exec_opcode),
263 { {
264 { C::precomputed_sel_exec_spec, 1 },
265 { C::precomputed_exec_opcode_opcode_gas, exec_instruction_spec.gas_cost.opcode_gas },
266 { C::precomputed_exec_opcode_base_da_gas, exec_instruction_spec.gas_cost.base_da },
267 { C::precomputed_exec_opcode_dynamic_l2_gas, exec_instruction_spec.gas_cost.dyn_l2 },
268 { C::precomputed_exec_opcode_dynamic_da_gas, exec_instruction_spec.gas_cost.dyn_da },
269 } });
270
271 // Register information.
272 const auto& register_info = EXEC_INSTRUCTION_SPEC.at(exec_opcode).register_info;
273 for (size_t i = 0; i < AVM_MAX_REGISTERS; i++) {
274 trace.set(MEM_OP_REG_COLUMNS.at(i), static_cast<uint32_t>(exec_opcode), register_info.is_active(i) ? 1 : 0);
275 trace.set(RW_COLUMNS.at(i), static_cast<uint32_t>(exec_opcode), register_info.is_write(i) ? 1 : 0);
276 trace.set(DO_TAG_CHECK_COLUMNS.at(i),
277 static_cast<uint32_t>(exec_opcode),
278 register_info.need_tag_check(i) ? 1 : 0);
279 trace.set(EXPECTED_TAG_COLUMNS.at(i),
280 static_cast<uint32_t>(exec_opcode),
281 static_cast<uint32_t>(register_info.expected_tag(i).value_or(static_cast<ValueTag>(0))));
282 }
283
284 // Whether an operand is an address
285 for (size_t i = 0; i < AVM_MAX_OPERANDS; i++) {
286 trace.set(SEL_OP_IS_ADDRESS_COLUMNS.at(i),
287 static_cast<uint32_t>(exec_opcode),
288 i < exec_instruction_spec.num_addresses ? 1 : 0);
289 }
290
291 // Gadget / Subtrace Selectors / Decomposable selectors
292 auto dispatch_to_subtrace = SUBTRACE_INFO_MAP.at(exec_opcode);
293 trace.set(static_cast<uint32_t>(exec_opcode),
294 { { { C::precomputed_subtrace_id, get_subtrace_id(dispatch_to_subtrace.subtrace_selector) },
295 { C::precomputed_subtrace_operation_id, dispatch_to_subtrace.subtrace_operation_id },
296 { C::precomputed_dyn_gas_id, exec_instruction_spec.dyn_gas_id } } });
297 }
298}
299
301{
302 using C = Column;
303
304 const auto& p_limbs_per_radix = get_p_limbs_per_radix();
305
306 trace.reserve_column(C::precomputed_sel_to_radix_p_limb_counts, p_limbs_per_radix.size());
307 trace.reserve_column(C::precomputed_to_radix_safe_limbs, p_limbs_per_radix.size());
308
309 for (size_t i = 0; i < p_limbs_per_radix.size(); ++i) {
310 size_t decomposition_len = p_limbs_per_radix[i].size();
311 if (decomposition_len > 0) {
312 trace.set(C::precomputed_sel_to_radix_p_limb_counts, static_cast<uint32_t>(i), 1);
313 trace.set(C::precomputed_to_radix_safe_limbs, static_cast<uint32_t>(i), decomposition_len - 1);
314 trace.set(C::precomputed_to_radix_num_limbs_for_p, static_cast<uint32_t>(i), decomposition_len);
315 }
316 }
317}
318
320{
321 using C = Column;
322
323 const auto& p_limbs_per_radix = get_p_limbs_per_radix();
324
325 uint32_t row = 0;
326 for (size_t i = 0; i < p_limbs_per_radix.size(); ++i) {
327 size_t decomposition_len = p_limbs_per_radix[i].size();
328 for (size_t j = 0; j < decomposition_len; ++j) {
329 trace.set(C::precomputed_sel_p_decomposition, row, 1);
330 trace.set(C::precomputed_p_decomposition_radix, row, i);
331 trace.set(C::precomputed_p_decomposition_limb_index, row, j);
332 trace.set(C::precomputed_p_decomposition_limb, row, p_limbs_per_radix[i][j]);
333 row++;
334 }
335 }
336}
337
339{
340 using C = Column;
341
342 constexpr uint32_t num_rows = 1 << 8; // 256
343
344 for (uint32_t i = static_cast<uint32_t>(MemoryTag::MAX) + 1; i < num_rows; i++) {
345 trace.set(C::precomputed_sel_mem_tag_out_of_range, i, 1);
346 }
347}
348
350{
351 using C = Column;
352
353 constexpr uint32_t num_rows = 1 << 16; // 65536
354 trace.reserve_column(C::precomputed_sel_addressing_gas, num_rows);
355 trace.reserve_column(C::precomputed_addressing_gas, num_rows);
356
357 for (uint32_t i = 0; i < num_rows; i++) {
358 trace.set(C::precomputed_sel_addressing_gas, i, 1);
359 trace.set(C::precomputed_addressing_gas, i, compute_addressing_gas(static_cast<uint16_t>(i)));
360 }
361}
362
364{
365 using C = Column;
366
367 // Non Revertible Nullifiers
369 trace.set(0,
370 {
371 {
372 { C::precomputed_sel_phase, 1 },
373 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::NR_NULLIFIER_INSERTION) },
374 { C::precomputed_sel_non_revertible_append_nullifier, 1 },
375
376 { C::precomputed_read_public_input_offset, nr_nullifiers.read_pi_offset },
377 { C::precomputed_read_public_input_length_offset, nr_nullifiers.read_pi_length_offset },
378 { C::precomputed_sel_can_emit_nullifier, 1 },
379 },
380 });
381 // Non Revertible Note Hash
383 trace.set(1,
384 {
385 {
386 { C::precomputed_sel_phase, 1 },
387 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::NR_NOTE_INSERTION) },
388 { C::precomputed_sel_non_revertible_append_note_hash, 1 },
389
390 { C::precomputed_read_public_input_offset, nr_note_hash.read_pi_offset },
391 { C::precomputed_read_public_input_length_offset, nr_note_hash.read_pi_length_offset },
392 { C::precomputed_sel_can_emit_note_hash, 1 },
393 },
394 });
395 // Non Revertible L2 to L1 Messages
397 trace.set(2,
398 {
399 {
400 { C::precomputed_sel_phase, 1 },
401 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::NR_L2_TO_L1_MESSAGE) },
402 { C::precomputed_sel_non_revertible_append_l2_l1_msg, 1 },
403
404 { C::precomputed_read_public_input_offset, nr_l2_to_l1_msgs.read_pi_offset },
405 { C::precomputed_read_public_input_length_offset, nr_l2_to_l1_msgs.read_pi_length_offset },
406 { C::precomputed_sel_can_emit_l2_l1_msg, 1 },
407 },
408 });
409 // Setup
411 trace.set(3,
412 {
413 {
414 { C::precomputed_sel_phase, 1 },
415 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::SETUP) },
416 { C::precomputed_is_public_call_request_phase, 1 },
417
418 { C::precomputed_read_public_input_offset, setup.read_pi_offset },
419 { C::precomputed_read_public_input_length_offset, setup.read_pi_length_offset },
420 { C::precomputed_sel_can_emit_note_hash, 1 },
421 { C::precomputed_sel_can_emit_nullifier, 1 },
422 { C::precomputed_sel_can_write_public_data, 1 },
423 { C::precomputed_sel_can_emit_unencrypted_log, 1 },
424 { C::precomputed_sel_can_emit_l2_l1_msg, 1 },
425 },
426 });
427 // Revertible Nullifiers
429 trace.set(4,
430 {
431 {
432 { C::precomputed_sel_phase, 1 },
433 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::R_NULLIFIER_INSERTION) },
434 { C::precomputed_sel_revertible_append_nullifier, 1 },
435 { C::precomputed_is_revertible, 1 },
436 { C::precomputed_next_phase_on_revert, static_cast<uint8_t>(TransactionPhase::TEARDOWN) },
437
438 { C::precomputed_read_public_input_offset, r_nullifiers.read_pi_offset },
439 { C::precomputed_read_public_input_length_offset, r_nullifiers.read_pi_length_offset },
440 { C::precomputed_sel_can_emit_nullifier, 1 },
441 },
442 });
443 // Revertible Note Hash
445 trace.set(5,
446 {
447 {
448 { C::precomputed_sel_phase, 1 },
449 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::R_NOTE_INSERTION) },
450 { C::precomputed_sel_revertible_append_note_hash, 1 },
451 { C::precomputed_is_revertible, 1 },
452 { C::precomputed_next_phase_on_revert, static_cast<uint8_t>(TransactionPhase::TEARDOWN) },
453
454 { C::precomputed_read_public_input_offset, r_note_hash.read_pi_offset },
455 { C::precomputed_read_public_input_length_offset, r_note_hash.read_pi_length_offset },
456 { C::precomputed_sel_can_emit_note_hash, 1 },
457 },
458 });
459 // Revertible L2 to L1 Messages
461 trace.set(6,
462 {
463 {
464 { C::precomputed_sel_phase, 1 },
465 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::R_L2_TO_L1_MESSAGE) },
466 { C::precomputed_sel_revertible_append_l2_l1_msg, 1 },
467 { C::precomputed_is_revertible, 1 },
468 { C::precomputed_next_phase_on_revert, static_cast<uint8_t>(TransactionPhase::TEARDOWN) },
469
470 { C::precomputed_read_public_input_offset, r_l2_to_l1_msgs.read_pi_offset },
471 { C::precomputed_read_public_input_length_offset, r_l2_to_l1_msgs.read_pi_length_offset },
472 { C::precomputed_sel_can_emit_l2_l1_msg, 1 },
473 },
474 });
475 // App Logic
477 trace.set(7,
478 {
479 {
480 { C::precomputed_sel_phase, 1 },
481 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::APP_LOGIC) },
482 { C::precomputed_is_public_call_request_phase, 1 },
483 { C::precomputed_is_revertible, 1 },
484 { C::precomputed_next_phase_on_revert, static_cast<uint8_t>(TransactionPhase::TEARDOWN) },
485
486 { C::precomputed_read_public_input_offset, app_logic.read_pi_offset },
487 { C::precomputed_read_public_input_length_offset, app_logic.read_pi_length_offset },
488 { C::precomputed_sel_can_emit_note_hash, 1 },
489 { C::precomputed_sel_can_emit_nullifier, 1 },
490 { C::precomputed_sel_can_write_public_data, 1 },
491 { C::precomputed_sel_can_emit_unencrypted_log, 1 },
492 { C::precomputed_sel_can_emit_l2_l1_msg, 1 },
493 },
494 });
495 // Teardown
497 trace.set(8,
498 {
499 {
500 { C::precomputed_sel_phase, 1 },
501 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::TEARDOWN) },
502 { C::precomputed_is_public_call_request_phase, 1 },
503 { C::precomputed_is_revertible, 1 },
504 { C::precomputed_next_phase_on_revert, static_cast<uint8_t>(TransactionPhase::COLLECT_GAS_FEES) },
505
506 { C::precomputed_read_public_input_offset, teardown.read_pi_offset },
507 { C::precomputed_read_public_input_length_offset, teardown.read_pi_length_offset },
508 { C::precomputed_sel_can_emit_note_hash, 1 },
509 { C::precomputed_sel_can_emit_nullifier, 1 },
510 { C::precomputed_sel_can_write_public_data, 1 },
511 { C::precomputed_sel_can_emit_unencrypted_log, 1 },
512 { C::precomputed_sel_can_emit_l2_l1_msg, 1 },
513 },
514 });
515 // TODO: Complete Collect Gas Fee and Pad Tree phases
517 trace.set(9,
518 {
519 {
520 { C::precomputed_sel_phase, 1 },
521 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::COLLECT_GAS_FEES) },
522 { C::precomputed_sel_collect_fee, 1 },
523 { C::precomputed_is_revertible, 0 },
524
525 { C::precomputed_read_public_input_offset, pay_gas.read_pi_offset },
526 { C::precomputed_read_public_input_length_offset, pay_gas.read_pi_length_offset },
527 { C::precomputed_sel_can_write_public_data, 1 },
528 },
529 });
530
531 trace.set(10,
532 {
533 {
534 { C::precomputed_sel_phase, 1 },
535 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::TREE_PADDING) },
536 { C::precomputed_sel_tree_padding, 1 },
537 { C::precomputed_is_revertible, 0 },
538 { C::precomputed_sel_can_emit_note_hash, 1 },
539 { C::precomputed_sel_can_emit_nullifier, 1 },
540 },
541 });
542
543 trace.set(11,
544 {
545 {
546 { C::precomputed_sel_phase, 1 },
547 { C::precomputed_phase_value, static_cast<uint8_t>(TransactionPhase::CLEANUP) },
548 { C::precomputed_sel_cleanup, 1 },
549 { C::precomputed_is_revertible, 0 },
550 },
551 });
552}
553
555{
556 using C = Column;
557
558 uint32_t row = 1;
559 for (const auto& round_constant : simulation::keccak_round_constants) {
560 trace.set(row,
561 { {
562 { C::precomputed_sel_keccak, 1 },
563 { C::precomputed_keccak_round_constant, round_constant },
564 } });
565 row++;
566 }
567}
568
573{
574 using C = Column;
575
576 constexpr uint32_t NUM_ROWS = 1 << 8;
577
578 // Start by flagging `invalid_envvar_enum` as 1 for all rows.
579 // "valid" rows will be reset manually to 0 below.
580 for (uint32_t i = 0; i < NUM_ROWS; i++) {
581 trace.set(C::precomputed_invalid_envvar_enum, i, 1);
582 }
583
584 for (uint8_t enum_value = 0; enum_value <= static_cast<uint8_t>(EnvironmentVariable::MAX); enum_value++) {
585 const auto& envvar_spec = GetEnvVarSpec::get_table(enum_value);
586 trace.set(static_cast<uint32_t>(enum_value),
587 { {
588 { C::precomputed_invalid_envvar_enum, 0 }, // Reset the invalid enum flag for valid rows
589 { C::precomputed_sel_envvar_pi_lookup_col0, envvar_spec.envvar_pi_lookup_col0 },
590 { C::precomputed_sel_envvar_pi_lookup_col1, envvar_spec.envvar_pi_lookup_col1 },
591 { C::precomputed_envvar_pi_row_idx, envvar_spec.envvar_pi_row_idx },
592 { C::precomputed_is_address, envvar_spec.is_address ? 1 : 0 },
593 { C::precomputed_is_sender, envvar_spec.is_sender ? 1 : 0 },
594 { C::precomputed_is_transactionfee, envvar_spec.is_transactionfee ? 1 : 0 },
595 { C::precomputed_is_isstaticcall, envvar_spec.is_isstaticcall ? 1 : 0 },
596 { C::precomputed_is_l2gasleft, envvar_spec.is_l2gasleft ? 1 : 0 },
597 { C::precomputed_is_dagasleft, envvar_spec.is_dagasleft ? 1 : 0 },
598 { C::precomputed_out_tag, envvar_spec.out_tag },
599 } });
600 }
601}
602
607{
608 using C = Column;
609
610 // Set valid rows based on the precomputed table
611 for (uint8_t enum_value = 0; enum_value <= static_cast<uint8_t>(ContractInstanceMember::MAX); enum_value++) {
612 const auto& spec = GetContractInstanceSpec::get_table(enum_value);
613
614 trace.set(static_cast<uint32_t>(enum_value),
615 { {
616 { C::precomputed_is_valid_member_enum, spec.is_valid_member_enum ? 1 : 0 },
617 { C::precomputed_is_deployer, spec.is_deployer ? 1 : 0 },
618 { C::precomputed_is_class_id, spec.is_class_id ? 1 : 0 },
619 { C::precomputed_is_init_hash, spec.is_init_hash ? 1 : 0 },
620 } });
621 }
622}
623
624} // namespace bb::avm2::tracegen
#define AVM_MAX_OPERANDS
#define AVM_MAX_REGISTERS
static Table get_table(uint8_t envvar)
void process_sha256_round_constants(TraceContainer &trace)
void process_to_radix_p_decompositions(TraceContainer &trace)
void process_wire_instruction_spec(TraceContainer &trace)
void process_keccak_round_constants(TraceContainer &trace)
void process_to_radix_safe_limbs(TraceContainer &trace)
void process_memory_tag_range(TraceContainer &trace)
void process_exec_instruction_spec(TraceContainer &trace)
void process_misc(TraceContainer &trace, const uint32_t num_rows=MAX_AVM_TRACE_SIZE)
void process_get_env_var_table(TraceContainer &trace)
void process_get_contract_instance_table(TraceContainer &trace)
static const Offsets & get_offsets(TransactionPhase phase)
TestTraceContainer trace
FF a
FF b
constexpr std::array< uint64_t, 24 > keccak_round_constants
constexpr uint32_t round_constants[64]
const std::unordered_map< ExecutionOpCode, SubtraceInfo > SUBTRACE_INFO_MAP
FF get_subtrace_id(SubtraceSel subtrace_sel)
Get the subtrace ID for a given subtrace enum.
const std::array< std::vector< uint8_t >, 257 > & get_p_limbs_per_radix()
Definition to_radix.cpp:48
@ NR_NOTE_INSERTION
@ R_NULLIFIER_INSERTION
@ NR_L2_TO_L1_MESSAGE
@ R_L2_TO_L1_MESSAGE
@ NR_NULLIFIER_INSERTION
uint32_t compute_addressing_gas(uint16_t indirect_flag)
Definition gas.cpp:10
uint8_t get_tag_bits(ValueTag tag)
uint256_t get_tag_max_value(ValueTag tag)
constexpr size_t NUM_OP_DC_SELECTORS
const std::unordered_map< WireOpCode, WireInstructionSpec > WIRE_INSTRUCTION_SPEC
AvmFlavorSettings::FF FF
Definition field.hpp:10
const std::unordered_map< ExecutionOpCode, ExecInstructionSpec > EXEC_INSTRUCTION_SPEC
uint8_t get_tag_bytes(ValueTag tag)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13