43 std::vector<FF> next_packed_pc_min_pc_inverses = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
44 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 };
50 for (
const auto&
event : events) {
51 const auto&
bytecode = *
event.bytecode;
52 const auto id =
event.bytecode_id;
54 const uint32_t bytecode_len =
static_cast<uint32_t
>(
bytecode.size());
56 for (uint32_t i = 0; i < bytecode_len; i++) {
57 const uint32_t remaining = bytecode_len - i;
59 const bool is_last = remaining == 1;
68 { C::bc_decomposition_sel, 1 },
69 { C::bc_decomposition_id,
id },
70 { C::bc_decomposition_pc, i },
71 { C::bc_decomposition_start, i == 0 ? 1 : 0 },
72 { C::bc_decomposition_last_of_contract, is_last ? 1 : 0 },
73 { C::bc_decomposition_bytes_remaining, remaining },
74 { C::bc_decomposition_bytes_to_read, bytes_to_read },
76 { C::bc_decomposition_sel_windows_eq_remaining, is_windows_eq_remaining ? 1 : 0 },
78 { C::bc_decomposition_bytes_rem_inv, remaining },
79 { C::bc_decomposition_bytes_rem_min_one_inv, is_last ? 0 :
FF(remaining - 1) },
80 { C::bc_decomposition_windows_min_remaining_inv,
83 { C::bc_decomposition_bytes, bytecode_at(i) },
84 { C::bc_decomposition_bytes_pc_plus_1, bytecode_at(i + 1) },
85 { C::bc_decomposition_bytes_pc_plus_2, bytecode_at(i + 2) },
86 { C::bc_decomposition_bytes_pc_plus_3, bytecode_at(i + 3) },
87 { C::bc_decomposition_bytes_pc_plus_4, bytecode_at(i + 4) },
88 { C::bc_decomposition_bytes_pc_plus_5, bytecode_at(i + 5) },
89 { C::bc_decomposition_bytes_pc_plus_6, bytecode_at(i + 6) },
90 { C::bc_decomposition_bytes_pc_plus_7, bytecode_at(i + 7) },
91 { C::bc_decomposition_bytes_pc_plus_8, bytecode_at(i + 8) },
92 { C::bc_decomposition_bytes_pc_plus_9, bytecode_at(i + 9) },
93 { C::bc_decomposition_bytes_pc_plus_10, bytecode_at(i + 10) },
94 { C::bc_decomposition_bytes_pc_plus_11, bytecode_at(i + 11) },
95 { C::bc_decomposition_bytes_pc_plus_12, bytecode_at(i + 12) },
96 { C::bc_decomposition_bytes_pc_plus_13, bytecode_at(i + 13) },
97 { C::bc_decomposition_bytes_pc_plus_14, bytecode_at(i + 14) },
98 { C::bc_decomposition_bytes_pc_plus_15, bytecode_at(i + 15) },
99 { C::bc_decomposition_bytes_pc_plus_16, bytecode_at(i + 16) },
100 { C::bc_decomposition_bytes_pc_plus_17, bytecode_at(i + 17) },
101 { C::bc_decomposition_bytes_pc_plus_18, bytecode_at(i + 18) },
102 { C::bc_decomposition_bytes_pc_plus_19, bytecode_at(i + 19) },
103 { C::bc_decomposition_bytes_pc_plus_20, bytecode_at(i + 20) },
104 { C::bc_decomposition_bytes_pc_plus_21, bytecode_at(i + 21) },
105 { C::bc_decomposition_bytes_pc_plus_22, bytecode_at(i + 22) },
106 { C::bc_decomposition_bytes_pc_plus_23, bytecode_at(i + 23) },
107 { C::bc_decomposition_bytes_pc_plus_24, bytecode_at(i + 24) },
108 { C::bc_decomposition_bytes_pc_plus_25, bytecode_at(i + 25) },
109 { C::bc_decomposition_bytes_pc_plus_26, bytecode_at(i + 26) },
110 { C::bc_decomposition_bytes_pc_plus_27, bytecode_at(i + 27) },
111 { C::bc_decomposition_bytes_pc_plus_28, bytecode_at(i + 28) },
112 { C::bc_decomposition_bytes_pc_plus_29, bytecode_at(i + 29) },
113 { C::bc_decomposition_bytes_pc_plus_30, bytecode_at(i + 30) },
114 { C::bc_decomposition_bytes_pc_plus_31, bytecode_at(i + 31) },
115 { C::bc_decomposition_bytes_pc_plus_32, bytecode_at(i + 32) },
116 { C::bc_decomposition_bytes_pc_plus_33, bytecode_at(i + 33) },
117 { C::bc_decomposition_bytes_pc_plus_34, bytecode_at(i + 34) },
118 { C::bc_decomposition_bytes_pc_plus_35, bytecode_at(i + 35) },
119 { C::bc_decomposition_bytes_pc_plus_36, bytecode_at(i + 36) },
124 auto bytecode_field_at = [&](
size_t i) ->
FF {
127 if (bytecode_len - i >= 32) {
130 as_int = from_buffer<uint256_t>(
bytecode, i);
133 std::vector<uint8_t> tail(
bytecode.begin() +
static_cast<ssize_t
>(i),
bytecode.end());
135 as_int = from_buffer<uint256_t>(tail, 0);
140 for (uint32_t i = 0; i < bytecode_len; i += 31) {
145 { C::bc_decomposition_sel_packed, 1 },
146 { C::bc_decomposition_packed_field, bytecode_field_at(i) },
147 { C::bc_decomposition_next_packed_pc, i },
148 { C::bc_decomposition_next_packed_pc_min_pc_inv, 0 },
152 for (uint32_t j = i + 1; j < std::min(bytecode_len, i + 31); j++) {
156 { C::bc_decomposition_next_packed_pc, i + 31 },
157 { C::bc_decomposition_next_packed_pc_min_pc_inv, next_packed_pc_min_pc_inverses[i + 31 - j] },
167 trace.invert_columns({ { C::bc_decomposition_bytes_rem_inv,
168 C::bc_decomposition_bytes_rem_min_one_inv,
169 C::bc_decomposition_windows_min_remaining_inv } });
178 for (
const auto&
event : events) {
179 const auto id =
event.bytecode_id;
182 fields.reserve(1 +
event.bytecode_fields.size());
183 fields.insert(fields.end(),
event.bytecode_fields.begin(),
event.bytecode_fields.end());
184 auto bytecode_field_at = [&fields](
size_t i) ->
FF {
return i < fields.size() ? fields[i] : 0; };
186 auto padding_amount = (3 - (fields.size() % 3)) % 3;
187 auto num_rounds = (fields.size() + padding_amount) / 3;
188 uint32_t pc_index = 0;
189 for (uint32_t i = 0; i < fields.size(); i += 3) {
190 bool start_of_bytecode = i == 0;
191 bool end_of_bytecode = i + 3 >= fields.size();
194 uint32_t pc_index_1 = start_of_bytecode ? 0 : pc_index + 31;
196 { { { C::bc_hashing_sel, 1 },
197 { C::bc_hashing_start, start_of_bytecode },
198 { C::bc_hashing_sel_not_start, !start_of_bytecode },
199 { C::bc_hashing_latch, end_of_bytecode },
200 { C::bc_hashing_bytecode_id,
id },
201 { C::bc_hashing_size_in_bytes,
202 event.bytecode_length },
203 { C::bc_hashing_input_len, fields.size() },
204 { C::bc_hashing_rounds_rem, num_rounds },
205 { C::bc_hashing_pc_index, pc_index },
206 { C::bc_hashing_pc_index_1, pc_index_1 },
207 { C::bc_hashing_pc_index_2, pc_index_1 + 31 },
208 { C::bc_hashing_packed_fields_0, bytecode_field_at(i) },
209 { C::bc_hashing_packed_fields_1, bytecode_field_at(i + 1) },
210 { C::bc_hashing_packed_fields_2, bytecode_field_at(i + 2) },
211 { C::bc_hashing_sel_not_padding_1, end_of_bytecode && padding_amount == 2 ? 0 : 1 },
212 { C::bc_hashing_sel_not_padding_2, end_of_bytecode && padding_amount > 0 ? 0 : 1 },
213 { C::bc_hashing_output_hash, output_hash } } });
214 if (end_of_bytecode) {
218 FF pc_at_final_field =
224 : pc_index_1 + (31 * (1 - padding_amount));
227 { C::bc_hashing_pc_at_final_field, pc_at_final_field },
230 pc_index = pc_index_1 + 62;
257 for (
const auto&
event : events) {
262 event.retrieved_bytecodes_snapshot_before.next_available_leaf_index;
263 bool error =
event.error.has_value();
266 "TOO_MANY_BYTECODES error incorrectly set for bytecode retrieval");
271 { C::bc_retrieval_sel, 1 },
272 { C::bc_retrieval_bytecode_id,
event.bytecode_id },
273 { C::bc_retrieval_address,
event.address },
276 { C::bc_retrieval_current_class_id,
event.current_class_id },
279 { C::bc_retrieval_artifact_hash,
event.contract_class.artifact_hash },
280 { C::bc_retrieval_private_functions_root,
event.contract_class.private_functions_root },
283 { C::bc_retrieval_public_data_tree_root,
event.public_data_tree_root },
284 { C::bc_retrieval_nullifier_tree_root,
event.nullifier_root },
288 { C::bc_retrieval_prev_retrieved_bytecodes_tree_root,
event.retrieved_bytecodes_snapshot_before.root },
289 { C::bc_retrieval_prev_retrieved_bytecodes_tree_size,
290 event.retrieved_bytecodes_snapshot_before.next_available_leaf_index },
291 { C::bc_retrieval_next_retrieved_bytecodes_tree_root,
event.retrieved_bytecodes_snapshot_after.root },
292 { C::bc_retrieval_next_retrieved_bytecodes_tree_size,
293 event.retrieved_bytecodes_snapshot_after.next_available_leaf_index },
296 { C::bc_retrieval_instance_exists,
300 { C::bc_retrieval_error, error ? 1 : 0 },
301 { C::bc_retrieval_is_new_class,
event.is_new_class },
302 { C::bc_retrieval_should_retrieve, error ? 0 : 1 },
304 { C::bc_retrieval_no_remaining_bytecodes, remaining_bytecodes == 0 ? 1 : 0 },
305 { C::bc_retrieval_remaining_bytecodes_inv, remaining_bytecodes },
311 trace.invert_columns({ { C::bc_retrieval_remaining_bytecodes_inv } });
328 for (
const auto&
event : events) {
330 const auto bytecode_size =
event.bytecode->size();
335 auto get_operand = [&](
size_t i) ->
FF {
336 return i <
event.instruction.operands.size() && !parsing_error_non_tag
337 ?
static_cast<FF>(
event.instruction.operands[i])
340 auto bytecode_at = [&](
size_t i) -> uint8_t {
return i < bytecode_size ? (*
event.bytecode)[i] : 0; };
342 const uint8_t wire_opcode = bytecode_at(
event.pc);
343 const bool wire_opcode_in_range =
346 uint32_t size_in_bytes = 0;
348 std::array<uint8_t, NUM_OP_DC_SELECTORS> op_dc_selectors{};
350 uint8_t tag_is_op2 = 0;
351 uint8_t tag_value = 0;
353 if (wire_opcode_in_range) {
355 size_in_bytes = wire_instr_spec.size_in_bytes;
356 exec_opcode = wire_instr_spec.exec_opcode;
357 op_dc_selectors = wire_instr_spec.op_dc_selectors;
359 if (wire_instr_spec.tag_operand_idx.has_value()) {
360 const auto tag_value_idx = wire_instr_spec.tag_operand_idx.value();
361 BB_ASSERT((tag_value_idx == 2 || tag_value_idx == 3),
362 "Current constraints support only tag for operand index equal to 2 or 3");
365 if (tag_value_idx == 2) {
367 tag_value =
static_cast<uint8_t
>(get_operand(1));
369 tag_value =
static_cast<uint8_t
>(get_operand(2));
374 const uint32_t bytes_remaining =
375 event.error ==
PC_OUT_OF_RANGE ? 0 :
static_cast<uint32_t
>(bytecode_size -
event.pc);
378 uint32_t instr_abs_diff = 0;
379 if (size_in_bytes <= bytes_to_read) {
380 instr_abs_diff = bytes_to_read - size_in_bytes;
382 instr_abs_diff = size_in_bytes - bytes_to_read - 1;
385 uint32_t bytecode_size_u32 =
static_cast<uint32_t
>(bytecode_size);
386 uint32_t pc_abs_diff =
387 bytecode_size_u32 >
event.pc ? bytecode_size_u32 -
event.pc - 1 :
event.pc - bytecode_size_u32;
391 { C::instr_fetching_sel, 1 },
392 { C::instr_fetching_bytecode_id, bytecode_id },
393 { C::instr_fetching_pc,
event.pc },
395 { C::instr_fetching_addressing_mode,
event.instruction.addressing_mode },
396 { C::instr_fetching_op1, get_operand(0) },
397 { C::instr_fetching_op2, get_operand(1) },
398 { C::instr_fetching_op3, get_operand(2) },
399 { C::instr_fetching_op4, get_operand(3) },
400 { C::instr_fetching_op5, get_operand(4) },
401 { C::instr_fetching_op6, get_operand(5) },
402 { C::instr_fetching_op7, get_operand(6) },
404 { C::instr_fetching_bd0, wire_opcode },
405 { C::instr_fetching_bd1, bytecode_at(
event.pc + 1) },
406 { C::instr_fetching_bd2, bytecode_at(
event.pc + 2) },
407 { C::instr_fetching_bd3, bytecode_at(
event.pc + 3) },
408 { C::instr_fetching_bd4, bytecode_at(
event.pc + 4) },
409 { C::instr_fetching_bd5, bytecode_at(
event.pc + 5) },
410 { C::instr_fetching_bd6, bytecode_at(
event.pc + 6) },
411 { C::instr_fetching_bd7, bytecode_at(
event.pc + 7) },
412 { C::instr_fetching_bd8, bytecode_at(
event.pc + 8) },
413 { C::instr_fetching_bd9, bytecode_at(
event.pc + 9) },
414 { C::instr_fetching_bd10, bytecode_at(
event.pc + 10) },
415 { C::instr_fetching_bd11, bytecode_at(
event.pc + 11) },
416 { C::instr_fetching_bd12, bytecode_at(
event.pc + 12) },
417 { C::instr_fetching_bd13, bytecode_at(
event.pc + 13) },
418 { C::instr_fetching_bd14, bytecode_at(
event.pc + 14) },
419 { C::instr_fetching_bd15, bytecode_at(
event.pc + 15) },
420 { C::instr_fetching_bd16, bytecode_at(
event.pc + 16) },
421 { C::instr_fetching_bd17, bytecode_at(
event.pc + 17) },
422 { C::instr_fetching_bd18, bytecode_at(
event.pc + 18) },
423 { C::instr_fetching_bd19, bytecode_at(
event.pc + 19) },
424 { C::instr_fetching_bd20, bytecode_at(
event.pc + 20) },
425 { C::instr_fetching_bd21, bytecode_at(
event.pc + 21) },
426 { C::instr_fetching_bd22, bytecode_at(
event.pc + 22) },
427 { C::instr_fetching_bd23, bytecode_at(
event.pc + 23) },
428 { C::instr_fetching_bd24, bytecode_at(
event.pc + 24) },
429 { C::instr_fetching_bd25, bytecode_at(
event.pc + 25) },
430 { C::instr_fetching_bd26, bytecode_at(
event.pc + 26) },
431 { C::instr_fetching_bd27, bytecode_at(
event.pc + 27) },
432 { C::instr_fetching_bd28, bytecode_at(
event.pc + 28) },
433 { C::instr_fetching_bd29, bytecode_at(
event.pc + 29) },
434 { C::instr_fetching_bd30, bytecode_at(
event.pc + 30) },
435 { C::instr_fetching_bd31, bytecode_at(
event.pc + 31) },
436 { C::instr_fetching_bd32, bytecode_at(
event.pc + 32) },
437 { C::instr_fetching_bd33, bytecode_at(
event.pc + 33) },
438 { C::instr_fetching_bd34, bytecode_at(
event.pc + 34) },
439 { C::instr_fetching_bd35, bytecode_at(
event.pc + 35) },
440 { C::instr_fetching_bd36, bytecode_at(
event.pc + 36) },
443 { C::instr_fetching_exec_opcode,
static_cast<uint32_t
>(exec_opcode) },
444 { C::instr_fetching_instr_size, size_in_bytes },
445 { C::instr_fetching_sel_has_tag, has_tag },
446 { C::instr_fetching_sel_tag_is_op2, tag_is_op2 },
449 { C::instr_fetching_sel_op_dc_0, op_dc_selectors.at(0) },
450 { C::instr_fetching_sel_op_dc_1, op_dc_selectors.at(1) },
451 { C::instr_fetching_sel_op_dc_2, op_dc_selectors.at(2) },
452 { C::instr_fetching_sel_op_dc_3, op_dc_selectors.at(3) },
453 { C::instr_fetching_sel_op_dc_4, op_dc_selectors.at(4) },
454 { C::instr_fetching_sel_op_dc_5, op_dc_selectors.at(5) },
455 { C::instr_fetching_sel_op_dc_6, op_dc_selectors.at(6) },
456 { C::instr_fetching_sel_op_dc_7, op_dc_selectors.at(7) },
457 { C::instr_fetching_sel_op_dc_8, op_dc_selectors.at(8) },
458 { C::instr_fetching_sel_op_dc_9, op_dc_selectors.at(9) },
459 { C::instr_fetching_sel_op_dc_10, op_dc_selectors.at(10) },
460 { C::instr_fetching_sel_op_dc_11, op_dc_selectors.at(11) },
461 { C::instr_fetching_sel_op_dc_12, op_dc_selectors.at(12) },
462 { C::instr_fetching_sel_op_dc_13, op_dc_selectors.at(13) },
463 { C::instr_fetching_sel_op_dc_14, op_dc_selectors.at(14) },
464 { C::instr_fetching_sel_op_dc_15, op_dc_selectors.at(15) },
465 { C::instr_fetching_sel_op_dc_16, op_dc_selectors.at(16) },
468 { C::instr_fetching_pc_out_of_range,
event.error ==
PC_OUT_OF_RANGE ? 1 : 0 },
471 { C::instr_fetching_tag_out_of_range,
event.error ==
TAG_OUT_OF_RANGE ? 1 : 0 },
472 { C::instr_fetching_sel_parsing_err,
event.error.has_value() ? 1 : 0 },
475 { C::instr_fetching_sel_pc_in_range,
event.error !=
PC_OUT_OF_RANGE ? 1 : 0 },
477 { C::instr_fetching_bytecode_size, bytecode_size },
478 { C::instr_fetching_bytes_to_read, bytes_to_read },
479 { C::instr_fetching_instr_abs_diff, instr_abs_diff },
480 { C::instr_fetching_pc_abs_diff, pc_abs_diff },
481 { C::instr_fetching_pc_size_in_bits,
483 { C::instr_fetching_tag_value, tag_value },