diff --git a/barretenberg/cpp/pil/avm/kernel.pil b/barretenberg/cpp/pil/avm/kernel.pil index 3b6594c297b..03da4e3d1f7 100644 --- a/barretenberg/cpp/pil/avm/kernel.pil +++ b/barretenberg/cpp/pil/avm/kernel.pil @@ -183,7 +183,7 @@ namespace main(256); + sel_op_emit_nullifier + sel_op_l1_to_l2_msg_exists + sel_op_emit_unencrypted_log + sel_op_emit_l2_to_l1_msg + sel_op_sload + sel_op_sstore; #[KERNEL_OUTPUT_ACTIVE_CHECK] - KERNEL_OUTPUT_SELECTORS * (1 - sel_q_kernel_output_lookup) = 0; + KERNEL_OUTPUT_SELECTORS * (1 - sel_q_kernel_output_lookup) * (1 - op_err) = 0; // TODO(#8287): Reintroduce constraints #[KERNEL_OUTPUT_LOOKUP] diff --git a/barretenberg/cpp/pil/avm/main.pil b/barretenberg/cpp/pil/avm/main.pil index 5242f3db0da..7317de68c91 100644 --- a/barretenberg/cpp/pil/avm/main.pil +++ b/barretenberg/cpp/pil/avm/main.pil @@ -85,6 +85,9 @@ namespace main(256); // TODO: Opcode value (byte) will be constrained by the bytecode validation circuit pol commit opcode_val; + //===== MISC ====================================================== + pol commit sel_op_debug_log; + //===== Gadget Selectors ====================================================== pol commit sel_op_radix_be; pol commit sel_op_sha256; @@ -246,6 +249,8 @@ namespace main(256); sel_op_sload * (1 - sel_op_sload) = 0; sel_op_sstore * (1 - sel_op_sstore) = 0; + sel_op_debug_log * (1 - sel_op_debug_log) = 0; + sel_op_radix_be * (1 - sel_op_radix_be) = 0; sel_op_sha256 * (1 - sel_op_sha256) = 0; sel_op_poseidon2 * (1 - sel_op_poseidon2) = 0; @@ -351,13 +356,16 @@ namespace main(256); #[SUBOP_FDIV_W_IN_TAG_FF] sel_op_fdiv * (w_in_tag - constants.MEM_TAG_FF) = 0; - // op_err cannot be maliciously activated for a non-relevant + // TODO: op_err cannot be maliciously activated for a non-relevant // operation selector, i.e., op_err == 1 ==> sel_op_fdiv || sel_op_XXX || ... // op_err * (sel_op_fdiv + sel_op_XXX + ... - 1) == 0 // Note that the above is even a stronger constraint, as it shows // that exactly one sel_op_XXX must be true. - #[SUBOP_ERROR_RELEVANT_OP] - op_err * ((sel_op_fdiv + sel_op_div + sel_op_get_contract_instance) - 1) = 0; + // #[SUBOP_ERROR_RELEVANT_OP] + // op_err * (1 - tag_err) * ((sel_op_fdiv + sel_op_div + sel_op_get_contract_instance) - 1) = 0; + + #[TAG_ERR_IMPLIES_OP_ERR] + tag_err * (1 - op_err) = 0; // TODO: constraint that we stop execution at the first error (tag_err or op_err) // An error can only happen at the last sub-operation row. @@ -426,7 +434,7 @@ namespace main(256); + sel_op_ecadd + sel_op_msm; pol SEL_ALL_MEMORY = sel_op_mov + sel_op_set; pol OPCODE_SELECTORS = sel_op_fdiv + sel_op_calldata_copy + sel_op_get_contract_instance - + sel_op_returndata_size + sel_op_returndata_copy + + sel_op_returndata_size + sel_op_returndata_copy + sel_op_debug_log + SEL_ALL_ALU + SEL_ALL_BINARY + SEL_ALL_MEMORY + SEL_ALL_GADGET + KERNEL_INPUT_SELECTORS + KERNEL_OUTPUT_SELECTORS + SEL_ALL_LEFTGAS + SEL_ALL_CTRL_FLOW; @@ -486,9 +494,9 @@ namespace main(256); #[MOV_MAIN_SAME_TAG] sel_op_mov * (r_in_tag - w_in_tag) = 0; - // Predicate to activate the copy of intermediate registers to ALU table. If tag_err == 1, - // the operation is not copied to the ALU table. - sel_alu = SEL_ALL_ALU * (1 - tag_err) * (1 - op_err); + // Predicate to activate the copy of intermediate registers to ALU table. If op_err == 1, + // the operation is not copied to the ALU table. Note that it encompasses tag_err == 1. + sel_alu = SEL_ALL_ALU * (1 - op_err); // Dispatch the correct in_tag for alu SEL_ALU_R_TAG * (alu_in_tag - r_in_tag) = 0; @@ -506,8 +514,8 @@ namespace main(256); //===== Memory Slice Constraints ============================================ pol commit sel_slice_gadget; // Selector to activate a slice gadget operation in the gadget (#[PERM_MAIN_SLICE]). - // Activate only if tag_err is disabled or retsize (ib) is non-zero - ib * (1 - tag_err) * (sel_op_calldata_copy + sel_op_external_return - sel_slice_gadget)= 0; + // Activate only if op_err is disabled or retsize (ib) is non-zero + ib * (1 - op_err) * (sel_op_calldata_copy + sel_op_external_return - sel_slice_gadget)= 0; //====== Inter-table Constraints ============================================ @@ -537,7 +545,7 @@ namespace main(256); // sel_Bin is not explicitly constrained to be boolean, however this is enforced through // the operation decomposition step during bytecode unpacking. #[BIN_SEL_2] - sel_bin = sel_op_and + sel_op_or + sel_op_xor; + sel_bin = (sel_op_and + sel_op_or + sel_op_xor) * (1 - op_err); #[PERM_MAIN_BIN] sel_bin {clk, ia, ib, ic, bin_op_id, r_in_tag} diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp index bdb0864db5a..149a3134805 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp @@ -326,6 +326,7 @@ AvmCircuitBuilder::ProverPolynomials AvmCircuitBuilder::compute_polynomials() co polys.main_sel_op_cast.set_if_valid_index(i, rows[i].main_sel_op_cast); polys.main_sel_op_chain_id.set_if_valid_index(i, rows[i].main_sel_op_chain_id); polys.main_sel_op_dagasleft.set_if_valid_index(i, rows[i].main_sel_op_dagasleft); + polys.main_sel_op_debug_log.set_if_valid_index(i, rows[i].main_sel_op_debug_log); polys.main_sel_op_div.set_if_valid_index(i, rows[i].main_sel_op_div); polys.main_sel_op_ecadd.set_if_valid_index(i, rows[i].main_sel_op_ecadd); polys.main_sel_op_emit_l2_to_l1_msg.set_if_valid_index(i, rows[i].main_sel_op_emit_l2_to_l1_msg); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.cpp index da72bdd87da..8c8a393e69f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.cpp @@ -225,630 +225,631 @@ AvmFlavor::AllConstRefValues::AllConstRefValues( , main_sel_op_cast(il[217]) , main_sel_op_chain_id(il[218]) , main_sel_op_dagasleft(il[219]) - , main_sel_op_div(il[220]) - , main_sel_op_ecadd(il[221]) - , main_sel_op_emit_l2_to_l1_msg(il[222]) - , main_sel_op_emit_note_hash(il[223]) - , main_sel_op_emit_nullifier(il[224]) - , main_sel_op_emit_unencrypted_log(il[225]) - , main_sel_op_eq(il[226]) - , main_sel_op_external_call(il[227]) - , main_sel_op_external_return(il[228]) - , main_sel_op_external_revert(il[229]) - , main_sel_op_fdiv(il[230]) - , main_sel_op_fee_per_da_gas(il[231]) - , main_sel_op_fee_per_l2_gas(il[232]) - , main_sel_op_function_selector(il[233]) - , main_sel_op_get_contract_instance(il[234]) - , main_sel_op_internal_call(il[235]) - , main_sel_op_internal_return(il[236]) - , main_sel_op_is_static_call(il[237]) - , main_sel_op_jump(il[238]) - , main_sel_op_jumpi(il[239]) - , main_sel_op_keccak(il[240]) - , main_sel_op_l1_to_l2_msg_exists(il[241]) - , main_sel_op_l2gasleft(il[242]) - , main_sel_op_lt(il[243]) - , main_sel_op_lte(il[244]) - , main_sel_op_mov(il[245]) - , main_sel_op_msm(il[246]) - , main_sel_op_mul(il[247]) - , main_sel_op_not(il[248]) - , main_sel_op_note_hash_exists(il[249]) - , main_sel_op_nullifier_exists(il[250]) - , main_sel_op_or(il[251]) - , main_sel_op_poseidon2(il[252]) - , main_sel_op_radix_be(il[253]) - , main_sel_op_returndata_copy(il[254]) - , main_sel_op_returndata_size(il[255]) - , main_sel_op_sender(il[256]) - , main_sel_op_set(il[257]) - , main_sel_op_sha256(il[258]) - , main_sel_op_shl(il[259]) - , main_sel_op_shr(il[260]) - , main_sel_op_sload(il[261]) - , main_sel_op_sstore(il[262]) - , main_sel_op_static_call(il[263]) - , main_sel_op_sub(il[264]) - , main_sel_op_timestamp(il[265]) - , main_sel_op_transaction_fee(il[266]) - , main_sel_op_version(il[267]) - , main_sel_op_xor(il[268]) - , main_sel_q_kernel_lookup(il[269]) - , main_sel_q_kernel_output_lookup(il[270]) - , main_sel_resolve_ind_addr_a(il[271]) - , main_sel_resolve_ind_addr_b(il[272]) - , main_sel_resolve_ind_addr_c(il[273]) - , main_sel_resolve_ind_addr_d(il[274]) - , main_sel_returndata(il[275]) - , main_sel_rng_16(il[276]) - , main_sel_rng_8(il[277]) - , main_sel_slice_gadget(il[278]) - , main_side_effect_counter(il[279]) - , main_sload_write_offset(il[280]) - , main_space_id(il[281]) - , main_sstore_write_offset(il[282]) - , main_tag_err(il[283]) - , main_w_in_tag(il[284]) - , mem_addr(il[285]) - , mem_clk(il[286]) - , mem_diff(il[287]) - , mem_glob_addr(il[288]) - , mem_last(il[289]) - , mem_lastAccess(il[290]) - , mem_one_min_inv(il[291]) - , mem_r_in_tag(il[292]) - , mem_rw(il[293]) - , mem_sel_mem(il[294]) - , mem_sel_mov_ia_to_ic(il[295]) - , mem_sel_mov_ib_to_ic(il[296]) - , mem_sel_op_a(il[297]) - , mem_sel_op_b(il[298]) - , mem_sel_op_c(il[299]) - , mem_sel_op_d(il[300]) - , mem_sel_op_poseidon_read_a(il[301]) - , mem_sel_op_poseidon_read_b(il[302]) - , mem_sel_op_poseidon_read_c(il[303]) - , mem_sel_op_poseidon_read_d(il[304]) - , mem_sel_op_poseidon_write_a(il[305]) - , mem_sel_op_poseidon_write_b(il[306]) - , mem_sel_op_poseidon_write_c(il[307]) - , mem_sel_op_poseidon_write_d(il[308]) - , mem_sel_op_slice(il[309]) - , mem_sel_resolve_ind_addr_a(il[310]) - , mem_sel_resolve_ind_addr_b(il[311]) - , mem_sel_resolve_ind_addr_c(il[312]) - , mem_sel_resolve_ind_addr_d(il[313]) - , mem_sel_rng_chk(il[314]) - , mem_skip_check_tag(il[315]) - , mem_space_id(il[316]) - , mem_tag(il[317]) - , mem_tag_err(il[318]) - , mem_tsp(il[319]) - , mem_u16_r0(il[320]) - , mem_u16_r1(il[321]) - , mem_u8_r0(il[322]) - , mem_val(il[323]) - , mem_w_in_tag(il[324]) - , merkle_tree_clk(il[325]) - , merkle_tree_expected_tree_root(il[326]) - , merkle_tree_latch(il[327]) - , merkle_tree_leaf_index(il[328]) - , merkle_tree_leaf_index_is_even(il[329]) - , merkle_tree_leaf_value(il[330]) - , merkle_tree_left_hash(il[331]) - , merkle_tree_output_hash(il[332]) - , merkle_tree_path_len(il[333]) - , merkle_tree_path_len_inv(il[334]) - , merkle_tree_right_hash(il[335]) - , merkle_tree_sel_merkle_tree(il[336]) - , merkle_tree_sibling_value(il[337]) - , poseidon2_B_10_0(il[338]) - , poseidon2_B_10_1(il[339]) - , poseidon2_B_10_2(il[340]) - , poseidon2_B_10_3(il[341]) - , poseidon2_B_11_0(il[342]) - , poseidon2_B_11_1(il[343]) - , poseidon2_B_11_2(il[344]) - , poseidon2_B_11_3(il[345]) - , poseidon2_B_12_0(il[346]) - , poseidon2_B_12_1(il[347]) - , poseidon2_B_12_2(il[348]) - , poseidon2_B_12_3(il[349]) - , poseidon2_B_13_0(il[350]) - , poseidon2_B_13_1(il[351]) - , poseidon2_B_13_2(il[352]) - , poseidon2_B_13_3(il[353]) - , poseidon2_B_14_0(il[354]) - , poseidon2_B_14_1(il[355]) - , poseidon2_B_14_2(il[356]) - , poseidon2_B_14_3(il[357]) - , poseidon2_B_15_0(il[358]) - , poseidon2_B_15_1(il[359]) - , poseidon2_B_15_2(il[360]) - , poseidon2_B_15_3(il[361]) - , poseidon2_B_16_0(il[362]) - , poseidon2_B_16_1(il[363]) - , poseidon2_B_16_2(il[364]) - , poseidon2_B_16_3(il[365]) - , poseidon2_B_17_0(il[366]) - , poseidon2_B_17_1(il[367]) - , poseidon2_B_17_2(il[368]) - , poseidon2_B_17_3(il[369]) - , poseidon2_B_18_0(il[370]) - , poseidon2_B_18_1(il[371]) - , poseidon2_B_18_2(il[372]) - , poseidon2_B_18_3(il[373]) - , poseidon2_B_19_0(il[374]) - , poseidon2_B_19_1(il[375]) - , poseidon2_B_19_2(il[376]) - , poseidon2_B_19_3(il[377]) - , poseidon2_B_20_0(il[378]) - , poseidon2_B_20_1(il[379]) - , poseidon2_B_20_2(il[380]) - , poseidon2_B_20_3(il[381]) - , poseidon2_B_21_0(il[382]) - , poseidon2_B_21_1(il[383]) - , poseidon2_B_21_2(il[384]) - , poseidon2_B_21_3(il[385]) - , poseidon2_B_22_0(il[386]) - , poseidon2_B_22_1(il[387]) - , poseidon2_B_22_2(il[388]) - , poseidon2_B_22_3(il[389]) - , poseidon2_B_23_0(il[390]) - , poseidon2_B_23_1(il[391]) - , poseidon2_B_23_2(il[392]) - , poseidon2_B_23_3(il[393]) - , poseidon2_B_24_0(il[394]) - , poseidon2_B_24_1(il[395]) - , poseidon2_B_24_2(il[396]) - , poseidon2_B_24_3(il[397]) - , poseidon2_B_25_0(il[398]) - , poseidon2_B_25_1(il[399]) - , poseidon2_B_25_2(il[400]) - , poseidon2_B_25_3(il[401]) - , poseidon2_B_26_0(il[402]) - , poseidon2_B_26_1(il[403]) - , poseidon2_B_26_2(il[404]) - , poseidon2_B_26_3(il[405]) - , poseidon2_B_27_0(il[406]) - , poseidon2_B_27_1(il[407]) - , poseidon2_B_27_2(il[408]) - , poseidon2_B_27_3(il[409]) - , poseidon2_B_28_0(il[410]) - , poseidon2_B_28_1(il[411]) - , poseidon2_B_28_2(il[412]) - , poseidon2_B_28_3(il[413]) - , poseidon2_B_29_0(il[414]) - , poseidon2_B_29_1(il[415]) - , poseidon2_B_29_2(il[416]) - , poseidon2_B_29_3(il[417]) - , poseidon2_B_30_0(il[418]) - , poseidon2_B_30_1(il[419]) - , poseidon2_B_30_2(il[420]) - , poseidon2_B_30_3(il[421]) - , poseidon2_B_31_0(il[422]) - , poseidon2_B_31_1(il[423]) - , poseidon2_B_31_2(il[424]) - , poseidon2_B_31_3(il[425]) - , poseidon2_B_32_0(il[426]) - , poseidon2_B_32_1(il[427]) - , poseidon2_B_32_2(il[428]) - , poseidon2_B_32_3(il[429]) - , poseidon2_B_33_0(il[430]) - , poseidon2_B_33_1(il[431]) - , poseidon2_B_33_2(il[432]) - , poseidon2_B_33_3(il[433]) - , poseidon2_B_34_0(il[434]) - , poseidon2_B_34_1(il[435]) - , poseidon2_B_34_2(il[436]) - , poseidon2_B_34_3(il[437]) - , poseidon2_B_35_0(il[438]) - , poseidon2_B_35_1(il[439]) - , poseidon2_B_35_2(il[440]) - , poseidon2_B_35_3(il[441]) - , poseidon2_B_36_0(il[442]) - , poseidon2_B_36_1(il[443]) - , poseidon2_B_36_2(il[444]) - , poseidon2_B_36_3(il[445]) - , poseidon2_B_37_0(il[446]) - , poseidon2_B_37_1(il[447]) - , poseidon2_B_37_2(il[448]) - , poseidon2_B_37_3(il[449]) - , poseidon2_B_38_0(il[450]) - , poseidon2_B_38_1(il[451]) - , poseidon2_B_38_2(il[452]) - , poseidon2_B_38_3(il[453]) - , poseidon2_B_39_0(il[454]) - , poseidon2_B_39_1(il[455]) - , poseidon2_B_39_2(il[456]) - , poseidon2_B_39_3(il[457]) - , poseidon2_B_40_0(il[458]) - , poseidon2_B_40_1(il[459]) - , poseidon2_B_40_2(il[460]) - , poseidon2_B_40_3(il[461]) - , poseidon2_B_41_0(il[462]) - , poseidon2_B_41_1(il[463]) - , poseidon2_B_41_2(il[464]) - , poseidon2_B_41_3(il[465]) - , poseidon2_B_42_0(il[466]) - , poseidon2_B_42_1(il[467]) - , poseidon2_B_42_2(il[468]) - , poseidon2_B_42_3(il[469]) - , poseidon2_B_43_0(il[470]) - , poseidon2_B_43_1(il[471]) - , poseidon2_B_43_2(il[472]) - , poseidon2_B_43_3(il[473]) - , poseidon2_B_44_0(il[474]) - , poseidon2_B_44_1(il[475]) - , poseidon2_B_44_2(il[476]) - , poseidon2_B_44_3(il[477]) - , poseidon2_B_45_0(il[478]) - , poseidon2_B_45_1(il[479]) - , poseidon2_B_45_2(il[480]) - , poseidon2_B_45_3(il[481]) - , poseidon2_B_46_0(il[482]) - , poseidon2_B_46_1(il[483]) - , poseidon2_B_46_2(il[484]) - , poseidon2_B_46_3(il[485]) - , poseidon2_B_47_0(il[486]) - , poseidon2_B_47_1(il[487]) - , poseidon2_B_47_2(il[488]) - , poseidon2_B_47_3(il[489]) - , poseidon2_B_48_0(il[490]) - , poseidon2_B_48_1(il[491]) - , poseidon2_B_48_2(il[492]) - , poseidon2_B_48_3(il[493]) - , poseidon2_B_49_0(il[494]) - , poseidon2_B_49_1(il[495]) - , poseidon2_B_49_2(il[496]) - , poseidon2_B_49_3(il[497]) - , poseidon2_B_4_0(il[498]) - , poseidon2_B_4_1(il[499]) - , poseidon2_B_4_2(il[500]) - , poseidon2_B_4_3(il[501]) - , poseidon2_B_50_0(il[502]) - , poseidon2_B_50_1(il[503]) - , poseidon2_B_50_2(il[504]) - , poseidon2_B_50_3(il[505]) - , poseidon2_B_51_0(il[506]) - , poseidon2_B_51_1(il[507]) - , poseidon2_B_51_2(il[508]) - , poseidon2_B_51_3(il[509]) - , poseidon2_B_52_0(il[510]) - , poseidon2_B_52_1(il[511]) - , poseidon2_B_52_2(il[512]) - , poseidon2_B_52_3(il[513]) - , poseidon2_B_53_0(il[514]) - , poseidon2_B_53_1(il[515]) - , poseidon2_B_53_2(il[516]) - , poseidon2_B_53_3(il[517]) - , poseidon2_B_54_0(il[518]) - , poseidon2_B_54_1(il[519]) - , poseidon2_B_54_2(il[520]) - , poseidon2_B_54_3(il[521]) - , poseidon2_B_55_0(il[522]) - , poseidon2_B_55_1(il[523]) - , poseidon2_B_55_2(il[524]) - , poseidon2_B_55_3(il[525]) - , poseidon2_B_56_0(il[526]) - , poseidon2_B_56_1(il[527]) - , poseidon2_B_56_2(il[528]) - , poseidon2_B_56_3(il[529]) - , poseidon2_B_57_0(il[530]) - , poseidon2_B_57_1(il[531]) - , poseidon2_B_57_2(il[532]) - , poseidon2_B_57_3(il[533]) - , poseidon2_B_58_0(il[534]) - , poseidon2_B_58_1(il[535]) - , poseidon2_B_58_2(il[536]) - , poseidon2_B_58_3(il[537]) - , poseidon2_B_59_0(il[538]) - , poseidon2_B_59_1(il[539]) - , poseidon2_B_59_2(il[540]) - , poseidon2_B_59_3(il[541]) - , poseidon2_B_5_0(il[542]) - , poseidon2_B_5_1(il[543]) - , poseidon2_B_5_2(il[544]) - , poseidon2_B_5_3(il[545]) - , poseidon2_B_6_0(il[546]) - , poseidon2_B_6_1(il[547]) - , poseidon2_B_6_2(il[548]) - , poseidon2_B_6_3(il[549]) - , poseidon2_B_7_0(il[550]) - , poseidon2_B_7_1(il[551]) - , poseidon2_B_7_2(il[552]) - , poseidon2_B_7_3(il[553]) - , poseidon2_B_8_0(il[554]) - , poseidon2_B_8_1(il[555]) - , poseidon2_B_8_2(il[556]) - , poseidon2_B_8_3(il[557]) - , poseidon2_B_9_0(il[558]) - , poseidon2_B_9_1(il[559]) - , poseidon2_B_9_2(il[560]) - , poseidon2_B_9_3(il[561]) - , poseidon2_EXT_LAYER_4(il[562]) - , poseidon2_EXT_LAYER_5(il[563]) - , poseidon2_EXT_LAYER_6(il[564]) - , poseidon2_EXT_LAYER_7(il[565]) - , poseidon2_T_0_4(il[566]) - , poseidon2_T_0_5(il[567]) - , poseidon2_T_0_6(il[568]) - , poseidon2_T_0_7(il[569]) - , poseidon2_T_1_4(il[570]) - , poseidon2_T_1_5(il[571]) - , poseidon2_T_1_6(il[572]) - , poseidon2_T_1_7(il[573]) - , poseidon2_T_2_4(il[574]) - , poseidon2_T_2_5(il[575]) - , poseidon2_T_2_6(il[576]) - , poseidon2_T_2_7(il[577]) - , poseidon2_T_3_4(il[578]) - , poseidon2_T_3_5(il[579]) - , poseidon2_T_3_6(il[580]) - , poseidon2_T_3_7(il[581]) - , poseidon2_T_60_4(il[582]) - , poseidon2_T_60_5(il[583]) - , poseidon2_T_60_6(il[584]) - , poseidon2_T_60_7(il[585]) - , poseidon2_T_61_4(il[586]) - , poseidon2_T_61_5(il[587]) - , poseidon2_T_61_6(il[588]) - , poseidon2_T_61_7(il[589]) - , poseidon2_T_62_4(il[590]) - , poseidon2_T_62_5(il[591]) - , poseidon2_T_62_6(il[592]) - , poseidon2_T_62_7(il[593]) - , poseidon2_T_63_4(il[594]) - , poseidon2_T_63_5(il[595]) - , poseidon2_T_63_6(il[596]) - , poseidon2_T_63_7(il[597]) - , poseidon2_a_0(il[598]) - , poseidon2_a_1(il[599]) - , poseidon2_a_2(il[600]) - , poseidon2_a_3(il[601]) - , poseidon2_b_0(il[602]) - , poseidon2_b_1(il[603]) - , poseidon2_b_2(il[604]) - , poseidon2_b_3(il[605]) - , poseidon2_clk(il[606]) - , poseidon2_full_a_0(il[607]) - , poseidon2_full_a_1(il[608]) - , poseidon2_full_a_2(il[609]) - , poseidon2_full_a_3(il[610]) - , poseidon2_full_b_0(il[611]) - , poseidon2_full_b_1(il[612]) - , poseidon2_full_b_2(il[613]) - , poseidon2_full_b_3(il[614]) - , poseidon2_full_clk(il[615]) - , poseidon2_full_end_poseidon(il[616]) - , poseidon2_full_execute_poseidon_perm(il[617]) - , poseidon2_full_input_0(il[618]) - , poseidon2_full_input_1(il[619]) - , poseidon2_full_input_2(il[620]) - , poseidon2_full_input_len(il[621]) - , poseidon2_full_num_perm_rounds_rem(il[622]) - , poseidon2_full_num_perm_rounds_rem_inv(il[623]) - , poseidon2_full_output(il[624]) - , poseidon2_full_padding(il[625]) - , poseidon2_full_sel_merkle_tree(il[626]) - , poseidon2_full_sel_poseidon(il[627]) - , poseidon2_full_start_poseidon(il[628]) - , poseidon2_input_addr(il[629]) - , poseidon2_mem_addr_read_a(il[630]) - , poseidon2_mem_addr_read_b(il[631]) - , poseidon2_mem_addr_read_c(il[632]) - , poseidon2_mem_addr_read_d(il[633]) - , poseidon2_mem_addr_write_a(il[634]) - , poseidon2_mem_addr_write_b(il[635]) - , poseidon2_mem_addr_write_c(il[636]) - , poseidon2_mem_addr_write_d(il[637]) - , poseidon2_output_addr(il[638]) - , poseidon2_sel_poseidon_perm(il[639]) - , poseidon2_sel_poseidon_perm_immediate(il[640]) - , poseidon2_sel_poseidon_perm_mem_op(il[641]) - , poseidon2_space_id(il[642]) - , range_check_alu_rng_chk(il[643]) - , range_check_clk(il[644]) - , range_check_cmp_hi_bits_rng_chk(il[645]) - , range_check_cmp_lo_bits_rng_chk(il[646]) - , range_check_dyn_diff(il[647]) - , range_check_dyn_rng_chk_bits(il[648]) - , range_check_dyn_rng_chk_pow_2(il[649]) - , range_check_gas_da_rng_chk(il[650]) - , range_check_gas_l2_rng_chk(il[651]) - , range_check_is_lte_u112(il[652]) - , range_check_is_lte_u128(il[653]) - , range_check_is_lte_u16(il[654]) - , range_check_is_lte_u32(il[655]) - , range_check_is_lte_u48(il[656]) - , range_check_is_lte_u64(il[657]) - , range_check_is_lte_u80(il[658]) - , range_check_is_lte_u96(il[659]) - , range_check_rng_chk_bits(il[660]) - , range_check_sel_lookup_0(il[661]) - , range_check_sel_lookup_1(il[662]) - , range_check_sel_lookup_2(il[663]) - , range_check_sel_lookup_3(il[664]) - , range_check_sel_lookup_4(il[665]) - , range_check_sel_lookup_5(il[666]) - , range_check_sel_lookup_6(il[667]) - , range_check_sel_rng_chk(il[668]) - , range_check_u16_r0(il[669]) - , range_check_u16_r1(il[670]) - , range_check_u16_r2(il[671]) - , range_check_u16_r3(il[672]) - , range_check_u16_r4(il[673]) - , range_check_u16_r5(il[674]) - , range_check_u16_r6(il[675]) - , range_check_u16_r7(il[676]) - , range_check_value(il[677]) - , sha256_clk(il[678]) - , sha256_input(il[679]) - , sha256_output(il[680]) - , sha256_sel_sha256_compression(il[681]) - , sha256_state(il[682]) - , slice_addr(il[683]) - , slice_clk(il[684]) - , slice_cnt(il[685]) - , slice_col_offset(il[686]) - , slice_one_min_inv(il[687]) - , slice_sel_cd_cpy(il[688]) - , slice_sel_mem_active(il[689]) - , slice_sel_return(il[690]) - , slice_sel_start(il[691]) - , slice_space_id(il[692]) - , slice_val(il[693]) - , lookup_rng_chk_pow_2_counts(il[694]) - , lookup_rng_chk_diff_counts(il[695]) - , lookup_rng_chk_0_counts(il[696]) - , lookup_rng_chk_1_counts(il[697]) - , lookup_rng_chk_2_counts(il[698]) - , lookup_rng_chk_3_counts(il[699]) - , lookup_rng_chk_4_counts(il[700]) - , lookup_rng_chk_5_counts(il[701]) - , lookup_rng_chk_6_counts(il[702]) - , lookup_rng_chk_7_counts(il[703]) - , lookup_mem_rng_chk_0_counts(il[704]) - , lookup_mem_rng_chk_1_counts(il[705]) - , lookup_mem_rng_chk_2_counts(il[706]) - , lookup_pow_2_0_counts(il[707]) - , lookup_pow_2_1_counts(il[708]) - , lookup_byte_lengths_counts(il[709]) - , lookup_byte_operations_counts(il[710]) - , lookup_opcode_gas_counts(il[711]) - , lookup_l2_gas_rng_chk_0_counts(il[712]) - , lookup_l2_gas_rng_chk_1_counts(il[713]) - , lookup_da_gas_rng_chk_0_counts(il[714]) - , lookup_da_gas_rng_chk_1_counts(il[715]) - , kernel_output_lookup_counts(il[716]) - , lookup_into_kernel_counts(il[717]) - , lookup_cd_value_counts(il[718]) - , lookup_ret_value_counts(il[719]) - , incl_main_tag_err_counts(il[720]) - , incl_mem_tag_err_counts(il[721]) - , perm_rng_cmp_lo_inv(il[722]) - , perm_rng_cmp_hi_inv(il[723]) - , perm_rng_alu_inv(il[724]) - , perm_cmp_alu_inv(il[725]) - , perm_l2_start_gas_inv(il[726]) - , perm_da_start_gas_inv(il[727]) - , perm_l2_end_gas_inv(il[728]) - , perm_da_end_gas_inv(il[729]) - , perm_pos_mem_read_a_inv(il[730]) - , perm_pos_mem_read_b_inv(il[731]) - , perm_pos_mem_read_c_inv(il[732]) - , perm_pos_mem_read_d_inv(il[733]) - , perm_pos_mem_write_a_inv(il[734]) - , perm_pos_mem_write_b_inv(il[735]) - , perm_pos_mem_write_c_inv(il[736]) - , perm_pos_mem_write_d_inv(il[737]) - , perm_pos2_fixed_pos2_perm_inv(il[738]) - , perm_slice_mem_inv(il[739]) - , perm_merkle_poseidon2_inv(il[740]) - , perm_main_alu_inv(il[741]) - , perm_main_bin_inv(il[742]) - , perm_main_conv_inv(il[743]) - , perm_main_sha256_inv(il[744]) - , perm_main_pos2_perm_inv(il[745]) - , perm_main_slice_inv(il[746]) - , perm_main_mem_a_inv(il[747]) - , perm_main_mem_b_inv(il[748]) - , perm_main_mem_c_inv(il[749]) - , perm_main_mem_d_inv(il[750]) - , perm_main_mem_ind_addr_a_inv(il[751]) - , perm_main_mem_ind_addr_b_inv(il[752]) - , perm_main_mem_ind_addr_c_inv(il[753]) - , perm_main_mem_ind_addr_d_inv(il[754]) - , lookup_rng_chk_pow_2_inv(il[755]) - , lookup_rng_chk_diff_inv(il[756]) - , lookup_rng_chk_0_inv(il[757]) - , lookup_rng_chk_1_inv(il[758]) - , lookup_rng_chk_2_inv(il[759]) - , lookup_rng_chk_3_inv(il[760]) - , lookup_rng_chk_4_inv(il[761]) - , lookup_rng_chk_5_inv(il[762]) - , lookup_rng_chk_6_inv(il[763]) - , lookup_rng_chk_7_inv(il[764]) - , lookup_mem_rng_chk_0_inv(il[765]) - , lookup_mem_rng_chk_1_inv(il[766]) - , lookup_mem_rng_chk_2_inv(il[767]) - , lookup_pow_2_0_inv(il[768]) - , lookup_pow_2_1_inv(il[769]) - , lookup_byte_lengths_inv(il[770]) - , lookup_byte_operations_inv(il[771]) - , lookup_opcode_gas_inv(il[772]) - , lookup_l2_gas_rng_chk_0_inv(il[773]) - , lookup_l2_gas_rng_chk_1_inv(il[774]) - , lookup_da_gas_rng_chk_0_inv(il[775]) - , lookup_da_gas_rng_chk_1_inv(il[776]) - , kernel_output_lookup_inv(il[777]) - , lookup_into_kernel_inv(il[778]) - , lookup_cd_value_inv(il[779]) - , lookup_ret_value_inv(il[780]) - , incl_main_tag_err_inv(il[781]) - , incl_mem_tag_err_inv(il[782]) - , binary_acc_ia_shift(il[783]) - , binary_acc_ib_shift(il[784]) - , binary_acc_ic_shift(il[785]) - , binary_mem_tag_ctr_shift(il[786]) - , binary_op_id_shift(il[787]) - , cmp_a_hi_shift(il[788]) - , cmp_a_lo_shift(il[789]) - , cmp_b_hi_shift(il[790]) - , cmp_b_lo_shift(il[791]) - , cmp_cmp_rng_ctr_shift(il[792]) - , cmp_op_gt_shift(il[793]) - , cmp_p_sub_a_hi_shift(il[794]) - , cmp_p_sub_a_lo_shift(il[795]) - , cmp_p_sub_b_hi_shift(il[796]) - , cmp_p_sub_b_lo_shift(il[797]) - , cmp_sel_rng_chk_shift(il[798]) - , main_da_gas_remaining_shift(il[799]) - , main_emit_l2_to_l1_msg_write_offset_shift(il[800]) - , main_emit_note_hash_write_offset_shift(il[801]) - , main_emit_nullifier_write_offset_shift(il[802]) - , main_emit_unencrypted_log_write_offset_shift(il[803]) - , main_internal_return_ptr_shift(il[804]) - , main_l1_to_l2_msg_exists_write_offset_shift(il[805]) - , main_l2_gas_remaining_shift(il[806]) - , main_note_hash_exist_write_offset_shift(il[807]) - , main_nullifier_exists_write_offset_shift(il[808]) - , main_nullifier_non_exists_write_offset_shift(il[809]) - , main_pc_shift(il[810]) - , main_sel_execution_end_shift(il[811]) - , main_sel_execution_row_shift(il[812]) - , main_sload_write_offset_shift(il[813]) - , main_sstore_write_offset_shift(il[814]) - , mem_glob_addr_shift(il[815]) - , mem_rw_shift(il[816]) - , mem_sel_mem_shift(il[817]) - , mem_tag_shift(il[818]) - , mem_tsp_shift(il[819]) - , mem_val_shift(il[820]) - , merkle_tree_leaf_index_shift(il[821]) - , merkle_tree_leaf_value_shift(il[822]) - , merkle_tree_path_len_shift(il[823]) - , poseidon2_full_a_0_shift(il[824]) - , poseidon2_full_a_1_shift(il[825]) - , poseidon2_full_a_2_shift(il[826]) - , poseidon2_full_a_3_shift(il[827]) - , poseidon2_full_execute_poseidon_perm_shift(il[828]) - , poseidon2_full_input_0_shift(il[829]) - , poseidon2_full_input_1_shift(il[830]) - , poseidon2_full_input_2_shift(il[831]) - , poseidon2_full_num_perm_rounds_rem_shift(il[832]) - , poseidon2_full_sel_poseidon_shift(il[833]) - , poseidon2_full_start_poseidon_shift(il[834]) - , slice_addr_shift(il[835]) - , slice_clk_shift(il[836]) - , slice_cnt_shift(il[837]) - , slice_col_offset_shift(il[838]) - , slice_sel_cd_cpy_shift(il[839]) - , slice_sel_mem_active_shift(il[840]) - , slice_sel_return_shift(il[841]) - , slice_sel_start_shift(il[842]) - , slice_space_id_shift(il[843]) + , main_sel_op_debug_log(il[220]) + , main_sel_op_div(il[221]) + , main_sel_op_ecadd(il[222]) + , main_sel_op_emit_l2_to_l1_msg(il[223]) + , main_sel_op_emit_note_hash(il[224]) + , main_sel_op_emit_nullifier(il[225]) + , main_sel_op_emit_unencrypted_log(il[226]) + , main_sel_op_eq(il[227]) + , main_sel_op_external_call(il[228]) + , main_sel_op_external_return(il[229]) + , main_sel_op_external_revert(il[230]) + , main_sel_op_fdiv(il[231]) + , main_sel_op_fee_per_da_gas(il[232]) + , main_sel_op_fee_per_l2_gas(il[233]) + , main_sel_op_function_selector(il[234]) + , main_sel_op_get_contract_instance(il[235]) + , main_sel_op_internal_call(il[236]) + , main_sel_op_internal_return(il[237]) + , main_sel_op_is_static_call(il[238]) + , main_sel_op_jump(il[239]) + , main_sel_op_jumpi(il[240]) + , main_sel_op_keccak(il[241]) + , main_sel_op_l1_to_l2_msg_exists(il[242]) + , main_sel_op_l2gasleft(il[243]) + , main_sel_op_lt(il[244]) + , main_sel_op_lte(il[245]) + , main_sel_op_mov(il[246]) + , main_sel_op_msm(il[247]) + , main_sel_op_mul(il[248]) + , main_sel_op_not(il[249]) + , main_sel_op_note_hash_exists(il[250]) + , main_sel_op_nullifier_exists(il[251]) + , main_sel_op_or(il[252]) + , main_sel_op_poseidon2(il[253]) + , main_sel_op_radix_be(il[254]) + , main_sel_op_returndata_copy(il[255]) + , main_sel_op_returndata_size(il[256]) + , main_sel_op_sender(il[257]) + , main_sel_op_set(il[258]) + , main_sel_op_sha256(il[259]) + , main_sel_op_shl(il[260]) + , main_sel_op_shr(il[261]) + , main_sel_op_sload(il[262]) + , main_sel_op_sstore(il[263]) + , main_sel_op_static_call(il[264]) + , main_sel_op_sub(il[265]) + , main_sel_op_timestamp(il[266]) + , main_sel_op_transaction_fee(il[267]) + , main_sel_op_version(il[268]) + , main_sel_op_xor(il[269]) + , main_sel_q_kernel_lookup(il[270]) + , main_sel_q_kernel_output_lookup(il[271]) + , main_sel_resolve_ind_addr_a(il[272]) + , main_sel_resolve_ind_addr_b(il[273]) + , main_sel_resolve_ind_addr_c(il[274]) + , main_sel_resolve_ind_addr_d(il[275]) + , main_sel_returndata(il[276]) + , main_sel_rng_16(il[277]) + , main_sel_rng_8(il[278]) + , main_sel_slice_gadget(il[279]) + , main_side_effect_counter(il[280]) + , main_sload_write_offset(il[281]) + , main_space_id(il[282]) + , main_sstore_write_offset(il[283]) + , main_tag_err(il[284]) + , main_w_in_tag(il[285]) + , mem_addr(il[286]) + , mem_clk(il[287]) + , mem_diff(il[288]) + , mem_glob_addr(il[289]) + , mem_last(il[290]) + , mem_lastAccess(il[291]) + , mem_one_min_inv(il[292]) + , mem_r_in_tag(il[293]) + , mem_rw(il[294]) + , mem_sel_mem(il[295]) + , mem_sel_mov_ia_to_ic(il[296]) + , mem_sel_mov_ib_to_ic(il[297]) + , mem_sel_op_a(il[298]) + , mem_sel_op_b(il[299]) + , mem_sel_op_c(il[300]) + , mem_sel_op_d(il[301]) + , mem_sel_op_poseidon_read_a(il[302]) + , mem_sel_op_poseidon_read_b(il[303]) + , mem_sel_op_poseidon_read_c(il[304]) + , mem_sel_op_poseidon_read_d(il[305]) + , mem_sel_op_poseidon_write_a(il[306]) + , mem_sel_op_poseidon_write_b(il[307]) + , mem_sel_op_poseidon_write_c(il[308]) + , mem_sel_op_poseidon_write_d(il[309]) + , mem_sel_op_slice(il[310]) + , mem_sel_resolve_ind_addr_a(il[311]) + , mem_sel_resolve_ind_addr_b(il[312]) + , mem_sel_resolve_ind_addr_c(il[313]) + , mem_sel_resolve_ind_addr_d(il[314]) + , mem_sel_rng_chk(il[315]) + , mem_skip_check_tag(il[316]) + , mem_space_id(il[317]) + , mem_tag(il[318]) + , mem_tag_err(il[319]) + , mem_tsp(il[320]) + , mem_u16_r0(il[321]) + , mem_u16_r1(il[322]) + , mem_u8_r0(il[323]) + , mem_val(il[324]) + , mem_w_in_tag(il[325]) + , merkle_tree_clk(il[326]) + , merkle_tree_expected_tree_root(il[327]) + , merkle_tree_latch(il[328]) + , merkle_tree_leaf_index(il[329]) + , merkle_tree_leaf_index_is_even(il[330]) + , merkle_tree_leaf_value(il[331]) + , merkle_tree_left_hash(il[332]) + , merkle_tree_output_hash(il[333]) + , merkle_tree_path_len(il[334]) + , merkle_tree_path_len_inv(il[335]) + , merkle_tree_right_hash(il[336]) + , merkle_tree_sel_merkle_tree(il[337]) + , merkle_tree_sibling_value(il[338]) + , poseidon2_B_10_0(il[339]) + , poseidon2_B_10_1(il[340]) + , poseidon2_B_10_2(il[341]) + , poseidon2_B_10_3(il[342]) + , poseidon2_B_11_0(il[343]) + , poseidon2_B_11_1(il[344]) + , poseidon2_B_11_2(il[345]) + , poseidon2_B_11_3(il[346]) + , poseidon2_B_12_0(il[347]) + , poseidon2_B_12_1(il[348]) + , poseidon2_B_12_2(il[349]) + , poseidon2_B_12_3(il[350]) + , poseidon2_B_13_0(il[351]) + , poseidon2_B_13_1(il[352]) + , poseidon2_B_13_2(il[353]) + , poseidon2_B_13_3(il[354]) + , poseidon2_B_14_0(il[355]) + , poseidon2_B_14_1(il[356]) + , poseidon2_B_14_2(il[357]) + , poseidon2_B_14_3(il[358]) + , poseidon2_B_15_0(il[359]) + , poseidon2_B_15_1(il[360]) + , poseidon2_B_15_2(il[361]) + , poseidon2_B_15_3(il[362]) + , poseidon2_B_16_0(il[363]) + , poseidon2_B_16_1(il[364]) + , poseidon2_B_16_2(il[365]) + , poseidon2_B_16_3(il[366]) + , poseidon2_B_17_0(il[367]) + , poseidon2_B_17_1(il[368]) + , poseidon2_B_17_2(il[369]) + , poseidon2_B_17_3(il[370]) + , poseidon2_B_18_0(il[371]) + , poseidon2_B_18_1(il[372]) + , poseidon2_B_18_2(il[373]) + , poseidon2_B_18_3(il[374]) + , poseidon2_B_19_0(il[375]) + , poseidon2_B_19_1(il[376]) + , poseidon2_B_19_2(il[377]) + , poseidon2_B_19_3(il[378]) + , poseidon2_B_20_0(il[379]) + , poseidon2_B_20_1(il[380]) + , poseidon2_B_20_2(il[381]) + , poseidon2_B_20_3(il[382]) + , poseidon2_B_21_0(il[383]) + , poseidon2_B_21_1(il[384]) + , poseidon2_B_21_2(il[385]) + , poseidon2_B_21_3(il[386]) + , poseidon2_B_22_0(il[387]) + , poseidon2_B_22_1(il[388]) + , poseidon2_B_22_2(il[389]) + , poseidon2_B_22_3(il[390]) + , poseidon2_B_23_0(il[391]) + , poseidon2_B_23_1(il[392]) + , poseidon2_B_23_2(il[393]) + , poseidon2_B_23_3(il[394]) + , poseidon2_B_24_0(il[395]) + , poseidon2_B_24_1(il[396]) + , poseidon2_B_24_2(il[397]) + , poseidon2_B_24_3(il[398]) + , poseidon2_B_25_0(il[399]) + , poseidon2_B_25_1(il[400]) + , poseidon2_B_25_2(il[401]) + , poseidon2_B_25_3(il[402]) + , poseidon2_B_26_0(il[403]) + , poseidon2_B_26_1(il[404]) + , poseidon2_B_26_2(il[405]) + , poseidon2_B_26_3(il[406]) + , poseidon2_B_27_0(il[407]) + , poseidon2_B_27_1(il[408]) + , poseidon2_B_27_2(il[409]) + , poseidon2_B_27_3(il[410]) + , poseidon2_B_28_0(il[411]) + , poseidon2_B_28_1(il[412]) + , poseidon2_B_28_2(il[413]) + , poseidon2_B_28_3(il[414]) + , poseidon2_B_29_0(il[415]) + , poseidon2_B_29_1(il[416]) + , poseidon2_B_29_2(il[417]) + , poseidon2_B_29_3(il[418]) + , poseidon2_B_30_0(il[419]) + , poseidon2_B_30_1(il[420]) + , poseidon2_B_30_2(il[421]) + , poseidon2_B_30_3(il[422]) + , poseidon2_B_31_0(il[423]) + , poseidon2_B_31_1(il[424]) + , poseidon2_B_31_2(il[425]) + , poseidon2_B_31_3(il[426]) + , poseidon2_B_32_0(il[427]) + , poseidon2_B_32_1(il[428]) + , poseidon2_B_32_2(il[429]) + , poseidon2_B_32_3(il[430]) + , poseidon2_B_33_0(il[431]) + , poseidon2_B_33_1(il[432]) + , poseidon2_B_33_2(il[433]) + , poseidon2_B_33_3(il[434]) + , poseidon2_B_34_0(il[435]) + , poseidon2_B_34_1(il[436]) + , poseidon2_B_34_2(il[437]) + , poseidon2_B_34_3(il[438]) + , poseidon2_B_35_0(il[439]) + , poseidon2_B_35_1(il[440]) + , poseidon2_B_35_2(il[441]) + , poseidon2_B_35_3(il[442]) + , poseidon2_B_36_0(il[443]) + , poseidon2_B_36_1(il[444]) + , poseidon2_B_36_2(il[445]) + , poseidon2_B_36_3(il[446]) + , poseidon2_B_37_0(il[447]) + , poseidon2_B_37_1(il[448]) + , poseidon2_B_37_2(il[449]) + , poseidon2_B_37_3(il[450]) + , poseidon2_B_38_0(il[451]) + , poseidon2_B_38_1(il[452]) + , poseidon2_B_38_2(il[453]) + , poseidon2_B_38_3(il[454]) + , poseidon2_B_39_0(il[455]) + , poseidon2_B_39_1(il[456]) + , poseidon2_B_39_2(il[457]) + , poseidon2_B_39_3(il[458]) + , poseidon2_B_40_0(il[459]) + , poseidon2_B_40_1(il[460]) + , poseidon2_B_40_2(il[461]) + , poseidon2_B_40_3(il[462]) + , poseidon2_B_41_0(il[463]) + , poseidon2_B_41_1(il[464]) + , poseidon2_B_41_2(il[465]) + , poseidon2_B_41_3(il[466]) + , poseidon2_B_42_0(il[467]) + , poseidon2_B_42_1(il[468]) + , poseidon2_B_42_2(il[469]) + , poseidon2_B_42_3(il[470]) + , poseidon2_B_43_0(il[471]) + , poseidon2_B_43_1(il[472]) + , poseidon2_B_43_2(il[473]) + , poseidon2_B_43_3(il[474]) + , poseidon2_B_44_0(il[475]) + , poseidon2_B_44_1(il[476]) + , poseidon2_B_44_2(il[477]) + , poseidon2_B_44_3(il[478]) + , poseidon2_B_45_0(il[479]) + , poseidon2_B_45_1(il[480]) + , poseidon2_B_45_2(il[481]) + , poseidon2_B_45_3(il[482]) + , poseidon2_B_46_0(il[483]) + , poseidon2_B_46_1(il[484]) + , poseidon2_B_46_2(il[485]) + , poseidon2_B_46_3(il[486]) + , poseidon2_B_47_0(il[487]) + , poseidon2_B_47_1(il[488]) + , poseidon2_B_47_2(il[489]) + , poseidon2_B_47_3(il[490]) + , poseidon2_B_48_0(il[491]) + , poseidon2_B_48_1(il[492]) + , poseidon2_B_48_2(il[493]) + , poseidon2_B_48_3(il[494]) + , poseidon2_B_49_0(il[495]) + , poseidon2_B_49_1(il[496]) + , poseidon2_B_49_2(il[497]) + , poseidon2_B_49_3(il[498]) + , poseidon2_B_4_0(il[499]) + , poseidon2_B_4_1(il[500]) + , poseidon2_B_4_2(il[501]) + , poseidon2_B_4_3(il[502]) + , poseidon2_B_50_0(il[503]) + , poseidon2_B_50_1(il[504]) + , poseidon2_B_50_2(il[505]) + , poseidon2_B_50_3(il[506]) + , poseidon2_B_51_0(il[507]) + , poseidon2_B_51_1(il[508]) + , poseidon2_B_51_2(il[509]) + , poseidon2_B_51_3(il[510]) + , poseidon2_B_52_0(il[511]) + , poseidon2_B_52_1(il[512]) + , poseidon2_B_52_2(il[513]) + , poseidon2_B_52_3(il[514]) + , poseidon2_B_53_0(il[515]) + , poseidon2_B_53_1(il[516]) + , poseidon2_B_53_2(il[517]) + , poseidon2_B_53_3(il[518]) + , poseidon2_B_54_0(il[519]) + , poseidon2_B_54_1(il[520]) + , poseidon2_B_54_2(il[521]) + , poseidon2_B_54_3(il[522]) + , poseidon2_B_55_0(il[523]) + , poseidon2_B_55_1(il[524]) + , poseidon2_B_55_2(il[525]) + , poseidon2_B_55_3(il[526]) + , poseidon2_B_56_0(il[527]) + , poseidon2_B_56_1(il[528]) + , poseidon2_B_56_2(il[529]) + , poseidon2_B_56_3(il[530]) + , poseidon2_B_57_0(il[531]) + , poseidon2_B_57_1(il[532]) + , poseidon2_B_57_2(il[533]) + , poseidon2_B_57_3(il[534]) + , poseidon2_B_58_0(il[535]) + , poseidon2_B_58_1(il[536]) + , poseidon2_B_58_2(il[537]) + , poseidon2_B_58_3(il[538]) + , poseidon2_B_59_0(il[539]) + , poseidon2_B_59_1(il[540]) + , poseidon2_B_59_2(il[541]) + , poseidon2_B_59_3(il[542]) + , poseidon2_B_5_0(il[543]) + , poseidon2_B_5_1(il[544]) + , poseidon2_B_5_2(il[545]) + , poseidon2_B_5_3(il[546]) + , poseidon2_B_6_0(il[547]) + , poseidon2_B_6_1(il[548]) + , poseidon2_B_6_2(il[549]) + , poseidon2_B_6_3(il[550]) + , poseidon2_B_7_0(il[551]) + , poseidon2_B_7_1(il[552]) + , poseidon2_B_7_2(il[553]) + , poseidon2_B_7_3(il[554]) + , poseidon2_B_8_0(il[555]) + , poseidon2_B_8_1(il[556]) + , poseidon2_B_8_2(il[557]) + , poseidon2_B_8_3(il[558]) + , poseidon2_B_9_0(il[559]) + , poseidon2_B_9_1(il[560]) + , poseidon2_B_9_2(il[561]) + , poseidon2_B_9_3(il[562]) + , poseidon2_EXT_LAYER_4(il[563]) + , poseidon2_EXT_LAYER_5(il[564]) + , poseidon2_EXT_LAYER_6(il[565]) + , poseidon2_EXT_LAYER_7(il[566]) + , poseidon2_T_0_4(il[567]) + , poseidon2_T_0_5(il[568]) + , poseidon2_T_0_6(il[569]) + , poseidon2_T_0_7(il[570]) + , poseidon2_T_1_4(il[571]) + , poseidon2_T_1_5(il[572]) + , poseidon2_T_1_6(il[573]) + , poseidon2_T_1_7(il[574]) + , poseidon2_T_2_4(il[575]) + , poseidon2_T_2_5(il[576]) + , poseidon2_T_2_6(il[577]) + , poseidon2_T_2_7(il[578]) + , poseidon2_T_3_4(il[579]) + , poseidon2_T_3_5(il[580]) + , poseidon2_T_3_6(il[581]) + , poseidon2_T_3_7(il[582]) + , poseidon2_T_60_4(il[583]) + , poseidon2_T_60_5(il[584]) + , poseidon2_T_60_6(il[585]) + , poseidon2_T_60_7(il[586]) + , poseidon2_T_61_4(il[587]) + , poseidon2_T_61_5(il[588]) + , poseidon2_T_61_6(il[589]) + , poseidon2_T_61_7(il[590]) + , poseidon2_T_62_4(il[591]) + , poseidon2_T_62_5(il[592]) + , poseidon2_T_62_6(il[593]) + , poseidon2_T_62_7(il[594]) + , poseidon2_T_63_4(il[595]) + , poseidon2_T_63_5(il[596]) + , poseidon2_T_63_6(il[597]) + , poseidon2_T_63_7(il[598]) + , poseidon2_a_0(il[599]) + , poseidon2_a_1(il[600]) + , poseidon2_a_2(il[601]) + , poseidon2_a_3(il[602]) + , poseidon2_b_0(il[603]) + , poseidon2_b_1(il[604]) + , poseidon2_b_2(il[605]) + , poseidon2_b_3(il[606]) + , poseidon2_clk(il[607]) + , poseidon2_full_a_0(il[608]) + , poseidon2_full_a_1(il[609]) + , poseidon2_full_a_2(il[610]) + , poseidon2_full_a_3(il[611]) + , poseidon2_full_b_0(il[612]) + , poseidon2_full_b_1(il[613]) + , poseidon2_full_b_2(il[614]) + , poseidon2_full_b_3(il[615]) + , poseidon2_full_clk(il[616]) + , poseidon2_full_end_poseidon(il[617]) + , poseidon2_full_execute_poseidon_perm(il[618]) + , poseidon2_full_input_0(il[619]) + , poseidon2_full_input_1(il[620]) + , poseidon2_full_input_2(il[621]) + , poseidon2_full_input_len(il[622]) + , poseidon2_full_num_perm_rounds_rem(il[623]) + , poseidon2_full_num_perm_rounds_rem_inv(il[624]) + , poseidon2_full_output(il[625]) + , poseidon2_full_padding(il[626]) + , poseidon2_full_sel_merkle_tree(il[627]) + , poseidon2_full_sel_poseidon(il[628]) + , poseidon2_full_start_poseidon(il[629]) + , poseidon2_input_addr(il[630]) + , poseidon2_mem_addr_read_a(il[631]) + , poseidon2_mem_addr_read_b(il[632]) + , poseidon2_mem_addr_read_c(il[633]) + , poseidon2_mem_addr_read_d(il[634]) + , poseidon2_mem_addr_write_a(il[635]) + , poseidon2_mem_addr_write_b(il[636]) + , poseidon2_mem_addr_write_c(il[637]) + , poseidon2_mem_addr_write_d(il[638]) + , poseidon2_output_addr(il[639]) + , poseidon2_sel_poseidon_perm(il[640]) + , poseidon2_sel_poseidon_perm_immediate(il[641]) + , poseidon2_sel_poseidon_perm_mem_op(il[642]) + , poseidon2_space_id(il[643]) + , range_check_alu_rng_chk(il[644]) + , range_check_clk(il[645]) + , range_check_cmp_hi_bits_rng_chk(il[646]) + , range_check_cmp_lo_bits_rng_chk(il[647]) + , range_check_dyn_diff(il[648]) + , range_check_dyn_rng_chk_bits(il[649]) + , range_check_dyn_rng_chk_pow_2(il[650]) + , range_check_gas_da_rng_chk(il[651]) + , range_check_gas_l2_rng_chk(il[652]) + , range_check_is_lte_u112(il[653]) + , range_check_is_lte_u128(il[654]) + , range_check_is_lte_u16(il[655]) + , range_check_is_lte_u32(il[656]) + , range_check_is_lte_u48(il[657]) + , range_check_is_lte_u64(il[658]) + , range_check_is_lte_u80(il[659]) + , range_check_is_lte_u96(il[660]) + , range_check_rng_chk_bits(il[661]) + , range_check_sel_lookup_0(il[662]) + , range_check_sel_lookup_1(il[663]) + , range_check_sel_lookup_2(il[664]) + , range_check_sel_lookup_3(il[665]) + , range_check_sel_lookup_4(il[666]) + , range_check_sel_lookup_5(il[667]) + , range_check_sel_lookup_6(il[668]) + , range_check_sel_rng_chk(il[669]) + , range_check_u16_r0(il[670]) + , range_check_u16_r1(il[671]) + , range_check_u16_r2(il[672]) + , range_check_u16_r3(il[673]) + , range_check_u16_r4(il[674]) + , range_check_u16_r5(il[675]) + , range_check_u16_r6(il[676]) + , range_check_u16_r7(il[677]) + , range_check_value(il[678]) + , sha256_clk(il[679]) + , sha256_input(il[680]) + , sha256_output(il[681]) + , sha256_sel_sha256_compression(il[682]) + , sha256_state(il[683]) + , slice_addr(il[684]) + , slice_clk(il[685]) + , slice_cnt(il[686]) + , slice_col_offset(il[687]) + , slice_one_min_inv(il[688]) + , slice_sel_cd_cpy(il[689]) + , slice_sel_mem_active(il[690]) + , slice_sel_return(il[691]) + , slice_sel_start(il[692]) + , slice_space_id(il[693]) + , slice_val(il[694]) + , lookup_rng_chk_pow_2_counts(il[695]) + , lookup_rng_chk_diff_counts(il[696]) + , lookup_rng_chk_0_counts(il[697]) + , lookup_rng_chk_1_counts(il[698]) + , lookup_rng_chk_2_counts(il[699]) + , lookup_rng_chk_3_counts(il[700]) + , lookup_rng_chk_4_counts(il[701]) + , lookup_rng_chk_5_counts(il[702]) + , lookup_rng_chk_6_counts(il[703]) + , lookup_rng_chk_7_counts(il[704]) + , lookup_mem_rng_chk_0_counts(il[705]) + , lookup_mem_rng_chk_1_counts(il[706]) + , lookup_mem_rng_chk_2_counts(il[707]) + , lookup_pow_2_0_counts(il[708]) + , lookup_pow_2_1_counts(il[709]) + , lookup_byte_lengths_counts(il[710]) + , lookup_byte_operations_counts(il[711]) + , lookup_opcode_gas_counts(il[712]) + , lookup_l2_gas_rng_chk_0_counts(il[713]) + , lookup_l2_gas_rng_chk_1_counts(il[714]) + , lookup_da_gas_rng_chk_0_counts(il[715]) + , lookup_da_gas_rng_chk_1_counts(il[716]) + , kernel_output_lookup_counts(il[717]) + , lookup_into_kernel_counts(il[718]) + , lookup_cd_value_counts(il[719]) + , lookup_ret_value_counts(il[720]) + , incl_main_tag_err_counts(il[721]) + , incl_mem_tag_err_counts(il[722]) + , perm_rng_cmp_lo_inv(il[723]) + , perm_rng_cmp_hi_inv(il[724]) + , perm_rng_alu_inv(il[725]) + , perm_cmp_alu_inv(il[726]) + , perm_l2_start_gas_inv(il[727]) + , perm_da_start_gas_inv(il[728]) + , perm_l2_end_gas_inv(il[729]) + , perm_da_end_gas_inv(il[730]) + , perm_pos_mem_read_a_inv(il[731]) + , perm_pos_mem_read_b_inv(il[732]) + , perm_pos_mem_read_c_inv(il[733]) + , perm_pos_mem_read_d_inv(il[734]) + , perm_pos_mem_write_a_inv(il[735]) + , perm_pos_mem_write_b_inv(il[736]) + , perm_pos_mem_write_c_inv(il[737]) + , perm_pos_mem_write_d_inv(il[738]) + , perm_pos2_fixed_pos2_perm_inv(il[739]) + , perm_slice_mem_inv(il[740]) + , perm_merkle_poseidon2_inv(il[741]) + , perm_main_alu_inv(il[742]) + , perm_main_bin_inv(il[743]) + , perm_main_conv_inv(il[744]) + , perm_main_sha256_inv(il[745]) + , perm_main_pos2_perm_inv(il[746]) + , perm_main_slice_inv(il[747]) + , perm_main_mem_a_inv(il[748]) + , perm_main_mem_b_inv(il[749]) + , perm_main_mem_c_inv(il[750]) + , perm_main_mem_d_inv(il[751]) + , perm_main_mem_ind_addr_a_inv(il[752]) + , perm_main_mem_ind_addr_b_inv(il[753]) + , perm_main_mem_ind_addr_c_inv(il[754]) + , perm_main_mem_ind_addr_d_inv(il[755]) + , lookup_rng_chk_pow_2_inv(il[756]) + , lookup_rng_chk_diff_inv(il[757]) + , lookup_rng_chk_0_inv(il[758]) + , lookup_rng_chk_1_inv(il[759]) + , lookup_rng_chk_2_inv(il[760]) + , lookup_rng_chk_3_inv(il[761]) + , lookup_rng_chk_4_inv(il[762]) + , lookup_rng_chk_5_inv(il[763]) + , lookup_rng_chk_6_inv(il[764]) + , lookup_rng_chk_7_inv(il[765]) + , lookup_mem_rng_chk_0_inv(il[766]) + , lookup_mem_rng_chk_1_inv(il[767]) + , lookup_mem_rng_chk_2_inv(il[768]) + , lookup_pow_2_0_inv(il[769]) + , lookup_pow_2_1_inv(il[770]) + , lookup_byte_lengths_inv(il[771]) + , lookup_byte_operations_inv(il[772]) + , lookup_opcode_gas_inv(il[773]) + , lookup_l2_gas_rng_chk_0_inv(il[774]) + , lookup_l2_gas_rng_chk_1_inv(il[775]) + , lookup_da_gas_rng_chk_0_inv(il[776]) + , lookup_da_gas_rng_chk_1_inv(il[777]) + , kernel_output_lookup_inv(il[778]) + , lookup_into_kernel_inv(il[779]) + , lookup_cd_value_inv(il[780]) + , lookup_ret_value_inv(il[781]) + , incl_main_tag_err_inv(il[782]) + , incl_mem_tag_err_inv(il[783]) + , binary_acc_ia_shift(il[784]) + , binary_acc_ib_shift(il[785]) + , binary_acc_ic_shift(il[786]) + , binary_mem_tag_ctr_shift(il[787]) + , binary_op_id_shift(il[788]) + , cmp_a_hi_shift(il[789]) + , cmp_a_lo_shift(il[790]) + , cmp_b_hi_shift(il[791]) + , cmp_b_lo_shift(il[792]) + , cmp_cmp_rng_ctr_shift(il[793]) + , cmp_op_gt_shift(il[794]) + , cmp_p_sub_a_hi_shift(il[795]) + , cmp_p_sub_a_lo_shift(il[796]) + , cmp_p_sub_b_hi_shift(il[797]) + , cmp_p_sub_b_lo_shift(il[798]) + , cmp_sel_rng_chk_shift(il[799]) + , main_da_gas_remaining_shift(il[800]) + , main_emit_l2_to_l1_msg_write_offset_shift(il[801]) + , main_emit_note_hash_write_offset_shift(il[802]) + , main_emit_nullifier_write_offset_shift(il[803]) + , main_emit_unencrypted_log_write_offset_shift(il[804]) + , main_internal_return_ptr_shift(il[805]) + , main_l1_to_l2_msg_exists_write_offset_shift(il[806]) + , main_l2_gas_remaining_shift(il[807]) + , main_note_hash_exist_write_offset_shift(il[808]) + , main_nullifier_exists_write_offset_shift(il[809]) + , main_nullifier_non_exists_write_offset_shift(il[810]) + , main_pc_shift(il[811]) + , main_sel_execution_end_shift(il[812]) + , main_sel_execution_row_shift(il[813]) + , main_sload_write_offset_shift(il[814]) + , main_sstore_write_offset_shift(il[815]) + , mem_glob_addr_shift(il[816]) + , mem_rw_shift(il[817]) + , mem_sel_mem_shift(il[818]) + , mem_tag_shift(il[819]) + , mem_tsp_shift(il[820]) + , mem_val_shift(il[821]) + , merkle_tree_leaf_index_shift(il[822]) + , merkle_tree_leaf_value_shift(il[823]) + , merkle_tree_path_len_shift(il[824]) + , poseidon2_full_a_0_shift(il[825]) + , poseidon2_full_a_1_shift(il[826]) + , poseidon2_full_a_2_shift(il[827]) + , poseidon2_full_a_3_shift(il[828]) + , poseidon2_full_execute_poseidon_perm_shift(il[829]) + , poseidon2_full_input_0_shift(il[830]) + , poseidon2_full_input_1_shift(il[831]) + , poseidon2_full_input_2_shift(il[832]) + , poseidon2_full_num_perm_rounds_rem_shift(il[833]) + , poseidon2_full_sel_poseidon_shift(il[834]) + , poseidon2_full_start_poseidon_shift(il[835]) + , slice_addr_shift(il[836]) + , slice_clk_shift(il[837]) + , slice_cnt_shift(il[838]) + , slice_col_offset_shift(il[839]) + , slice_sel_cd_cpy_shift(il[840]) + , slice_sel_mem_active_shift(il[841]) + , slice_sel_return_shift(il[842]) + , slice_sel_start_shift(il[843]) + , slice_space_id_shift(il[844]) {} AvmFlavor::ProverPolynomials::ProverPolynomials(ProvingKey& proving_key) @@ -1085,6 +1086,7 @@ AvmFlavor::AllConstRefValues AvmFlavor::ProverPolynomials::get_row(size_t row_id main_sel_op_cast[row_idx], main_sel_op_chain_id[row_idx], main_sel_op_dagasleft[row_idx], + main_sel_op_debug_log[row_idx], main_sel_op_div[row_idx], main_sel_op_ecadd[row_idx], main_sel_op_emit_l2_to_l1_msg[row_idx], @@ -1933,6 +1935,7 @@ AvmFlavor::CommitmentLabels::CommitmentLabels() Base::main_sel_op_cast = "MAIN_SEL_OP_CAST"; Base::main_sel_op_chain_id = "MAIN_SEL_OP_CHAIN_ID"; Base::main_sel_op_dagasleft = "MAIN_SEL_OP_DAGASLEFT"; + Base::main_sel_op_debug_log = "MAIN_SEL_OP_DEBUG_LOG"; Base::main_sel_op_div = "MAIN_SEL_OP_DIV"; Base::main_sel_op_ecadd = "MAIN_SEL_OP_ECADD"; Base::main_sel_op_emit_l2_to_l1_msg = "MAIN_SEL_OP_EMIT_L2_TO_L1_MSG"; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp index 19880c215eb..11a849f85c4 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp @@ -102,7 +102,7 @@ template using tuple_cat_t = decltype(std::tuple_cat(std:: // The entities that will be used in the flavor. // clang-format off #define PRECOMPUTED_ENTITIES byte_lookup_sel_bin, byte_lookup_table_byte_lengths, byte_lookup_table_in_tags, byte_lookup_table_input_a, byte_lookup_table_input_b, byte_lookup_table_op_id, byte_lookup_table_output, gas_base_da_gas_fixed_table, gas_base_l2_gas_fixed_table, gas_dyn_da_gas_fixed_table, gas_dyn_l2_gas_fixed_table, gas_sel_gas_cost, main_clk, main_sel_da_end_gas_kernel_input, main_sel_da_start_gas_kernel_input, main_sel_first, main_sel_l2_end_gas_kernel_input, main_sel_l2_start_gas_kernel_input, main_sel_start_exec, main_zeroes, powers_power_of_2 -#define WIRE_ENTITIES main_kernel_inputs, main_kernel_value_out, main_kernel_side_effect_out, main_kernel_metadata_out, main_calldata, main_returndata, alu_a_hi, alu_a_lo, alu_b_hi, alu_b_lo, alu_b_pow, alu_c_hi, alu_c_lo, alu_cf, alu_clk, alu_cmp_gadget_gt, alu_cmp_gadget_input_a, alu_cmp_gadget_input_b, alu_cmp_gadget_result, alu_cmp_gadget_sel, alu_ff_tag, alu_ia, alu_ib, alu_ic, alu_in_tag, alu_max_bits_sub_b_bits, alu_max_bits_sub_b_pow, alu_op_add, alu_op_cast, alu_op_div, alu_op_eq, alu_op_lt, alu_op_lte, alu_op_mul, alu_op_not, alu_op_shl, alu_op_shr, alu_op_sub, alu_partial_prod_hi, alu_partial_prod_lo, alu_range_check_input_value, alu_range_check_num_bits, alu_range_check_sel, alu_remainder, alu_sel_alu, alu_sel_cmp, alu_sel_shift_which, alu_u128_tag, alu_u16_tag, alu_u1_tag, alu_u32_tag, alu_u64_tag, alu_u8_tag, alu_zero_shift, binary_acc_ia, binary_acc_ib, binary_acc_ic, binary_clk, binary_ia_bytes, binary_ib_bytes, binary_ic_bytes, binary_in_tag, binary_mem_tag_ctr, binary_mem_tag_ctr_inv, binary_op_id, binary_sel_bin, binary_start, bytecode_arifact_hash, bytecode_as_fields, bytecode_bytes, bytecode_bytes_pc, bytecode_class_id, bytecode_contract_address, bytecode_decomposed, bytecode_deployer_addr, bytecode_end_latch, bytecode_incoming_viewing_key_x, bytecode_incoming_viewing_key_y, bytecode_initialization_hash, bytecode_length_remaining, bytecode_nullifier_key_x, bytecode_nullifier_key_y, bytecode_outgoing_viewing_key_x, bytecode_outgoing_viewing_key_y, bytecode_private_fn_root, bytecode_public_key_hash, bytecode_running_hash, bytecode_salt, bytecode_tagging_key_x, bytecode_tagging_key_y, cmp_a_hi, cmp_a_lo, cmp_b_hi, cmp_b_lo, cmp_borrow, cmp_clk, cmp_cmp_rng_ctr, cmp_input_a, cmp_input_b, cmp_op_eq, cmp_op_eq_diff_inv, cmp_op_gt, cmp_p_a_borrow, cmp_p_b_borrow, cmp_p_sub_a_hi, cmp_p_sub_a_lo, cmp_p_sub_b_hi, cmp_p_sub_b_lo, cmp_range_chk_clk, cmp_res_hi, cmp_res_lo, cmp_result, cmp_sel_cmp, cmp_sel_rng_chk, cmp_shift_sel, conversion_clk, conversion_input, conversion_num_limbs, conversion_output_bits, conversion_radix, conversion_sel_to_radix_be, keccakf1600_clk, keccakf1600_input, keccakf1600_output, keccakf1600_sel_keccakf1600, main_abs_da_rem_gas, main_abs_l2_rem_gas, main_alu_in_tag, main_base_da_gas_op_cost, main_base_l2_gas_op_cost, main_bin_op_id, main_call_ptr, main_da_gas_remaining, main_da_gas_u16_r0, main_da_gas_u16_r1, main_da_out_of_gas, main_dyn_da_gas_op_cost, main_dyn_gas_multiplier, main_dyn_l2_gas_op_cost, main_emit_l2_to_l1_msg_write_offset, main_emit_note_hash_write_offset, main_emit_nullifier_write_offset, main_emit_unencrypted_log_write_offset, main_ia, main_ib, main_ic, main_id, main_id_zero, main_ind_addr_a, main_ind_addr_b, main_ind_addr_c, main_ind_addr_d, main_internal_return_ptr, main_inv, main_is_fake_row, main_is_gas_accounted, main_kernel_in_offset, main_kernel_out_offset, main_l1_to_l2_msg_exists_write_offset, main_l2_gas_remaining, main_l2_gas_u16_r0, main_l2_gas_u16_r1, main_l2_out_of_gas, main_mem_addr_a, main_mem_addr_b, main_mem_addr_c, main_mem_addr_d, main_note_hash_exist_write_offset, main_nullifier_exists_write_offset, main_nullifier_non_exists_write_offset, main_op_err, main_opcode_val, main_pc, main_r_in_tag, main_rwa, main_rwb, main_rwc, main_rwd, main_sel_alu, main_sel_bin, main_sel_calldata, main_sel_execution_end, main_sel_execution_row, main_sel_kernel_inputs, main_sel_kernel_out, main_sel_mem_op_a, main_sel_mem_op_b, main_sel_mem_op_c, main_sel_mem_op_d, main_sel_mov_ia_to_ic, main_sel_mov_ib_to_ic, main_sel_op_add, main_sel_op_address, main_sel_op_and, main_sel_op_block_number, main_sel_op_calldata_copy, main_sel_op_cast, main_sel_op_chain_id, main_sel_op_dagasleft, main_sel_op_div, main_sel_op_ecadd, main_sel_op_emit_l2_to_l1_msg, main_sel_op_emit_note_hash, main_sel_op_emit_nullifier, main_sel_op_emit_unencrypted_log, main_sel_op_eq, main_sel_op_external_call, main_sel_op_external_return, main_sel_op_external_revert, main_sel_op_fdiv, main_sel_op_fee_per_da_gas, main_sel_op_fee_per_l2_gas, main_sel_op_function_selector, main_sel_op_get_contract_instance, main_sel_op_internal_call, main_sel_op_internal_return, main_sel_op_is_static_call, main_sel_op_jump, main_sel_op_jumpi, main_sel_op_keccak, main_sel_op_l1_to_l2_msg_exists, main_sel_op_l2gasleft, main_sel_op_lt, main_sel_op_lte, main_sel_op_mov, main_sel_op_msm, main_sel_op_mul, main_sel_op_not, main_sel_op_note_hash_exists, main_sel_op_nullifier_exists, main_sel_op_or, main_sel_op_poseidon2, main_sel_op_radix_be, main_sel_op_returndata_copy, main_sel_op_returndata_size, main_sel_op_sender, main_sel_op_set, main_sel_op_sha256, main_sel_op_shl, main_sel_op_shr, main_sel_op_sload, main_sel_op_sstore, main_sel_op_static_call, main_sel_op_sub, main_sel_op_timestamp, main_sel_op_transaction_fee, main_sel_op_version, main_sel_op_xor, main_sel_q_kernel_lookup, main_sel_q_kernel_output_lookup, main_sel_resolve_ind_addr_a, main_sel_resolve_ind_addr_b, main_sel_resolve_ind_addr_c, main_sel_resolve_ind_addr_d, main_sel_returndata, main_sel_rng_16, main_sel_rng_8, main_sel_slice_gadget, main_side_effect_counter, main_sload_write_offset, main_space_id, main_sstore_write_offset, main_tag_err, main_w_in_tag, mem_addr, mem_clk, mem_diff, mem_glob_addr, mem_last, mem_lastAccess, mem_one_min_inv, mem_r_in_tag, mem_rw, mem_sel_mem, mem_sel_mov_ia_to_ic, mem_sel_mov_ib_to_ic, mem_sel_op_a, mem_sel_op_b, mem_sel_op_c, mem_sel_op_d, mem_sel_op_poseidon_read_a, mem_sel_op_poseidon_read_b, mem_sel_op_poseidon_read_c, mem_sel_op_poseidon_read_d, mem_sel_op_poseidon_write_a, mem_sel_op_poseidon_write_b, mem_sel_op_poseidon_write_c, mem_sel_op_poseidon_write_d, mem_sel_op_slice, mem_sel_resolve_ind_addr_a, mem_sel_resolve_ind_addr_b, mem_sel_resolve_ind_addr_c, mem_sel_resolve_ind_addr_d, mem_sel_rng_chk, mem_skip_check_tag, mem_space_id, mem_tag, mem_tag_err, mem_tsp, mem_u16_r0, mem_u16_r1, mem_u8_r0, mem_val, mem_w_in_tag, merkle_tree_clk, merkle_tree_expected_tree_root, merkle_tree_latch, merkle_tree_leaf_index, merkle_tree_leaf_index_is_even, merkle_tree_leaf_value, merkle_tree_left_hash, merkle_tree_output_hash, merkle_tree_path_len, merkle_tree_path_len_inv, merkle_tree_right_hash, merkle_tree_sel_merkle_tree, merkle_tree_sibling_value, poseidon2_B_10_0, poseidon2_B_10_1, poseidon2_B_10_2, poseidon2_B_10_3, poseidon2_B_11_0, poseidon2_B_11_1, poseidon2_B_11_2, poseidon2_B_11_3, poseidon2_B_12_0, poseidon2_B_12_1, poseidon2_B_12_2, poseidon2_B_12_3, poseidon2_B_13_0, poseidon2_B_13_1, poseidon2_B_13_2, poseidon2_B_13_3, poseidon2_B_14_0, poseidon2_B_14_1, poseidon2_B_14_2, poseidon2_B_14_3, poseidon2_B_15_0, poseidon2_B_15_1, poseidon2_B_15_2, poseidon2_B_15_3, poseidon2_B_16_0, poseidon2_B_16_1, poseidon2_B_16_2, poseidon2_B_16_3, poseidon2_B_17_0, poseidon2_B_17_1, poseidon2_B_17_2, poseidon2_B_17_3, poseidon2_B_18_0, poseidon2_B_18_1, poseidon2_B_18_2, poseidon2_B_18_3, poseidon2_B_19_0, poseidon2_B_19_1, poseidon2_B_19_2, poseidon2_B_19_3, poseidon2_B_20_0, poseidon2_B_20_1, poseidon2_B_20_2, poseidon2_B_20_3, poseidon2_B_21_0, poseidon2_B_21_1, poseidon2_B_21_2, poseidon2_B_21_3, poseidon2_B_22_0, poseidon2_B_22_1, poseidon2_B_22_2, poseidon2_B_22_3, poseidon2_B_23_0, poseidon2_B_23_1, poseidon2_B_23_2, poseidon2_B_23_3, poseidon2_B_24_0, poseidon2_B_24_1, poseidon2_B_24_2, poseidon2_B_24_3, poseidon2_B_25_0, poseidon2_B_25_1, poseidon2_B_25_2, poseidon2_B_25_3, poseidon2_B_26_0, poseidon2_B_26_1, poseidon2_B_26_2, poseidon2_B_26_3, poseidon2_B_27_0, poseidon2_B_27_1, poseidon2_B_27_2, poseidon2_B_27_3, poseidon2_B_28_0, poseidon2_B_28_1, poseidon2_B_28_2, poseidon2_B_28_3, poseidon2_B_29_0, poseidon2_B_29_1, poseidon2_B_29_2, poseidon2_B_29_3, poseidon2_B_30_0, poseidon2_B_30_1, poseidon2_B_30_2, poseidon2_B_30_3, poseidon2_B_31_0, poseidon2_B_31_1, poseidon2_B_31_2, poseidon2_B_31_3, poseidon2_B_32_0, poseidon2_B_32_1, poseidon2_B_32_2, poseidon2_B_32_3, poseidon2_B_33_0, poseidon2_B_33_1, poseidon2_B_33_2, poseidon2_B_33_3, poseidon2_B_34_0, poseidon2_B_34_1, poseidon2_B_34_2, poseidon2_B_34_3, poseidon2_B_35_0, poseidon2_B_35_1, poseidon2_B_35_2, poseidon2_B_35_3, poseidon2_B_36_0, poseidon2_B_36_1, poseidon2_B_36_2, poseidon2_B_36_3, poseidon2_B_37_0, poseidon2_B_37_1, poseidon2_B_37_2, poseidon2_B_37_3, poseidon2_B_38_0, poseidon2_B_38_1, poseidon2_B_38_2, poseidon2_B_38_3, poseidon2_B_39_0, poseidon2_B_39_1, poseidon2_B_39_2, poseidon2_B_39_3, poseidon2_B_40_0, poseidon2_B_40_1, poseidon2_B_40_2, poseidon2_B_40_3, poseidon2_B_41_0, poseidon2_B_41_1, poseidon2_B_41_2, poseidon2_B_41_3, poseidon2_B_42_0, poseidon2_B_42_1, poseidon2_B_42_2, poseidon2_B_42_3, poseidon2_B_43_0, poseidon2_B_43_1, poseidon2_B_43_2, poseidon2_B_43_3, poseidon2_B_44_0, poseidon2_B_44_1, poseidon2_B_44_2, poseidon2_B_44_3, poseidon2_B_45_0, poseidon2_B_45_1, poseidon2_B_45_2, poseidon2_B_45_3, poseidon2_B_46_0, poseidon2_B_46_1, poseidon2_B_46_2, poseidon2_B_46_3, poseidon2_B_47_0, poseidon2_B_47_1, poseidon2_B_47_2, poseidon2_B_47_3, poseidon2_B_48_0, poseidon2_B_48_1, poseidon2_B_48_2, poseidon2_B_48_3, poseidon2_B_49_0, poseidon2_B_49_1, poseidon2_B_49_2, poseidon2_B_49_3, poseidon2_B_4_0, poseidon2_B_4_1, poseidon2_B_4_2, poseidon2_B_4_3, poseidon2_B_50_0, poseidon2_B_50_1, poseidon2_B_50_2, poseidon2_B_50_3, poseidon2_B_51_0, poseidon2_B_51_1, poseidon2_B_51_2, poseidon2_B_51_3, poseidon2_B_52_0, poseidon2_B_52_1, poseidon2_B_52_2, poseidon2_B_52_3, poseidon2_B_53_0, poseidon2_B_53_1, poseidon2_B_53_2, poseidon2_B_53_3, poseidon2_B_54_0, poseidon2_B_54_1, poseidon2_B_54_2, poseidon2_B_54_3, poseidon2_B_55_0, poseidon2_B_55_1, poseidon2_B_55_2, poseidon2_B_55_3, poseidon2_B_56_0, poseidon2_B_56_1, poseidon2_B_56_2, poseidon2_B_56_3, poseidon2_B_57_0, poseidon2_B_57_1, poseidon2_B_57_2, poseidon2_B_57_3, poseidon2_B_58_0, poseidon2_B_58_1, poseidon2_B_58_2, poseidon2_B_58_3, poseidon2_B_59_0, poseidon2_B_59_1, poseidon2_B_59_2, poseidon2_B_59_3, poseidon2_B_5_0, poseidon2_B_5_1, poseidon2_B_5_2, poseidon2_B_5_3, poseidon2_B_6_0, poseidon2_B_6_1, poseidon2_B_6_2, poseidon2_B_6_3, poseidon2_B_7_0, poseidon2_B_7_1, poseidon2_B_7_2, poseidon2_B_7_3, poseidon2_B_8_0, poseidon2_B_8_1, poseidon2_B_8_2, poseidon2_B_8_3, poseidon2_B_9_0, poseidon2_B_9_1, poseidon2_B_9_2, poseidon2_B_9_3, poseidon2_EXT_LAYER_4, poseidon2_EXT_LAYER_5, poseidon2_EXT_LAYER_6, poseidon2_EXT_LAYER_7, poseidon2_T_0_4, poseidon2_T_0_5, poseidon2_T_0_6, poseidon2_T_0_7, poseidon2_T_1_4, poseidon2_T_1_5, poseidon2_T_1_6, poseidon2_T_1_7, poseidon2_T_2_4, poseidon2_T_2_5, poseidon2_T_2_6, poseidon2_T_2_7, poseidon2_T_3_4, poseidon2_T_3_5, poseidon2_T_3_6, poseidon2_T_3_7, poseidon2_T_60_4, poseidon2_T_60_5, poseidon2_T_60_6, poseidon2_T_60_7, poseidon2_T_61_4, poseidon2_T_61_5, poseidon2_T_61_6, poseidon2_T_61_7, poseidon2_T_62_4, poseidon2_T_62_5, poseidon2_T_62_6, poseidon2_T_62_7, poseidon2_T_63_4, poseidon2_T_63_5, poseidon2_T_63_6, poseidon2_T_63_7, poseidon2_a_0, poseidon2_a_1, poseidon2_a_2, poseidon2_a_3, poseidon2_b_0, poseidon2_b_1, poseidon2_b_2, poseidon2_b_3, poseidon2_clk, poseidon2_full_a_0, poseidon2_full_a_1, poseidon2_full_a_2, poseidon2_full_a_3, poseidon2_full_b_0, poseidon2_full_b_1, poseidon2_full_b_2, poseidon2_full_b_3, poseidon2_full_clk, poseidon2_full_end_poseidon, poseidon2_full_execute_poseidon_perm, poseidon2_full_input_0, poseidon2_full_input_1, poseidon2_full_input_2, poseidon2_full_input_len, poseidon2_full_num_perm_rounds_rem, poseidon2_full_num_perm_rounds_rem_inv, poseidon2_full_output, poseidon2_full_padding, poseidon2_full_sel_merkle_tree, poseidon2_full_sel_poseidon, poseidon2_full_start_poseidon, poseidon2_input_addr, poseidon2_mem_addr_read_a, poseidon2_mem_addr_read_b, poseidon2_mem_addr_read_c, poseidon2_mem_addr_read_d, poseidon2_mem_addr_write_a, poseidon2_mem_addr_write_b, poseidon2_mem_addr_write_c, poseidon2_mem_addr_write_d, poseidon2_output_addr, poseidon2_sel_poseidon_perm, poseidon2_sel_poseidon_perm_immediate, poseidon2_sel_poseidon_perm_mem_op, poseidon2_space_id, range_check_alu_rng_chk, range_check_clk, range_check_cmp_hi_bits_rng_chk, range_check_cmp_lo_bits_rng_chk, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_gas_da_rng_chk, range_check_gas_l2_rng_chk, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_rng_chk_bits, range_check_sel_lookup_0, range_check_sel_lookup_1, range_check_sel_lookup_2, range_check_sel_lookup_3, range_check_sel_lookup_4, range_check_sel_lookup_5, range_check_sel_lookup_6, range_check_sel_rng_chk, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, sha256_clk, sha256_input, sha256_output, sha256_sel_sha256_compression, sha256_state, slice_addr, slice_clk, slice_cnt, slice_col_offset, slice_one_min_inv, slice_sel_cd_cpy, slice_sel_mem_active, slice_sel_return, slice_sel_start, slice_space_id, slice_val, lookup_rng_chk_pow_2_counts, lookup_rng_chk_diff_counts, lookup_rng_chk_0_counts, lookup_rng_chk_1_counts, lookup_rng_chk_2_counts, lookup_rng_chk_3_counts, lookup_rng_chk_4_counts, lookup_rng_chk_5_counts, lookup_rng_chk_6_counts, lookup_rng_chk_7_counts, lookup_mem_rng_chk_0_counts, lookup_mem_rng_chk_1_counts, lookup_mem_rng_chk_2_counts, lookup_pow_2_0_counts, lookup_pow_2_1_counts, lookup_byte_lengths_counts, lookup_byte_operations_counts, lookup_opcode_gas_counts, lookup_l2_gas_rng_chk_0_counts, lookup_l2_gas_rng_chk_1_counts, lookup_da_gas_rng_chk_0_counts, lookup_da_gas_rng_chk_1_counts, kernel_output_lookup_counts, lookup_into_kernel_counts, lookup_cd_value_counts, lookup_ret_value_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts +#define WIRE_ENTITIES main_kernel_inputs, main_kernel_value_out, main_kernel_side_effect_out, main_kernel_metadata_out, main_calldata, main_returndata, alu_a_hi, alu_a_lo, alu_b_hi, alu_b_lo, alu_b_pow, alu_c_hi, alu_c_lo, alu_cf, alu_clk, alu_cmp_gadget_gt, alu_cmp_gadget_input_a, alu_cmp_gadget_input_b, alu_cmp_gadget_result, alu_cmp_gadget_sel, alu_ff_tag, alu_ia, alu_ib, alu_ic, alu_in_tag, alu_max_bits_sub_b_bits, alu_max_bits_sub_b_pow, alu_op_add, alu_op_cast, alu_op_div, alu_op_eq, alu_op_lt, alu_op_lte, alu_op_mul, alu_op_not, alu_op_shl, alu_op_shr, alu_op_sub, alu_partial_prod_hi, alu_partial_prod_lo, alu_range_check_input_value, alu_range_check_num_bits, alu_range_check_sel, alu_remainder, alu_sel_alu, alu_sel_cmp, alu_sel_shift_which, alu_u128_tag, alu_u16_tag, alu_u1_tag, alu_u32_tag, alu_u64_tag, alu_u8_tag, alu_zero_shift, binary_acc_ia, binary_acc_ib, binary_acc_ic, binary_clk, binary_ia_bytes, binary_ib_bytes, binary_ic_bytes, binary_in_tag, binary_mem_tag_ctr, binary_mem_tag_ctr_inv, binary_op_id, binary_sel_bin, binary_start, bytecode_arifact_hash, bytecode_as_fields, bytecode_bytes, bytecode_bytes_pc, bytecode_class_id, bytecode_contract_address, bytecode_decomposed, bytecode_deployer_addr, bytecode_end_latch, bytecode_incoming_viewing_key_x, bytecode_incoming_viewing_key_y, bytecode_initialization_hash, bytecode_length_remaining, bytecode_nullifier_key_x, bytecode_nullifier_key_y, bytecode_outgoing_viewing_key_x, bytecode_outgoing_viewing_key_y, bytecode_private_fn_root, bytecode_public_key_hash, bytecode_running_hash, bytecode_salt, bytecode_tagging_key_x, bytecode_tagging_key_y, cmp_a_hi, cmp_a_lo, cmp_b_hi, cmp_b_lo, cmp_borrow, cmp_clk, cmp_cmp_rng_ctr, cmp_input_a, cmp_input_b, cmp_op_eq, cmp_op_eq_diff_inv, cmp_op_gt, cmp_p_a_borrow, cmp_p_b_borrow, cmp_p_sub_a_hi, cmp_p_sub_a_lo, cmp_p_sub_b_hi, cmp_p_sub_b_lo, cmp_range_chk_clk, cmp_res_hi, cmp_res_lo, cmp_result, cmp_sel_cmp, cmp_sel_rng_chk, cmp_shift_sel, conversion_clk, conversion_input, conversion_num_limbs, conversion_output_bits, conversion_radix, conversion_sel_to_radix_be, keccakf1600_clk, keccakf1600_input, keccakf1600_output, keccakf1600_sel_keccakf1600, main_abs_da_rem_gas, main_abs_l2_rem_gas, main_alu_in_tag, main_base_da_gas_op_cost, main_base_l2_gas_op_cost, main_bin_op_id, main_call_ptr, main_da_gas_remaining, main_da_gas_u16_r0, main_da_gas_u16_r1, main_da_out_of_gas, main_dyn_da_gas_op_cost, main_dyn_gas_multiplier, main_dyn_l2_gas_op_cost, main_emit_l2_to_l1_msg_write_offset, main_emit_note_hash_write_offset, main_emit_nullifier_write_offset, main_emit_unencrypted_log_write_offset, main_ia, main_ib, main_ic, main_id, main_id_zero, main_ind_addr_a, main_ind_addr_b, main_ind_addr_c, main_ind_addr_d, main_internal_return_ptr, main_inv, main_is_fake_row, main_is_gas_accounted, main_kernel_in_offset, main_kernel_out_offset, main_l1_to_l2_msg_exists_write_offset, main_l2_gas_remaining, main_l2_gas_u16_r0, main_l2_gas_u16_r1, main_l2_out_of_gas, main_mem_addr_a, main_mem_addr_b, main_mem_addr_c, main_mem_addr_d, main_note_hash_exist_write_offset, main_nullifier_exists_write_offset, main_nullifier_non_exists_write_offset, main_op_err, main_opcode_val, main_pc, main_r_in_tag, main_rwa, main_rwb, main_rwc, main_rwd, main_sel_alu, main_sel_bin, main_sel_calldata, main_sel_execution_end, main_sel_execution_row, main_sel_kernel_inputs, main_sel_kernel_out, main_sel_mem_op_a, main_sel_mem_op_b, main_sel_mem_op_c, main_sel_mem_op_d, main_sel_mov_ia_to_ic, main_sel_mov_ib_to_ic, main_sel_op_add, main_sel_op_address, main_sel_op_and, main_sel_op_block_number, main_sel_op_calldata_copy, main_sel_op_cast, main_sel_op_chain_id, main_sel_op_dagasleft, main_sel_op_debug_log, main_sel_op_div, main_sel_op_ecadd, main_sel_op_emit_l2_to_l1_msg, main_sel_op_emit_note_hash, main_sel_op_emit_nullifier, main_sel_op_emit_unencrypted_log, main_sel_op_eq, main_sel_op_external_call, main_sel_op_external_return, main_sel_op_external_revert, main_sel_op_fdiv, main_sel_op_fee_per_da_gas, main_sel_op_fee_per_l2_gas, main_sel_op_function_selector, main_sel_op_get_contract_instance, main_sel_op_internal_call, main_sel_op_internal_return, main_sel_op_is_static_call, main_sel_op_jump, main_sel_op_jumpi, main_sel_op_keccak, main_sel_op_l1_to_l2_msg_exists, main_sel_op_l2gasleft, main_sel_op_lt, main_sel_op_lte, main_sel_op_mov, main_sel_op_msm, main_sel_op_mul, main_sel_op_not, main_sel_op_note_hash_exists, main_sel_op_nullifier_exists, main_sel_op_or, main_sel_op_poseidon2, main_sel_op_radix_be, main_sel_op_returndata_copy, main_sel_op_returndata_size, main_sel_op_sender, main_sel_op_set, main_sel_op_sha256, main_sel_op_shl, main_sel_op_shr, main_sel_op_sload, main_sel_op_sstore, main_sel_op_static_call, main_sel_op_sub, main_sel_op_timestamp, main_sel_op_transaction_fee, main_sel_op_version, main_sel_op_xor, main_sel_q_kernel_lookup, main_sel_q_kernel_output_lookup, main_sel_resolve_ind_addr_a, main_sel_resolve_ind_addr_b, main_sel_resolve_ind_addr_c, main_sel_resolve_ind_addr_d, main_sel_returndata, main_sel_rng_16, main_sel_rng_8, main_sel_slice_gadget, main_side_effect_counter, main_sload_write_offset, main_space_id, main_sstore_write_offset, main_tag_err, main_w_in_tag, mem_addr, mem_clk, mem_diff, mem_glob_addr, mem_last, mem_lastAccess, mem_one_min_inv, mem_r_in_tag, mem_rw, mem_sel_mem, mem_sel_mov_ia_to_ic, mem_sel_mov_ib_to_ic, mem_sel_op_a, mem_sel_op_b, mem_sel_op_c, mem_sel_op_d, mem_sel_op_poseidon_read_a, mem_sel_op_poseidon_read_b, mem_sel_op_poseidon_read_c, mem_sel_op_poseidon_read_d, mem_sel_op_poseidon_write_a, mem_sel_op_poseidon_write_b, mem_sel_op_poseidon_write_c, mem_sel_op_poseidon_write_d, mem_sel_op_slice, mem_sel_resolve_ind_addr_a, mem_sel_resolve_ind_addr_b, mem_sel_resolve_ind_addr_c, mem_sel_resolve_ind_addr_d, mem_sel_rng_chk, mem_skip_check_tag, mem_space_id, mem_tag, mem_tag_err, mem_tsp, mem_u16_r0, mem_u16_r1, mem_u8_r0, mem_val, mem_w_in_tag, merkle_tree_clk, merkle_tree_expected_tree_root, merkle_tree_latch, merkle_tree_leaf_index, merkle_tree_leaf_index_is_even, merkle_tree_leaf_value, merkle_tree_left_hash, merkle_tree_output_hash, merkle_tree_path_len, merkle_tree_path_len_inv, merkle_tree_right_hash, merkle_tree_sel_merkle_tree, merkle_tree_sibling_value, poseidon2_B_10_0, poseidon2_B_10_1, poseidon2_B_10_2, poseidon2_B_10_3, poseidon2_B_11_0, poseidon2_B_11_1, poseidon2_B_11_2, poseidon2_B_11_3, poseidon2_B_12_0, poseidon2_B_12_1, poseidon2_B_12_2, poseidon2_B_12_3, poseidon2_B_13_0, poseidon2_B_13_1, poseidon2_B_13_2, poseidon2_B_13_3, poseidon2_B_14_0, poseidon2_B_14_1, poseidon2_B_14_2, poseidon2_B_14_3, poseidon2_B_15_0, poseidon2_B_15_1, poseidon2_B_15_2, poseidon2_B_15_3, poseidon2_B_16_0, poseidon2_B_16_1, poseidon2_B_16_2, poseidon2_B_16_3, poseidon2_B_17_0, poseidon2_B_17_1, poseidon2_B_17_2, poseidon2_B_17_3, poseidon2_B_18_0, poseidon2_B_18_1, poseidon2_B_18_2, poseidon2_B_18_3, poseidon2_B_19_0, poseidon2_B_19_1, poseidon2_B_19_2, poseidon2_B_19_3, poseidon2_B_20_0, poseidon2_B_20_1, poseidon2_B_20_2, poseidon2_B_20_3, poseidon2_B_21_0, poseidon2_B_21_1, poseidon2_B_21_2, poseidon2_B_21_3, poseidon2_B_22_0, poseidon2_B_22_1, poseidon2_B_22_2, poseidon2_B_22_3, poseidon2_B_23_0, poseidon2_B_23_1, poseidon2_B_23_2, poseidon2_B_23_3, poseidon2_B_24_0, poseidon2_B_24_1, poseidon2_B_24_2, poseidon2_B_24_3, poseidon2_B_25_0, poseidon2_B_25_1, poseidon2_B_25_2, poseidon2_B_25_3, poseidon2_B_26_0, poseidon2_B_26_1, poseidon2_B_26_2, poseidon2_B_26_3, poseidon2_B_27_0, poseidon2_B_27_1, poseidon2_B_27_2, poseidon2_B_27_3, poseidon2_B_28_0, poseidon2_B_28_1, poseidon2_B_28_2, poseidon2_B_28_3, poseidon2_B_29_0, poseidon2_B_29_1, poseidon2_B_29_2, poseidon2_B_29_3, poseidon2_B_30_0, poseidon2_B_30_1, poseidon2_B_30_2, poseidon2_B_30_3, poseidon2_B_31_0, poseidon2_B_31_1, poseidon2_B_31_2, poseidon2_B_31_3, poseidon2_B_32_0, poseidon2_B_32_1, poseidon2_B_32_2, poseidon2_B_32_3, poseidon2_B_33_0, poseidon2_B_33_1, poseidon2_B_33_2, poseidon2_B_33_3, poseidon2_B_34_0, poseidon2_B_34_1, poseidon2_B_34_2, poseidon2_B_34_3, poseidon2_B_35_0, poseidon2_B_35_1, poseidon2_B_35_2, poseidon2_B_35_3, poseidon2_B_36_0, poseidon2_B_36_1, poseidon2_B_36_2, poseidon2_B_36_3, poseidon2_B_37_0, poseidon2_B_37_1, poseidon2_B_37_2, poseidon2_B_37_3, poseidon2_B_38_0, poseidon2_B_38_1, poseidon2_B_38_2, poseidon2_B_38_3, poseidon2_B_39_0, poseidon2_B_39_1, poseidon2_B_39_2, poseidon2_B_39_3, poseidon2_B_40_0, poseidon2_B_40_1, poseidon2_B_40_2, poseidon2_B_40_3, poseidon2_B_41_0, poseidon2_B_41_1, poseidon2_B_41_2, poseidon2_B_41_3, poseidon2_B_42_0, poseidon2_B_42_1, poseidon2_B_42_2, poseidon2_B_42_3, poseidon2_B_43_0, poseidon2_B_43_1, poseidon2_B_43_2, poseidon2_B_43_3, poseidon2_B_44_0, poseidon2_B_44_1, poseidon2_B_44_2, poseidon2_B_44_3, poseidon2_B_45_0, poseidon2_B_45_1, poseidon2_B_45_2, poseidon2_B_45_3, poseidon2_B_46_0, poseidon2_B_46_1, poseidon2_B_46_2, poseidon2_B_46_3, poseidon2_B_47_0, poseidon2_B_47_1, poseidon2_B_47_2, poseidon2_B_47_3, poseidon2_B_48_0, poseidon2_B_48_1, poseidon2_B_48_2, poseidon2_B_48_3, poseidon2_B_49_0, poseidon2_B_49_1, poseidon2_B_49_2, poseidon2_B_49_3, poseidon2_B_4_0, poseidon2_B_4_1, poseidon2_B_4_2, poseidon2_B_4_3, poseidon2_B_50_0, poseidon2_B_50_1, poseidon2_B_50_2, poseidon2_B_50_3, poseidon2_B_51_0, poseidon2_B_51_1, poseidon2_B_51_2, poseidon2_B_51_3, poseidon2_B_52_0, poseidon2_B_52_1, poseidon2_B_52_2, poseidon2_B_52_3, poseidon2_B_53_0, poseidon2_B_53_1, poseidon2_B_53_2, poseidon2_B_53_3, poseidon2_B_54_0, poseidon2_B_54_1, poseidon2_B_54_2, poseidon2_B_54_3, poseidon2_B_55_0, poseidon2_B_55_1, poseidon2_B_55_2, poseidon2_B_55_3, poseidon2_B_56_0, poseidon2_B_56_1, poseidon2_B_56_2, poseidon2_B_56_3, poseidon2_B_57_0, poseidon2_B_57_1, poseidon2_B_57_2, poseidon2_B_57_3, poseidon2_B_58_0, poseidon2_B_58_1, poseidon2_B_58_2, poseidon2_B_58_3, poseidon2_B_59_0, poseidon2_B_59_1, poseidon2_B_59_2, poseidon2_B_59_3, poseidon2_B_5_0, poseidon2_B_5_1, poseidon2_B_5_2, poseidon2_B_5_3, poseidon2_B_6_0, poseidon2_B_6_1, poseidon2_B_6_2, poseidon2_B_6_3, poseidon2_B_7_0, poseidon2_B_7_1, poseidon2_B_7_2, poseidon2_B_7_3, poseidon2_B_8_0, poseidon2_B_8_1, poseidon2_B_8_2, poseidon2_B_8_3, poseidon2_B_9_0, poseidon2_B_9_1, poseidon2_B_9_2, poseidon2_B_9_3, poseidon2_EXT_LAYER_4, poseidon2_EXT_LAYER_5, poseidon2_EXT_LAYER_6, poseidon2_EXT_LAYER_7, poseidon2_T_0_4, poseidon2_T_0_5, poseidon2_T_0_6, poseidon2_T_0_7, poseidon2_T_1_4, poseidon2_T_1_5, poseidon2_T_1_6, poseidon2_T_1_7, poseidon2_T_2_4, poseidon2_T_2_5, poseidon2_T_2_6, poseidon2_T_2_7, poseidon2_T_3_4, poseidon2_T_3_5, poseidon2_T_3_6, poseidon2_T_3_7, poseidon2_T_60_4, poseidon2_T_60_5, poseidon2_T_60_6, poseidon2_T_60_7, poseidon2_T_61_4, poseidon2_T_61_5, poseidon2_T_61_6, poseidon2_T_61_7, poseidon2_T_62_4, poseidon2_T_62_5, poseidon2_T_62_6, poseidon2_T_62_7, poseidon2_T_63_4, poseidon2_T_63_5, poseidon2_T_63_6, poseidon2_T_63_7, poseidon2_a_0, poseidon2_a_1, poseidon2_a_2, poseidon2_a_3, poseidon2_b_0, poseidon2_b_1, poseidon2_b_2, poseidon2_b_3, poseidon2_clk, poseidon2_full_a_0, poseidon2_full_a_1, poseidon2_full_a_2, poseidon2_full_a_3, poseidon2_full_b_0, poseidon2_full_b_1, poseidon2_full_b_2, poseidon2_full_b_3, poseidon2_full_clk, poseidon2_full_end_poseidon, poseidon2_full_execute_poseidon_perm, poseidon2_full_input_0, poseidon2_full_input_1, poseidon2_full_input_2, poseidon2_full_input_len, poseidon2_full_num_perm_rounds_rem, poseidon2_full_num_perm_rounds_rem_inv, poseidon2_full_output, poseidon2_full_padding, poseidon2_full_sel_merkle_tree, poseidon2_full_sel_poseidon, poseidon2_full_start_poseidon, poseidon2_input_addr, poseidon2_mem_addr_read_a, poseidon2_mem_addr_read_b, poseidon2_mem_addr_read_c, poseidon2_mem_addr_read_d, poseidon2_mem_addr_write_a, poseidon2_mem_addr_write_b, poseidon2_mem_addr_write_c, poseidon2_mem_addr_write_d, poseidon2_output_addr, poseidon2_sel_poseidon_perm, poseidon2_sel_poseidon_perm_immediate, poseidon2_sel_poseidon_perm_mem_op, poseidon2_space_id, range_check_alu_rng_chk, range_check_clk, range_check_cmp_hi_bits_rng_chk, range_check_cmp_lo_bits_rng_chk, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_gas_da_rng_chk, range_check_gas_l2_rng_chk, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_rng_chk_bits, range_check_sel_lookup_0, range_check_sel_lookup_1, range_check_sel_lookup_2, range_check_sel_lookup_3, range_check_sel_lookup_4, range_check_sel_lookup_5, range_check_sel_lookup_6, range_check_sel_rng_chk, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, sha256_clk, sha256_input, sha256_output, sha256_sel_sha256_compression, sha256_state, slice_addr, slice_clk, slice_cnt, slice_col_offset, slice_one_min_inv, slice_sel_cd_cpy, slice_sel_mem_active, slice_sel_return, slice_sel_start, slice_space_id, slice_val, lookup_rng_chk_pow_2_counts, lookup_rng_chk_diff_counts, lookup_rng_chk_0_counts, lookup_rng_chk_1_counts, lookup_rng_chk_2_counts, lookup_rng_chk_3_counts, lookup_rng_chk_4_counts, lookup_rng_chk_5_counts, lookup_rng_chk_6_counts, lookup_rng_chk_7_counts, lookup_mem_rng_chk_0_counts, lookup_mem_rng_chk_1_counts, lookup_mem_rng_chk_2_counts, lookup_pow_2_0_counts, lookup_pow_2_1_counts, lookup_byte_lengths_counts, lookup_byte_operations_counts, lookup_opcode_gas_counts, lookup_l2_gas_rng_chk_0_counts, lookup_l2_gas_rng_chk_1_counts, lookup_da_gas_rng_chk_0_counts, lookup_da_gas_rng_chk_1_counts, kernel_output_lookup_counts, lookup_into_kernel_counts, lookup_cd_value_counts, lookup_ret_value_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts #define DERIVED_WITNESS_ENTITIES perm_rng_cmp_lo_inv, perm_rng_cmp_hi_inv, perm_rng_alu_inv, perm_cmp_alu_inv, perm_l2_start_gas_inv, perm_da_start_gas_inv, perm_l2_end_gas_inv, perm_da_end_gas_inv, perm_pos_mem_read_a_inv, perm_pos_mem_read_b_inv, perm_pos_mem_read_c_inv, perm_pos_mem_read_d_inv, perm_pos_mem_write_a_inv, perm_pos_mem_write_b_inv, perm_pos_mem_write_c_inv, perm_pos_mem_write_d_inv, perm_pos2_fixed_pos2_perm_inv, perm_slice_mem_inv, perm_merkle_poseidon2_inv, perm_main_alu_inv, perm_main_bin_inv, perm_main_conv_inv, perm_main_sha256_inv, perm_main_pos2_perm_inv, perm_main_slice_inv, perm_main_mem_a_inv, perm_main_mem_b_inv, perm_main_mem_c_inv, perm_main_mem_d_inv, perm_main_mem_ind_addr_a_inv, perm_main_mem_ind_addr_b_inv, perm_main_mem_ind_addr_c_inv, perm_main_mem_ind_addr_d_inv, lookup_rng_chk_pow_2_inv, lookup_rng_chk_diff_inv, lookup_rng_chk_0_inv, lookup_rng_chk_1_inv, lookup_rng_chk_2_inv, lookup_rng_chk_3_inv, lookup_rng_chk_4_inv, lookup_rng_chk_5_inv, lookup_rng_chk_6_inv, lookup_rng_chk_7_inv, lookup_mem_rng_chk_0_inv, lookup_mem_rng_chk_1_inv, lookup_mem_rng_chk_2_inv, lookup_pow_2_0_inv, lookup_pow_2_1_inv, lookup_byte_lengths_inv, lookup_byte_operations_inv, lookup_opcode_gas_inv, lookup_l2_gas_rng_chk_0_inv, lookup_l2_gas_rng_chk_1_inv, lookup_da_gas_rng_chk_0_inv, lookup_da_gas_rng_chk_1_inv, kernel_output_lookup_inv, lookup_into_kernel_inv, lookup_cd_value_inv, lookup_ret_value_inv, incl_main_tag_err_inv, incl_mem_tag_err_inv #define SHIFTED_ENTITIES binary_acc_ia_shift, binary_acc_ib_shift, binary_acc_ic_shift, binary_mem_tag_ctr_shift, binary_op_id_shift, cmp_a_hi_shift, cmp_a_lo_shift, cmp_b_hi_shift, cmp_b_lo_shift, cmp_cmp_rng_ctr_shift, cmp_op_gt_shift, cmp_p_sub_a_hi_shift, cmp_p_sub_a_lo_shift, cmp_p_sub_b_hi_shift, cmp_p_sub_b_lo_shift, cmp_sel_rng_chk_shift, main_da_gas_remaining_shift, main_emit_l2_to_l1_msg_write_offset_shift, main_emit_note_hash_write_offset_shift, main_emit_nullifier_write_offset_shift, main_emit_unencrypted_log_write_offset_shift, main_internal_return_ptr_shift, main_l1_to_l2_msg_exists_write_offset_shift, main_l2_gas_remaining_shift, main_note_hash_exist_write_offset_shift, main_nullifier_exists_write_offset_shift, main_nullifier_non_exists_write_offset_shift, main_pc_shift, main_sel_execution_end_shift, main_sel_execution_row_shift, main_sload_write_offset_shift, main_sstore_write_offset_shift, mem_glob_addr_shift, mem_rw_shift, mem_sel_mem_shift, mem_tag_shift, mem_tsp_shift, mem_val_shift, merkle_tree_leaf_index_shift, merkle_tree_leaf_value_shift, merkle_tree_path_len_shift, poseidon2_full_a_0_shift, poseidon2_full_a_1_shift, poseidon2_full_a_2_shift, poseidon2_full_a_3_shift, poseidon2_full_execute_poseidon_perm_shift, poseidon2_full_input_0_shift, poseidon2_full_input_1_shift, poseidon2_full_input_2_shift, poseidon2_full_num_perm_rounds_rem_shift, poseidon2_full_sel_poseidon_shift, poseidon2_full_start_poseidon_shift, slice_addr_shift, slice_clk_shift, slice_cnt_shift, slice_col_offset_shift, slice_sel_cd_cpy_shift, slice_sel_mem_active_shift, slice_sel_return_shift, slice_sel_start_shift, slice_space_id_shift #define TO_BE_SHIFTED(e) e.binary_acc_ia, e.binary_acc_ib, e.binary_acc_ic, e.binary_mem_tag_ctr, e.binary_op_id, e.cmp_a_hi, e.cmp_a_lo, e.cmp_b_hi, e.cmp_b_lo, e.cmp_cmp_rng_ctr, e.cmp_op_gt, e.cmp_p_sub_a_hi, e.cmp_p_sub_a_lo, e.cmp_p_sub_b_hi, e.cmp_p_sub_b_lo, e.cmp_sel_rng_chk, e.main_da_gas_remaining, e.main_emit_l2_to_l1_msg_write_offset, e.main_emit_note_hash_write_offset, e.main_emit_nullifier_write_offset, e.main_emit_unencrypted_log_write_offset, e.main_internal_return_ptr, e.main_l1_to_l2_msg_exists_write_offset, e.main_l2_gas_remaining, e.main_note_hash_exist_write_offset, e.main_nullifier_exists_write_offset, e.main_nullifier_non_exists_write_offset, e.main_pc, e.main_sel_execution_end, e.main_sel_execution_row, e.main_sload_write_offset, e.main_sstore_write_offset, e.mem_glob_addr, e.mem_rw, e.mem_sel_mem, e.mem_tag, e.mem_tsp, e.mem_val, e.merkle_tree_leaf_index, e.merkle_tree_leaf_value, e.merkle_tree_path_len, e.poseidon2_full_a_0, e.poseidon2_full_a_1, e.poseidon2_full_a_2, e.poseidon2_full_a_3, e.poseidon2_full_execute_poseidon_perm, e.poseidon2_full_input_0, e.poseidon2_full_input_1, e.poseidon2_full_input_2, e.poseidon2_full_num_perm_rounds_rem, e.poseidon2_full_sel_poseidon, e.poseidon2_full_start_poseidon, e.slice_addr, e.slice_clk, e.slice_cnt, e.slice_col_offset, e.slice_sel_cd_cpy, e.slice_sel_mem_active, e.slice_sel_return, e.slice_sel_start, e.slice_space_id @@ -131,12 +131,12 @@ class AvmFlavor { static constexpr bool HasZK = false; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 21; - static constexpr size_t NUM_WITNESS_ENTITIES = 762; + static constexpr size_t NUM_WITNESS_ENTITIES = 763; static constexpr size_t NUM_SHIFTED_ENTITIES = 61; static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES; // We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for // the unshifted and one for the shifted - static constexpr size_t NUM_ALL_ENTITIES = 844; + static constexpr size_t NUM_ALL_ENTITIES = 845; // The total number of witnesses including shifts and derived entities. static constexpr size_t NUM_ALL_WITNESS_ENTITIES = NUM_WITNESS_ENTITIES + NUM_SHIFTED_ENTITIES; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.cpp index fe3bcba4543..7da7e623f3d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.cpp @@ -239,6 +239,7 @@ template std::vector AvmFullRow::names() "main_sel_op_cast", "main_sel_op_chain_id", "main_sel_op_dagasleft", + "main_sel_op_debug_log", "main_sel_op_div", "main_sel_op_ecadd", "main_sel_op_emit_l2_to_l1_msg", @@ -1027,6 +1028,7 @@ template RefVector AvmFullRow::as_vector() const main_sel_op_cast, main_sel_op_chain_id, main_sel_op_dagasleft, + main_sel_op_debug_log, main_sel_op_div, main_sel_op_ecadd, main_sel_op_emit_l2_to_l1_msg, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.hpp index 8b7d8a6390e..42dd696e1b7 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.hpp @@ -230,6 +230,7 @@ template struct AvmFullRow { FF main_sel_op_cast{}; FF main_sel_op_chain_id{}; FF main_sel_op_dagasleft{}; + FF main_sel_op_debug_log{}; FF main_sel_op_div{}; FF main_sel_op_ecadd{}; FF main_sel_op_emit_l2_to_l1_msg{}; @@ -797,7 +798,7 @@ template struct AvmFullRow { RefVector as_vector() const; static std::vector names(); - static constexpr size_t SIZE = 783; + static constexpr size_t SIZE = 784; }; template std::ostream& operator<<(std::ostream& os, AvmFullRow const& row); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/kernel.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/kernel.hpp index a18277a8633..efc5b9f621b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/kernel.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/kernel.hpp @@ -12,7 +12,7 @@ template class kernelImpl { static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4 }; template void static accumulate(ContainerOverSubrelations& evals, @@ -364,7 +364,8 @@ template class kernelImpl { } { using Accumulator = typename std::tuple_element_t<41, ContainerOverSubrelations>; - auto tmp = (main_KERNEL_OUTPUT_SELECTORS * (FF(1) - new_term.main_sel_q_kernel_output_lookup)); + auto tmp = ((main_KERNEL_OUTPUT_SELECTORS * (FF(1) - new_term.main_sel_q_kernel_output_lookup)) * + (FF(1) - new_term.main_op_err)); tmp *= scaling_factor; std::get<41>(evals) += typename Accumulator::View(tmp); } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp index 4278b2cbb29..841dfc71ba6 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp @@ -10,11 +10,11 @@ template class mainImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { - 2, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, 3, 3, 3, 3, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 4, 4, 3, 3, 3, 3, 4, 3, 3, 3, 3, 4, 2, 2 + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { + 2, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, 3, 3, 3, 3, 4, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 2, 3 }; template @@ -72,18 +72,20 @@ template class mainImpl { new_term.main_sel_op_ecadd) + new_term.main_sel_op_msm); const auto main_SEL_ALL_MEMORY = (new_term.main_sel_op_mov + new_term.main_sel_op_set); - const auto main_OPCODE_SELECTORS = ((((((((((((new_term.main_sel_op_fdiv + new_term.main_sel_op_calldata_copy) + - new_term.main_sel_op_get_contract_instance) + - new_term.main_sel_op_returndata_size) + - new_term.main_sel_op_returndata_copy) + - main_SEL_ALL_ALU) + - main_SEL_ALL_BINARY) + - main_SEL_ALL_MEMORY) + - main_SEL_ALL_GADGET) + - main_KERNEL_INPUT_SELECTORS) + - main_KERNEL_OUTPUT_SELECTORS) + - main_SEL_ALL_LEFTGAS) + - main_SEL_ALL_CTRL_FLOW); + const auto main_OPCODE_SELECTORS = + (((((((((((((new_term.main_sel_op_fdiv + new_term.main_sel_op_calldata_copy) + + new_term.main_sel_op_get_contract_instance) + + new_term.main_sel_op_returndata_size) + + new_term.main_sel_op_returndata_copy) + + new_term.main_sel_op_debug_log) + + main_SEL_ALL_ALU) + + main_SEL_ALL_BINARY) + + main_SEL_ALL_MEMORY) + + main_SEL_ALL_GADGET) + + main_KERNEL_INPUT_SELECTORS) + + main_KERNEL_OUTPUT_SELECTORS) + + main_SEL_ALL_LEFTGAS) + + main_SEL_ALL_CTRL_FLOW); const auto main_CUR_AND_NEXT_ARE_MAIN = (new_term.main_sel_execution_row * new_term.main_sel_execution_row_shift); @@ -249,540 +251,544 @@ template class mainImpl { } { using Accumulator = typename std::tuple_element_t<26, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_radix_be * (FF(1) - new_term.main_sel_op_radix_be)); + auto tmp = (new_term.main_sel_op_debug_log * (FF(1) - new_term.main_sel_op_debug_log)); tmp *= scaling_factor; std::get<26>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<27, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_sha256 * (FF(1) - new_term.main_sel_op_sha256)); + auto tmp = (new_term.main_sel_op_radix_be * (FF(1) - new_term.main_sel_op_radix_be)); tmp *= scaling_factor; std::get<27>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<28, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_poseidon2 * (FF(1) - new_term.main_sel_op_poseidon2)); + auto tmp = (new_term.main_sel_op_sha256 * (FF(1) - new_term.main_sel_op_sha256)); tmp *= scaling_factor; std::get<28>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<29, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_keccak * (FF(1) - new_term.main_sel_op_keccak)); + auto tmp = (new_term.main_sel_op_poseidon2 * (FF(1) - new_term.main_sel_op_poseidon2)); tmp *= scaling_factor; std::get<29>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<30, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_ecadd * (FF(1) - new_term.main_sel_op_ecadd)); + auto tmp = (new_term.main_sel_op_keccak * (FF(1) - new_term.main_sel_op_keccak)); tmp *= scaling_factor; std::get<30>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<31, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_msm * (FF(1) - new_term.main_sel_op_msm)); + auto tmp = (new_term.main_sel_op_ecadd * (FF(1) - new_term.main_sel_op_ecadd)); tmp *= scaling_factor; std::get<31>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<32, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_add * (FF(1) - new_term.main_sel_op_add)); + auto tmp = (new_term.main_sel_op_msm * (FF(1) - new_term.main_sel_op_msm)); tmp *= scaling_factor; std::get<32>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<33, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_sub * (FF(1) - new_term.main_sel_op_sub)); + auto tmp = (new_term.main_sel_op_add * (FF(1) - new_term.main_sel_op_add)); tmp *= scaling_factor; std::get<33>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<34, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_mul * (FF(1) - new_term.main_sel_op_mul)); + auto tmp = (new_term.main_sel_op_sub * (FF(1) - new_term.main_sel_op_sub)); tmp *= scaling_factor; std::get<34>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<35, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_div * (FF(1) - new_term.main_sel_op_div)); + auto tmp = (new_term.main_sel_op_mul * (FF(1) - new_term.main_sel_op_mul)); tmp *= scaling_factor; std::get<35>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<36, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_fdiv * (FF(1) - new_term.main_sel_op_fdiv)); + auto tmp = (new_term.main_sel_op_div * (FF(1) - new_term.main_sel_op_div)); tmp *= scaling_factor; std::get<36>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<37, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_not * (FF(1) - new_term.main_sel_op_not)); + auto tmp = (new_term.main_sel_op_fdiv * (FF(1) - new_term.main_sel_op_fdiv)); tmp *= scaling_factor; std::get<37>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<38, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_eq * (FF(1) - new_term.main_sel_op_eq)); + auto tmp = (new_term.main_sel_op_not * (FF(1) - new_term.main_sel_op_not)); tmp *= scaling_factor; std::get<38>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<39, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_and * (FF(1) - new_term.main_sel_op_and)); + auto tmp = (new_term.main_sel_op_eq * (FF(1) - new_term.main_sel_op_eq)); tmp *= scaling_factor; std::get<39>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<40, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_or * (FF(1) - new_term.main_sel_op_or)); + auto tmp = (new_term.main_sel_op_and * (FF(1) - new_term.main_sel_op_and)); tmp *= scaling_factor; std::get<40>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<41, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_xor * (FF(1) - new_term.main_sel_op_xor)); + auto tmp = (new_term.main_sel_op_or * (FF(1) - new_term.main_sel_op_or)); tmp *= scaling_factor; std::get<41>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<42, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_cast * (FF(1) - new_term.main_sel_op_cast)); + auto tmp = (new_term.main_sel_op_xor * (FF(1) - new_term.main_sel_op_xor)); tmp *= scaling_factor; std::get<42>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<43, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_lt * (FF(1) - new_term.main_sel_op_lt)); + auto tmp = (new_term.main_sel_op_cast * (FF(1) - new_term.main_sel_op_cast)); tmp *= scaling_factor; std::get<43>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<44, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_lte * (FF(1) - new_term.main_sel_op_lte)); + auto tmp = (new_term.main_sel_op_lt * (FF(1) - new_term.main_sel_op_lt)); tmp *= scaling_factor; std::get<44>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<45, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_shl * (FF(1) - new_term.main_sel_op_shl)); + auto tmp = (new_term.main_sel_op_lte * (FF(1) - new_term.main_sel_op_lte)); tmp *= scaling_factor; std::get<45>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<46, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_shr * (FF(1) - new_term.main_sel_op_shr)); + auto tmp = (new_term.main_sel_op_shl * (FF(1) - new_term.main_sel_op_shl)); tmp *= scaling_factor; std::get<46>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<47, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_call * (FF(1) - new_term.main_sel_op_internal_call)); + auto tmp = (new_term.main_sel_op_shr * (FF(1) - new_term.main_sel_op_shr)); tmp *= scaling_factor; std::get<47>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<48, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_return * (FF(1) - new_term.main_sel_op_internal_return)); + auto tmp = (new_term.main_sel_op_internal_call * (FF(1) - new_term.main_sel_op_internal_call)); tmp *= scaling_factor; std::get<48>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<49, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_jump * (FF(1) - new_term.main_sel_op_jump)); + auto tmp = (new_term.main_sel_op_internal_return * (FF(1) - new_term.main_sel_op_internal_return)); tmp *= scaling_factor; std::get<49>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<50, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_jumpi * (FF(1) - new_term.main_sel_op_jumpi)); + auto tmp = (new_term.main_sel_op_jump * (FF(1) - new_term.main_sel_op_jump)); tmp *= scaling_factor; std::get<50>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<51, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_external_call * (FF(1) - new_term.main_sel_op_external_call)); + auto tmp = (new_term.main_sel_op_jumpi * (FF(1) - new_term.main_sel_op_jumpi)); tmp *= scaling_factor; std::get<51>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<52, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_static_call * (FF(1) - new_term.main_sel_op_static_call)); + auto tmp = (new_term.main_sel_op_external_call * (FF(1) - new_term.main_sel_op_external_call)); tmp *= scaling_factor; std::get<52>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<53, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_calldata_copy * (FF(1) - new_term.main_sel_op_calldata_copy)); + auto tmp = (new_term.main_sel_op_static_call * (FF(1) - new_term.main_sel_op_static_call)); tmp *= scaling_factor; std::get<53>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<54, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_returndata_size * (FF(1) - new_term.main_sel_op_returndata_size)); + auto tmp = (new_term.main_sel_op_calldata_copy * (FF(1) - new_term.main_sel_op_calldata_copy)); tmp *= scaling_factor; std::get<54>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<55, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_returndata_copy * (FF(1) - new_term.main_sel_op_returndata_copy)); + auto tmp = (new_term.main_sel_op_returndata_size * (FF(1) - new_term.main_sel_op_returndata_size)); tmp *= scaling_factor; std::get<55>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<56, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_external_return * (FF(1) - new_term.main_sel_op_external_return)); + auto tmp = (new_term.main_sel_op_returndata_copy * (FF(1) - new_term.main_sel_op_returndata_copy)); tmp *= scaling_factor; std::get<56>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<57, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_external_revert * (FF(1) - new_term.main_sel_op_external_revert)); + auto tmp = (new_term.main_sel_op_external_return * (FF(1) - new_term.main_sel_op_external_return)); tmp *= scaling_factor; std::get<57>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<58, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_set * (FF(1) - new_term.main_sel_op_set)); + auto tmp = (new_term.main_sel_op_external_revert * (FF(1) - new_term.main_sel_op_external_revert)); tmp *= scaling_factor; std::get<58>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<59, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_mov * (FF(1) - new_term.main_sel_op_mov)); + auto tmp = (new_term.main_sel_op_set * (FF(1) - new_term.main_sel_op_set)); tmp *= scaling_factor; std::get<59>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<60, ContainerOverSubrelations>; - auto tmp = (new_term.main_op_err * (FF(1) - new_term.main_op_err)); + auto tmp = (new_term.main_sel_op_mov * (FF(1) - new_term.main_sel_op_mov)); tmp *= scaling_factor; std::get<60>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<61, ContainerOverSubrelations>; - auto tmp = (new_term.main_tag_err * (FF(1) - new_term.main_tag_err)); + auto tmp = (new_term.main_op_err * (FF(1) - new_term.main_op_err)); tmp *= scaling_factor; std::get<61>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<62, ContainerOverSubrelations>; - auto tmp = (new_term.main_id_zero * (FF(1) - new_term.main_id_zero)); + auto tmp = (new_term.main_tag_err * (FF(1) - new_term.main_tag_err)); tmp *= scaling_factor; std::get<62>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<63, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_mem_op_a * (FF(1) - new_term.main_sel_mem_op_a)); + auto tmp = (new_term.main_id_zero * (FF(1) - new_term.main_id_zero)); tmp *= scaling_factor; std::get<63>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<64, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_mem_op_b * (FF(1) - new_term.main_sel_mem_op_b)); + auto tmp = (new_term.main_sel_mem_op_a * (FF(1) - new_term.main_sel_mem_op_a)); tmp *= scaling_factor; std::get<64>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<65, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_mem_op_c * (FF(1) - new_term.main_sel_mem_op_c)); + auto tmp = (new_term.main_sel_mem_op_b * (FF(1) - new_term.main_sel_mem_op_b)); tmp *= scaling_factor; std::get<65>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<66, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_mem_op_d * (FF(1) - new_term.main_sel_mem_op_d)); + auto tmp = (new_term.main_sel_mem_op_c * (FF(1) - new_term.main_sel_mem_op_c)); tmp *= scaling_factor; std::get<66>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<67, ContainerOverSubrelations>; - auto tmp = (new_term.main_rwa * (FF(1) - new_term.main_rwa)); + auto tmp = (new_term.main_sel_mem_op_d * (FF(1) - new_term.main_sel_mem_op_d)); tmp *= scaling_factor; std::get<67>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<68, ContainerOverSubrelations>; - auto tmp = (new_term.main_rwb * (FF(1) - new_term.main_rwb)); + auto tmp = (new_term.main_rwa * (FF(1) - new_term.main_rwa)); tmp *= scaling_factor; std::get<68>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<69, ContainerOverSubrelations>; - auto tmp = (new_term.main_rwc * (FF(1) - new_term.main_rwc)); + auto tmp = (new_term.main_rwb * (FF(1) - new_term.main_rwb)); tmp *= scaling_factor; std::get<69>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<70, ContainerOverSubrelations>; - auto tmp = (new_term.main_rwd * (FF(1) - new_term.main_rwd)); + auto tmp = (new_term.main_rwc * (FF(1) - new_term.main_rwc)); tmp *= scaling_factor; std::get<70>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<71, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_resolve_ind_addr_a * (FF(1) - new_term.main_sel_resolve_ind_addr_a)); + auto tmp = (new_term.main_rwd * (FF(1) - new_term.main_rwd)); tmp *= scaling_factor; std::get<71>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<72, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_resolve_ind_addr_b * (FF(1) - new_term.main_sel_resolve_ind_addr_b)); + auto tmp = (new_term.main_sel_resolve_ind_addr_a * (FF(1) - new_term.main_sel_resolve_ind_addr_a)); tmp *= scaling_factor; std::get<72>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<73, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_resolve_ind_addr_c * (FF(1) - new_term.main_sel_resolve_ind_addr_c)); + auto tmp = (new_term.main_sel_resolve_ind_addr_b * (FF(1) - new_term.main_sel_resolve_ind_addr_b)); tmp *= scaling_factor; std::get<73>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<74, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_resolve_ind_addr_d * (FF(1) - new_term.main_sel_resolve_ind_addr_d)); + auto tmp = (new_term.main_sel_resolve_ind_addr_c * (FF(1) - new_term.main_sel_resolve_ind_addr_c)); tmp *= scaling_factor; std::get<74>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<75, ContainerOverSubrelations>; - auto tmp = (((new_term.main_sel_op_eq + new_term.main_sel_op_lte) + new_term.main_sel_op_lt) * - (new_term.main_w_in_tag - constants_MEM_TAG_U1)); + auto tmp = (new_term.main_sel_resolve_ind_addr_d * (FF(1) - new_term.main_sel_resolve_ind_addr_d)); tmp *= scaling_factor; std::get<75>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<76, ContainerOverSubrelations>; - auto tmp = ((new_term.main_sel_op_fdiv * (FF(1) - new_term.main_op_err)) * - ((new_term.main_ic * new_term.main_ib) - new_term.main_ia)); + auto tmp = (((new_term.main_sel_op_eq + new_term.main_sel_op_lte) + new_term.main_sel_op_lt) * + (new_term.main_w_in_tag - constants_MEM_TAG_U1)); tmp *= scaling_factor; std::get<76>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<77, ContainerOverSubrelations>; - auto tmp = ((new_term.main_sel_op_fdiv + new_term.main_sel_op_div) * - (((new_term.main_ib * new_term.main_inv) - FF(1)) + new_term.main_op_err)); + auto tmp = ((new_term.main_sel_op_fdiv * (FF(1) - new_term.main_op_err)) * + ((new_term.main_ic * new_term.main_ib) - new_term.main_ia)); tmp *= scaling_factor; std::get<77>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<78, ContainerOverSubrelations>; - auto tmp = (((new_term.main_sel_op_fdiv + new_term.main_sel_op_div) * new_term.main_op_err) * - (FF(1) - new_term.main_inv)); + auto tmp = ((new_term.main_sel_op_fdiv + new_term.main_sel_op_div) * + (((new_term.main_ib * new_term.main_inv) - FF(1)) + new_term.main_op_err)); tmp *= scaling_factor; std::get<78>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<79, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_fdiv * (new_term.main_r_in_tag - constants_MEM_TAG_FF)); + auto tmp = (((new_term.main_sel_op_fdiv + new_term.main_sel_op_div) * new_term.main_op_err) * + (FF(1) - new_term.main_inv)); tmp *= scaling_factor; std::get<79>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<80, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_fdiv * (new_term.main_w_in_tag - constants_MEM_TAG_FF)); + auto tmp = (new_term.main_sel_op_fdiv * (new_term.main_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<80>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<81, ContainerOverSubrelations>; - auto tmp = (new_term.main_op_err * (((new_term.main_sel_op_fdiv + new_term.main_sel_op_div) + - new_term.main_sel_op_get_contract_instance) - - FF(1))); + auto tmp = (new_term.main_sel_op_fdiv * (new_term.main_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<81>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<82, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_jump * (new_term.main_pc_shift - new_term.main_ia)); + auto tmp = (new_term.main_tag_err * (FF(1) - new_term.main_op_err)); tmp *= scaling_factor; std::get<82>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<83, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_jumpi * - (((FF(1) - new_term.main_id_zero) * (new_term.main_pc_shift - new_term.main_ia)) + - (new_term.main_id_zero * ((new_term.main_pc_shift - new_term.main_pc) - FF(8))))); + auto tmp = (new_term.main_sel_op_jump * (new_term.main_pc_shift - new_term.main_ia)); tmp *= scaling_factor; std::get<83>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<84, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_call * - (new_term.main_internal_return_ptr_shift - (new_term.main_internal_return_ptr + FF(1)))); + auto tmp = (new_term.main_sel_op_jumpi * + (((FF(1) - new_term.main_id_zero) * (new_term.main_pc_shift - new_term.main_ia)) + + (new_term.main_id_zero * ((new_term.main_pc_shift - new_term.main_pc) - FF(8))))); tmp *= scaling_factor; std::get<84>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<85, ContainerOverSubrelations>; - auto tmp = - (new_term.main_sel_op_internal_call * (new_term.main_internal_return_ptr - new_term.main_mem_addr_b)); + auto tmp = (new_term.main_sel_op_internal_call * + (new_term.main_internal_return_ptr_shift - (new_term.main_internal_return_ptr + FF(1)))); tmp *= scaling_factor; std::get<85>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<86, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_call * (new_term.main_pc_shift - new_term.main_ia)); + auto tmp = + (new_term.main_sel_op_internal_call * (new_term.main_internal_return_ptr - new_term.main_mem_addr_b)); tmp *= scaling_factor; std::get<86>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<87, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_call * ((new_term.main_pc + FF(5)) - new_term.main_ib)); + auto tmp = (new_term.main_sel_op_internal_call * (new_term.main_pc_shift - new_term.main_ia)); tmp *= scaling_factor; std::get<87>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<88, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_call * (new_term.main_rwb - FF(1))); + auto tmp = (new_term.main_sel_op_internal_call * ((new_term.main_pc + FF(5)) - new_term.main_ib)); tmp *= scaling_factor; std::get<88>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<89, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_call * (new_term.main_sel_mem_op_b - FF(1))); + auto tmp = (new_term.main_sel_op_internal_call * (new_term.main_rwb - FF(1))); tmp *= scaling_factor; std::get<89>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<90, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_return * - (new_term.main_internal_return_ptr_shift - (new_term.main_internal_return_ptr - FF(1)))); + auto tmp = (new_term.main_sel_op_internal_call * (new_term.main_sel_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<90>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<91, ContainerOverSubrelations>; auto tmp = (new_term.main_sel_op_internal_return * - ((new_term.main_internal_return_ptr - FF(1)) - new_term.main_mem_addr_a)); + (new_term.main_internal_return_ptr_shift - (new_term.main_internal_return_ptr - FF(1)))); tmp *= scaling_factor; std::get<91>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<92, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_return * (new_term.main_pc_shift - new_term.main_ia)); + auto tmp = (new_term.main_sel_op_internal_return * + ((new_term.main_internal_return_ptr - FF(1)) - new_term.main_mem_addr_a)); tmp *= scaling_factor; std::get<92>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<93, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_return * new_term.main_rwa); + auto tmp = (new_term.main_sel_op_internal_return * (new_term.main_pc_shift - new_term.main_ia)); tmp *= scaling_factor; std::get<93>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<94, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_internal_return * (new_term.main_sel_mem_op_a - FF(1))); + auto tmp = (new_term.main_sel_op_internal_return * new_term.main_rwa); tmp *= scaling_factor; std::get<94>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<95, ContainerOverSubrelations>; - auto tmp = ((main_CUR_AND_NEXT_ARE_MAIN * (FF(1) - main_SEL_ALL_CTRL_FLOW)) * - (new_term.main_internal_return_ptr_shift - new_term.main_internal_return_ptr)); + auto tmp = (new_term.main_sel_op_internal_return * (new_term.main_sel_mem_op_a - FF(1))); tmp *= scaling_factor; std::get<95>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<96, ContainerOverSubrelations>; - auto tmp = ((new_term.main_sel_op_internal_call + new_term.main_sel_op_internal_return) * - (new_term.main_space_id - constants_misc_INTERNAL_CALL_SPACE_ID)); + auto tmp = ((main_CUR_AND_NEXT_ARE_MAIN * (FF(1) - main_SEL_ALL_CTRL_FLOW)) * + (new_term.main_internal_return_ptr_shift - new_term.main_internal_return_ptr)); tmp *= scaling_factor; std::get<96>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<97, ContainerOverSubrelations>; - auto tmp = (((FF(1) - new_term.main_sel_op_internal_call) - new_term.main_sel_op_internal_return) * - (new_term.main_call_ptr - new_term.main_space_id)); + auto tmp = ((new_term.main_sel_op_internal_call + new_term.main_sel_op_internal_return) * + (new_term.main_space_id - constants_misc_INTERNAL_CALL_SPACE_ID)); tmp *= scaling_factor; std::get<97>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<98, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_jumpi * - (((new_term.main_id * new_term.main_inv) - FF(1)) + new_term.main_id_zero)); + auto tmp = (((FF(1) - new_term.main_sel_op_internal_call) - new_term.main_sel_op_internal_return) * + (new_term.main_call_ptr - new_term.main_space_id)); tmp *= scaling_factor; std::get<98>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<99, ContainerOverSubrelations>; - auto tmp = ((new_term.main_sel_op_jumpi * new_term.main_id_zero) * (FF(1) - new_term.main_inv)); + auto tmp = (new_term.main_sel_op_jumpi * + (((new_term.main_id * new_term.main_inv) - FF(1)) + new_term.main_id_zero)); tmp *= scaling_factor; std::get<99>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<100, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_mov_ia_to_ic - (new_term.main_sel_op_mov * (FF(1) - new_term.main_id_zero))); + auto tmp = ((new_term.main_sel_op_jumpi * new_term.main_id_zero) * (FF(1) - new_term.main_inv)); tmp *= scaling_factor; std::get<100>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<101, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_mov_ia_to_ic * (new_term.main_ia - new_term.main_ic)); + auto tmp = (new_term.main_sel_mov_ia_to_ic - (new_term.main_sel_op_mov * (FF(1) - new_term.main_id_zero))); tmp *= scaling_factor; std::get<101>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<102, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_mov_ib_to_ic * (new_term.main_ib - new_term.main_ic)); + auto tmp = (new_term.main_sel_mov_ia_to_ic * (new_term.main_ia - new_term.main_ic)); tmp *= scaling_factor; std::get<102>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<103, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_mov * (new_term.main_r_in_tag - new_term.main_w_in_tag)); + auto tmp = (new_term.main_sel_mov_ib_to_ic * (new_term.main_ib - new_term.main_ic)); tmp *= scaling_factor; std::get<103>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<104, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_alu - - ((main_SEL_ALL_ALU * (FF(1) - new_term.main_tag_err)) * (FF(1) - new_term.main_op_err))); + auto tmp = (new_term.main_sel_op_mov * (new_term.main_r_in_tag - new_term.main_w_in_tag)); tmp *= scaling_factor; std::get<104>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<105, ContainerOverSubrelations>; - auto tmp = (main_SEL_ALU_R_TAG * (new_term.main_alu_in_tag - new_term.main_r_in_tag)); + auto tmp = (new_term.main_sel_alu - (main_SEL_ALL_ALU * (FF(1) - new_term.main_op_err))); tmp *= scaling_factor; std::get<105>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<106, ContainerOverSubrelations>; - auto tmp = (main_SEL_ALU_W_TAG * (new_term.main_alu_in_tag - new_term.main_w_in_tag)); + auto tmp = (main_SEL_ALU_R_TAG * (new_term.main_alu_in_tag - new_term.main_r_in_tag)); tmp *= scaling_factor; std::get<106>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<107, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_l2gasleft * (new_term.main_ia - new_term.main_l2_gas_remaining_shift)); + auto tmp = (main_SEL_ALU_W_TAG * (new_term.main_alu_in_tag - new_term.main_w_in_tag)); tmp *= scaling_factor; std::get<107>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<108, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_dagasleft * (new_term.main_ia - new_term.main_da_gas_remaining_shift)); + auto tmp = (new_term.main_sel_op_l2gasleft * (new_term.main_ia - new_term.main_l2_gas_remaining_shift)); tmp *= scaling_factor; std::get<108>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<109, ContainerOverSubrelations>; - auto tmp = ((new_term.main_ib * (FF(1) - new_term.main_tag_err)) * - ((new_term.main_sel_op_calldata_copy + new_term.main_sel_op_external_return) - - new_term.main_sel_slice_gadget)); + auto tmp = (new_term.main_sel_op_dagasleft * (new_term.main_ia - new_term.main_da_gas_remaining_shift)); tmp *= scaling_factor; std::get<109>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<110, ContainerOverSubrelations>; - auto tmp = (new_term.main_bin_op_id - (new_term.main_sel_op_or + (FF(2) * new_term.main_sel_op_xor))); + auto tmp = ((new_term.main_ib * (FF(1) - new_term.main_op_err)) * + ((new_term.main_sel_op_calldata_copy + new_term.main_sel_op_external_return) - + new_term.main_sel_slice_gadget)); tmp *= scaling_factor; std::get<110>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<111, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_bin - - ((new_term.main_sel_op_and + new_term.main_sel_op_or) + new_term.main_sel_op_xor)); + auto tmp = (new_term.main_bin_op_id - (new_term.main_sel_op_or + (FF(2) * new_term.main_sel_op_xor))); tmp *= scaling_factor; std::get<111>(evals) += typename Accumulator::View(tmp); } + { + using Accumulator = typename std::tuple_element_t<112, ContainerOverSubrelations>; + auto tmp = (new_term.main_sel_bin - + (((new_term.main_sel_op_and + new_term.main_sel_op_or) + new_term.main_sel_op_xor) * + (FF(1) - new_term.main_op_err))); + tmp *= scaling_factor; + std::get<112>(evals) += typename Accumulator::View(tmp); + } } }; @@ -795,51 +801,51 @@ template class main : public Relation> { switch (index) { case 0: return "OPCODE_SELECTORS"; - case 75: - return "OUTPUT_U1"; case 76: - return "SUBOP_FDIV"; + return "OUTPUT_U1"; case 77: - return "SUBOP_FDIV_ZERO_ERR1"; + return "SUBOP_FDIV"; case 78: - return "SUBOP_FDIV_ZERO_ERR2"; + return "SUBOP_FDIV_ZERO_ERR1"; case 79: - return "SUBOP_FDIV_R_IN_TAG_FF"; + return "SUBOP_FDIV_ZERO_ERR2"; case 80: - return "SUBOP_FDIV_W_IN_TAG_FF"; + return "SUBOP_FDIV_R_IN_TAG_FF"; case 81: - return "SUBOP_ERROR_RELEVANT_OP"; + return "SUBOP_FDIV_W_IN_TAG_FF"; case 82: - return "PC_JUMP"; + return "TAG_ERR_IMPLIES_OP_ERR"; case 83: - return "PC_JUMPI"; + return "PC_JUMP"; case 84: + return "PC_JUMPI"; + case 85: return "RETURN_POINTER_INCREMENT"; - case 90: + case 91: return "RETURN_POINTER_DECREMENT"; - case 95: - return "INTERNAL_RETURN_POINTER_CONSISTENCY"; case 96: - return "SPACE_ID_INTERNAL"; + return "INTERNAL_RETURN_POINTER_CONSISTENCY"; case 97: - return "SPACE_ID_STANDARD_OPCODES"; + return "SPACE_ID_INTERNAL"; case 98: - return "JMP_CONDITION_RES_1"; + return "SPACE_ID_STANDARD_OPCODES"; case 99: + return "JMP_CONDITION_RES_1"; + case 100: return "JMP_CONDITION_RES_2"; - case 101: - return "MOV_SAME_VALUE_A"; case 102: - return "MOV_SAME_VALUE_B"; + return "MOV_SAME_VALUE_A"; case 103: + return "MOV_SAME_VALUE_B"; + case 104: return "MOV_MAIN_SAME_TAG"; - case 107: - return "L2GASLEFT"; case 108: + return "L2GASLEFT"; + case 109: return "DAGASLEFT"; - case 110: - return "BIN_SEL_1"; case 111: + return "BIN_SEL_1"; + case 112: return "BIN_SEL_2"; } return std::to_string(index); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp index 8ae8c6ba769..462bed25ff1 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp @@ -548,7 +548,7 @@ TEST_P(AvmBitwiseTestsShr, AllShrTest) const auto [operands, mem_tag] = GetParam(); const auto [a, b, output] = operands; trace_builder.op_set(0, a, 0, mem_tag); - trace_builder.op_set(0, b, 1, mem_tag); + trace_builder.op_set(0, b, 1, AvmMemoryTag::U8); trace_builder.op_shr(0, 0, 1, 2); trace_builder.op_set(0, 1, 100, AvmMemoryTag::U32); trace_builder.op_return(0, 2, 100); @@ -566,7 +566,7 @@ TEST_P(AvmBitwiseTestsShl, AllShlTest) const auto [operands, mem_tag] = GetParam(); const auto [a, b, output] = operands; trace_builder.op_set(0, a, 0, mem_tag); - trace_builder.op_set(0, b, 1, mem_tag); + trace_builder.op_set(0, b, 1, AvmMemoryTag::U8); trace_builder.op_shl(0, 0, 1, 2); trace_builder.op_set(0, 1, 100, AvmMemoryTag::U32); trace_builder.op_return(0, 2, 100); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp index 6dd3bdad82f..1dd11e5bf6c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp @@ -185,6 +185,7 @@ TEST_F(AvmCastTests, truncationFFToU16ModMinus1) trace_builder = AvmTraceBuilder(public_inputs, {}, 0, calldata) .set_full_precomputed_tables(false) .set_range_check_required(false); + trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32); trace_builder.op_set(0, 1, 1, AvmMemoryTag::U32); trace_builder.op_calldata_copy(0, 0, 1, 0); trace_builder.op_cast(0, 0, 1, AvmMemoryTag::U16); @@ -202,6 +203,7 @@ TEST_F(AvmCastTests, truncationFFToU16ModMinus2) trace_builder = AvmTraceBuilder(public_inputs, {}, 0, calldata) .set_full_precomputed_tables(false) .set_range_check_required(false); + trace_builder.op_set(0, 0, 0, AvmMemoryTag::U32); trace_builder.op_set(0, 1, 1, AvmMemoryTag::U32); trace_builder.op_calldata_copy(0, 0, 1, 0); trace_builder.op_cast(0, 0, 1, AvmMemoryTag::U16); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp index 47a2e0b24cd..c04ea043b62 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp @@ -258,6 +258,7 @@ TEST_F(AvmExecutionTests, setAndSubOpcodes) // the result at offset 1. TEST_F(AvmExecutionTests, powerWithMulOpcodes) { + const int NUM_MUL_ITERATIONS = 12; std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag + to_hex(AvmMemoryTag::U64) + @@ -286,7 +287,7 @@ TEST_F(AvmExecutionTests, powerWithMulOpcodes) "0000" // ret offset 0 "00FF"; // ret size offset 255 - for (int i = 0; i < 12; i++) { + for (int i = 0; i < NUM_MUL_ITERATIONS; i++) { bytecode_hex.append(mul_hex); } bytecode_hex.append(set_return_size_hex); @@ -307,7 +308,7 @@ TEST_F(AvmExecutionTests, powerWithMulOpcodes) VariantWith(1))))); // MUL last pos - EXPECT_THAT(instructions.at(13), + EXPECT_THAT(instructions.at(NUM_MUL_ITERATIONS + 1), AllOf(Field(&Instruction::op_code, OpCode::MUL_8), Field(&Instruction::operands, ElementsAre(VariantWith(0), @@ -316,7 +317,7 @@ TEST_F(AvmExecutionTests, powerWithMulOpcodes) VariantWith(1))))); // SET - EXPECT_THAT(instructions.at(14), + EXPECT_THAT(instructions.at(NUM_MUL_ITERATIONS + 2), AllOf(Field(&Instruction::op_code, OpCode::SET_8), Field(&Instruction::operands, ElementsAre(VariantWith(0), @@ -326,7 +327,7 @@ TEST_F(AvmExecutionTests, powerWithMulOpcodes) // RETURN EXPECT_THAT( - instructions.at(15), + instructions.at(NUM_MUL_ITERATIONS + 3), AllOf(Field(&Instruction::op_code, OpCode::RETURN), Field(&Instruction::operands, ElementsAre(VariantWith(0), VariantWith(0), VariantWith(255))))); @@ -334,13 +335,20 @@ TEST_F(AvmExecutionTests, powerWithMulOpcodes) auto trace = gen_trace_from_bytecode(bytecode); // Find the first row enabling the multiplication selector and pc of last multiplication - const auto last_mul_pc = - 2 * Deserialization::get_pc_increment(OpCode::SET_8) + 11 * Deserialization::get_pc_increment(OpCode::MUL_8); + const auto last_mul_pc = 2 * Deserialization::get_pc_increment(OpCode::SET_8) + + (NUM_MUL_ITERATIONS - 1) * Deserialization::get_pc_increment(OpCode::MUL_8); auto row = std::ranges::find_if(trace.begin(), trace.end(), [last_mul_pc](Row r) { return r.main_sel_op_mul == 1 && r.main_pc == last_mul_pc; }); - EXPECT_EQ(row->main_ic, 244140625); // 5^12 = 244140625 + + int result = 1; + // Compute 5 ^ NUM_MUL_ITERATIONS + for (int i = 0; i < NUM_MUL_ITERATIONS; i++) { + result *= 5; + } + + EXPECT_EQ(row->main_ic, result); validate_trace(std::move(trace), public_inputs); } @@ -1129,7 +1137,6 @@ TEST_F(AvmExecutionTests, poseidon2PermutationOpCode) // Positive test with Keccakf1600. TEST_F(AvmExecutionTests, keccakf1600OpCode) { - // Test vectors taken noir/noir-repo/acvm-repo/blackbox_solver/src/hash.rs std::vector state = { 0xF1258F7940E1DDE7LLU, 0x84D5CCF933C0478ALLU, 0xD598261EA65AA9EELLU, 0xBD1547306F80494DLLU, @@ -1209,14 +1216,14 @@ TEST_F(AvmExecutionTests, embeddedCurveAddOpCode) auto b_is_inf = b.is_point_at_infinity(); grumpkin::g1::affine_element res = a + b; auto expected_output = std::vector{ res.x, res.y, res.is_point_at_infinity() }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "00" // val - "00" // dst_offset - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "00" // val + "00" // dst_offset + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // "06" // val "01" // dst_offset + to_hex(OpCode::CALLDATACOPY) + // Calldatacopy @@ -1226,37 +1233,37 @@ TEST_F(AvmExecutionTests, embeddedCurveAddOpCode) "0000" // dst_offset + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 "00" // Indirect flag - + to_hex(AvmMemoryTag::U8) + - "02" // a_is_inf - "02" // a_is_inf - + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 - "00" // Indirect flag - + to_hex(AvmMemoryTag::U8) + - "05" // b_is_inf - "05" // b_is_inf - + to_hex(OpCode::SET_8) + // opcode SET for direct src_length - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "07" // value - "06" // dst_offset - + to_hex(OpCode::ECADD) + // opcode ECADD - "0040" // Indirect flag (sixth operand indirect) - "0000" // hash_index offset (direct) - "0001" // dest offset (direct) - "0002" // input offset (indirect) - "0003" // length offset (direct) - "0004" // length offset (direct) - "0005" // length offset (direct) - "0006" // length offset (direct) - + to_hex(OpCode::SET_16) + // opcode SET (for return size) - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "0003" // val: 3 - "0200" // dst_offset=512 - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "0007" // ret offset 3 - "0200"; // ret size offset 512 + + to_hex(AvmMemoryTag::U1) + // + "02" // a_is_inf + "02" // a_is_inf + + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 + "00" // Indirect flag + + to_hex(AvmMemoryTag::U1) + // + "05" // b_is_inf + "05" // b_is_inf + + to_hex(OpCode::SET_8) + // opcode SET for direct src_length + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "07" // value + "06" // dst_offset + + to_hex(OpCode::ECADD) + // opcode ECADD + "0040" // Indirect flag (sixth operand indirect) + "0000" // lhs_x_offset (direct) + "0001" // lhs_y_offset (direct) + "0002" // lhs_is_inf_offset (direct) + "0003" // rhs_x_offset (direct) + "0004" // rhs_y_offset (direct) + "0005" // rhs_is_inf_offset (direct) + "0006" // output_offset (indirect) and resolves to 7 + + to_hex(OpCode::SET_16) + // opcode SET (for return size) + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "0003" // val: 3 + "0200" // dst_offset=512 + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "0007" // ret offset 7 + "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse_bytecode_statically(bytecode); @@ -1291,16 +1298,17 @@ TEST_F(AvmExecutionTests, msmOpCode) // Send all the input as Fields and cast them to U8 later std::vector calldata = { FF(a.x), FF(a.y), a_is_inf, FF(b.x), FF(b.y), b_is_inf, scalar_a_lo, scalar_a_hi, scalar_b_lo, scalar_b_hi }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "00" // val - "00" // dst_offset - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "0A" // val - "01" + + + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "00" // val + "00" // dst_offset + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "0A" // val + "01" + // to_hex(OpCode::CALLDATACOPY) + // Calldatacopy "00" // Indirect flag "0000" // cd_offset 0 @@ -1308,49 +1316,49 @@ TEST_F(AvmExecutionTests, msmOpCode) "0000" // dst_offset 0 + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 "00" // Indirect flag - + to_hex(AvmMemoryTag::U8) + - "02" // a_is_inf - "02" // - + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 - "00" // Indirect flag - + to_hex(AvmMemoryTag::U8) + - "05" // b_is_inf - "05" // - + to_hex(OpCode::SET_8) + // opcode SET for length - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "06" // Length of point elements (6) - "0b" // dst offset (11) - + to_hex(OpCode::SET_8) + // SET Indirects - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "00" // points offset - "0d" // dst offset + - + to_hex(OpCode::SET_8) + // SET Indirects - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "06" // scalars offset - "0e" + // dst offset - to_hex(OpCode::SET_8) + // SET Indirects - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "0c" // output offset - "0f" + // dst offset - to_hex(OpCode::MSM) + // opcode MSM - "07" // Indirect flag (first 3 indirect) - "000d" // points offset - "000e" // scalars offset - "000f" // output offset - "000b" // length offset - + to_hex(OpCode::SET_16) + // opcode SET (for return size) - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "0003" // val: 3 - "0200" // dst_offset=512 - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "000c" // ret offset 12 (this overwrites) - "0200"; // ret size offset 512 + + to_hex(AvmMemoryTag::U1) + // + "02" // a_is_inf + "02" // + + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 + "00" // Indirect flag + + to_hex(AvmMemoryTag::U1) + // + "05" // b_is_inf + "05" // + + to_hex(OpCode::SET_8) + // opcode SET for length + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "06" // Length of point elements (6) + "0b" // dst offset (11) + + to_hex(OpCode::SET_8) + // SET Indirects + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "00" // points offset + "0d" // dst offset + + + to_hex(OpCode::SET_8) + // SET Indirects + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "06" // scalars offset + "0e" + // dst offset + to_hex(OpCode::SET_8) + // SET Indirects + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "0c" // output offset + "0f" + // dst offset + to_hex(OpCode::MSM) + // opcode MSM + "07" // Indirect flag (first 3 indirect) + "000d" // points offset + "000e" // scalars offset + "000f" // output offset + "000b" // length offset + + to_hex(OpCode::SET_16) + // opcode SET (for return size) + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "0003" // val: 3 + "0200" // dst_offset=512 + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "000c" // ret offset 12 (this overwrites) + "0200"; // ret size offset 512 auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse_bytecode_statically(bytecode); @@ -1791,6 +1799,11 @@ TEST_F(AvmExecutionTests, kernelOutputEmitOpcodes) { // Set values into the first register to emit std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode Set + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // tag U32 + "00" // value 0 + "02" // dst_offset 2 + + to_hex(OpCode::SET_8) + // opcode Set "00" // Indirect flag + to_hex(AvmMemoryTag::U32) + // tag U32 "01" // value 1 @@ -1822,7 +1835,7 @@ TEST_F(AvmExecutionTests, kernelOutputEmitOpcodes) auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse_bytecode_statically(bytecode); - ASSERT_THAT(instructions, SizeIs(7)); + ASSERT_THAT(instructions, SizeIs(8)); std::vector calldata = {}; std::vector returndata = {}; @@ -2235,6 +2248,7 @@ TEST_F(AvmExecutionTests, opCallOpcodes) // Calldata for l2_gas, da_gas, contract_address, nested_call_args (4 elements), std::vector calldata = { 17, 10, 34802342, 1, 2, 3, 4 }; std::string bytecode_preamble; + // Set up Gas offsets bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET for gas offset indirect "00" // Indirect flag @@ -2254,11 +2268,16 @@ TEST_F(AvmExecutionTests, opCallOpcodes) "03" // val 3 (the start of the args array) "13"; // dst_offset 19 // Set up args size offset - bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET for ret offset indirect + bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET for args size indirect "00" // Indirect flag + to_hex(AvmMemoryTag::U32) + - "04" // val 4 (the length of the args array) - "14"; // dst_offset 20 + "04" // val 4 - resolved address + "14"; // dst_offset 20 + bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + // + "00" // val 0 (args size) + "04"; // dst_offset 4 // Set up the ret offset bytecode_preamble += to_hex(OpCode::SET_16) + // opcode SET for ret offset indirect "00" // Indirect flag @@ -2266,7 +2285,7 @@ TEST_F(AvmExecutionTests, opCallOpcodes) "0100" // val 256 (the start of where to write the return data) "0015"; // dst_offset 21 // Set up the success offset - bytecode_preamble += to_hex(OpCode::SET_16) + // opcode SET for ret offset indirect + bytecode_preamble += to_hex(OpCode::SET_16) + // opcode SET for success offset indirect "00" // Indirect flag + to_hex(AvmMemoryTag::U32) + "0102" // val 258 (write the success flag at ret_offset + ret_size) @@ -2359,8 +2378,8 @@ TEST_F(AvmExecutionTests, opGetContractInstanceOpcode) std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - + to_hex(AvmMemoryTag::U8) + to_hex(address_byte) + // val - "01" // dst_offset 0 + + to_hex(AvmMemoryTag::FF) + to_hex(address_byte) + // val + "01" // dst_offset 1 + to_hex(OpCode::GETCONTRACTINSTANCE) + // opcode GETCONTRACTINSTANCE "00" // Indirect flag + to_hex(static_cast(ContractInstanceMember::DEPLOYER)) + // member enum diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp index 25d1b54ebc6..00857da903f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp @@ -450,9 +450,8 @@ FF AvmAluTraceBuilder::op_not(FF const& a, AvmMemoryTag in_tag, uint32_t const c */ FF AvmAluTraceBuilder::op_shl(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk) { - // TODO(9497): this should raise error flag in main trace, not assert - ASSERT(in_tag != AvmMemoryTag::FF); - // Check that the shifted amount is an 8-bit integer + // Check that the shifted amount is an 8-bit integer. + // Caller from trace.cpp ensures that the tag is U8. ASSERT(uint256_t(b) < 256); // Perform the shift operation over 256-bit integers @@ -513,9 +512,8 @@ FF AvmAluTraceBuilder::op_shl(FF const& a, FF const& b, AvmMemoryTag in_tag, uin */ FF AvmAluTraceBuilder::op_shr(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk) { - // TODO(9497): this should raise error flag in main trace, not assert - ASSERT(in_tag != AvmMemoryTag::FF); - // Check that the shifted amount is an 8-bit integer + // Check that the shifted amount is an 8-bit integer. + // Caller from trace.cpp ensures that the tag is U8. ASSERT(uint256_t(b) < 256); // Perform the shift operation over 256-bit integers diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp index fd5de470550..c8983191ec4 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp @@ -49,6 +49,16 @@ enum class AvmMemoryTag : uint32_t { static const uint32_t MAX_MEM_TAG = MEM_TAG_U128; +enum class AvmError : uint32_t { + NO_ERROR, + TAG_ERROR, + ADDR_RES_ERROR, + DIV_ZERO, + PARSING_ERROR, + ENV_VAR_UNKNOWN, + CONTRACT_INST_MEM_UNKNOWN +}; + static const size_t NUM_MEM_SPACES = 256; static const uint8_t INTERNAL_CALL_SPACE_ID = 255; static const uint32_t MAX_SIZE_INTERNAL_STACK = 1 << 16; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp index 0a8c36751b1..71385470d45 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp @@ -287,7 +287,8 @@ std::vector Execution::gen_trace(std::vector const& calldata, // is determined by this value which require read access to the code below. uint32_t pc = 0; uint32_t counter = 0; - while ((pc = trace_builder.get_pc()) < bytecode.size()) { + AvmError error = AvmError::NO_ERROR; + while (error == AvmError::NO_ERROR && (pc = trace_builder.get_pc()) < bytecode.size()) { auto inst = Deserialization::parse(bytecode, pc); debug("[PC:" + std::to_string(pc) + "] [IC:" + std::to_string(counter++) + "] " + inst.to_string() + " (gasLeft l2=" + std::to_string(trace_builder.get_l2_gas_left()) + ")"); @@ -296,404 +297,405 @@ std::vector Execution::gen_trace(std::vector const& calldata, // Compute // Compute - Arithmetic case OpCode::ADD_8: - trace_builder.op_add(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::ADD_8); + error = trace_builder.op_add(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::ADD_8); break; case OpCode::ADD_16: - trace_builder.op_add(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::ADD_16); + error = trace_builder.op_add(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::ADD_16); break; case OpCode::SUB_8: - trace_builder.op_sub(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::SUB_8); + error = trace_builder.op_sub(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::SUB_8); break; case OpCode::SUB_16: - trace_builder.op_sub(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::SUB_16); + error = trace_builder.op_sub(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::SUB_16); break; case OpCode::MUL_8: - trace_builder.op_mul(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::MUL_8); + error = trace_builder.op_mul(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::MUL_8); break; case OpCode::MUL_16: - trace_builder.op_mul(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::MUL_16); + error = trace_builder.op_mul(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::MUL_16); break; case OpCode::DIV_8: - trace_builder.op_div(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::DIV_8); + error = trace_builder.op_div(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::DIV_8); break; case OpCode::DIV_16: - trace_builder.op_div(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::DIV_16); + error = trace_builder.op_div(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::DIV_16); break; case OpCode::FDIV_8: - trace_builder.op_fdiv(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::FDIV_8); + error = trace_builder.op_fdiv(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::FDIV_8); break; case OpCode::FDIV_16: - trace_builder.op_fdiv(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::FDIV_16); + error = trace_builder.op_fdiv(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::FDIV_16); break; case OpCode::EQ_8: - trace_builder.op_eq(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::EQ_8); + error = trace_builder.op_eq(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::EQ_8); break; case OpCode::EQ_16: - trace_builder.op_eq(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::EQ_16); + error = trace_builder.op_eq(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::EQ_16); break; case OpCode::LT_8: - trace_builder.op_lt(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::LT_8); + error = trace_builder.op_lt(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::LT_8); break; case OpCode::LT_16: - trace_builder.op_lt(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::LT_16); + error = trace_builder.op_lt(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::LT_16); break; case OpCode::LTE_8: - trace_builder.op_lte(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::LTE_8); + error = trace_builder.op_lte(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::LTE_8); break; case OpCode::LTE_16: - trace_builder.op_lte(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::LTE_16); + error = trace_builder.op_lte(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::LTE_16); break; case OpCode::AND_8: - trace_builder.op_and(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::AND_8); + error = trace_builder.op_and(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::AND_8); break; case OpCode::AND_16: - trace_builder.op_and(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::AND_16); + error = trace_builder.op_and(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::AND_16); break; case OpCode::OR_8: - trace_builder.op_or(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::OR_8); + error = trace_builder.op_or(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::OR_8); break; case OpCode::OR_16: - trace_builder.op_or(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::OR_16); + error = trace_builder.op_or(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::OR_16); break; case OpCode::XOR_8: - trace_builder.op_xor(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::XOR_8); + error = trace_builder.op_xor(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::XOR_8); break; case OpCode::XOR_16: - trace_builder.op_xor(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::XOR_16); + error = trace_builder.op_xor(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::XOR_16); break; case OpCode::NOT_8: - trace_builder.op_not(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - OpCode::NOT_8); + error = trace_builder.op_not(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + OpCode::NOT_8); break; case OpCode::NOT_16: - trace_builder.op_not(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - OpCode::NOT_16); + error = trace_builder.op_not(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + OpCode::NOT_16); break; case OpCode::SHL_8: - trace_builder.op_shl(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::SHL_8); + error = trace_builder.op_shl(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::SHL_8); break; case OpCode::SHL_16: - trace_builder.op_shl(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::SHL_16); + error = trace_builder.op_shl(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::SHL_16); break; case OpCode::SHR_8: - trace_builder.op_shr(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::SHR_8); + error = trace_builder.op_shr(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::SHR_8); break; case OpCode::SHR_16: - trace_builder.op_shr(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - OpCode::SHR_16); + error = trace_builder.op_shr(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + OpCode::SHR_16); break; // Compute - Type Conversions case OpCode::CAST_8: - trace_builder.op_cast(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(1)), - OpCode::CAST_8); + error = trace_builder.op_cast(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(1)), + OpCode::CAST_8); break; case OpCode::CAST_16: - trace_builder.op_cast(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(1)), - OpCode::CAST_16); + error = trace_builder.op_cast(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(1)), + OpCode::CAST_16); break; // Execution Environment // TODO(https://github.com/AztecProtocol/aztec-packages/issues/6284): support indirect for below case OpCode::GETENVVAR_16: - trace_builder.op_get_env_var(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2))); + error = trace_builder.op_get_env_var(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2))); break; // Execution Environment - Calldata case OpCode::CALLDATACOPY: - trace_builder.op_calldata_copy(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3))); + error = trace_builder.op_calldata_copy(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3))); break; case OpCode::RETURNDATASIZE: - trace_builder.op_returndata_size(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1))); + error = trace_builder.op_returndata_size(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1))); break; case OpCode::RETURNDATACOPY: - trace_builder.op_returndata_copy(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3))); + error = trace_builder.op_returndata_copy(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3))); break; // Machine State - Internal Control Flow case OpCode::JUMP_32: - trace_builder.op_jump(std::get(inst.operands.at(0))); + error = trace_builder.op_jump(std::get(inst.operands.at(0))); break; case OpCode::JUMPI_32: - trace_builder.op_jumpi(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2))); + error = trace_builder.op_jumpi(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2))); break; case OpCode::INTERNALCALL: - trace_builder.op_internal_call(std::get(inst.operands.at(0))); + error = trace_builder.op_internal_call(std::get(inst.operands.at(0))); break; case OpCode::INTERNALRETURN: - trace_builder.op_internal_return(); + error = trace_builder.op_internal_return(); break; // Machine State - Memory case OpCode::SET_8: { - trace_builder.op_set(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(1)), - OpCode::SET_8); + error = trace_builder.op_set(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(1)), + OpCode::SET_8); break; } case OpCode::SET_16: { - trace_builder.op_set(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(1)), - OpCode::SET_16); + error = trace_builder.op_set(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(1)), + OpCode::SET_16); break; } case OpCode::SET_32: { - trace_builder.op_set(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(1)), - OpCode::SET_32); + error = trace_builder.op_set(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(1)), + OpCode::SET_32); break; } case OpCode::SET_64: { - trace_builder.op_set(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(1)), - OpCode::SET_64); + error = trace_builder.op_set(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(1)), + OpCode::SET_64); break; } case OpCode::SET_128: { - trace_builder.op_set(std::get(inst.operands.at(0)), - uint256_t::from_uint128(std::get(inst.operands.at(2))), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(1)), - OpCode::SET_128); + error = trace_builder.op_set(std::get(inst.operands.at(0)), + uint256_t::from_uint128(std::get(inst.operands.at(2))), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(1)), + OpCode::SET_128); break; } case OpCode::SET_FF: { - trace_builder.op_set(std::get(inst.operands.at(0)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(1)), - OpCode::SET_FF); + error = trace_builder.op_set(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(1)), + OpCode::SET_FF); break; } case OpCode::MOV_8: - trace_builder.op_mov(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - OpCode::MOV_8); + error = trace_builder.op_mov(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + OpCode::MOV_8); break; case OpCode::MOV_16: - trace_builder.op_mov(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - OpCode::MOV_16); + error = trace_builder.op_mov(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + OpCode::MOV_16); break; // World State case OpCode::SLOAD: - trace_builder.op_sload(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - 1, - std::get(inst.operands.at(2))); + error = trace_builder.op_sload(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + 1, + std::get(inst.operands.at(2))); break; case OpCode::SSTORE: - trace_builder.op_sstore(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - 1, - std::get(inst.operands.at(2))); + error = trace_builder.op_sstore(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + 1, + std::get(inst.operands.at(2))); break; case OpCode::NOTEHASHEXISTS: - trace_builder.op_note_hash_exists(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3))); + error = trace_builder.op_note_hash_exists(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3))); break; case OpCode::EMITNOTEHASH: - trace_builder.op_emit_note_hash(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1))); + error = trace_builder.op_emit_note_hash(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1))); break; case OpCode::NULLIFIEREXISTS: - trace_builder.op_nullifier_exists(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3))); + error = trace_builder.op_nullifier_exists(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3))); break; case OpCode::EMITNULLIFIER: - trace_builder.op_emit_nullifier(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1))); + error = trace_builder.op_emit_nullifier(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1))); break; case OpCode::L1TOL2MSGEXISTS: - trace_builder.op_l1_to_l2_msg_exists(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3))); + error = trace_builder.op_l1_to_l2_msg_exists(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3))); break; case OpCode::GETCONTRACTINSTANCE: - trace_builder.op_get_contract_instance(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4))); + error = trace_builder.op_get_contract_instance(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4))); break; // Accrued Substate case OpCode::EMITUNENCRYPTEDLOG: - trace_builder.op_emit_unencrypted_log(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2))); + error = trace_builder.op_emit_unencrypted_log(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2))); break; case OpCode::SENDL2TOL1MSG: - trace_builder.op_emit_l2_to_l1_msg(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2))); + error = trace_builder.op_emit_l2_to_l1_msg(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2))); break; // Control Flow - Contract Calls case OpCode::CALL: - trace_builder.op_call(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), - std::get(inst.operands.at(5))); + error = trace_builder.op_call(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(5))); break; case OpCode::STATICCALL: - trace_builder.op_static_call(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), - std::get(inst.operands.at(5))); + error = trace_builder.op_static_call(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(5))); break; case OpCode::RETURN: { auto ret = trace_builder.op_return(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), std::get(inst.operands.at(2))); - returndata.insert(returndata.end(), ret.begin(), ret.end()); + error = ret.error; + returndata.insert(returndata.end(), ret.return_data.begin(), ret.return_data.end()); break; } @@ -702,7 +704,8 @@ std::vector Execution::gen_trace(std::vector const& calldata, auto ret = trace_builder.op_revert(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), std::get(inst.operands.at(2))); - returndata.insert(returndata.end(), ret.begin(), ret.end()); + error = ret.error; + returndata.insert(returndata.end(), ret.return_data.begin(), ret.return_data.end()); break; } @@ -711,66 +714,69 @@ std::vector Execution::gen_trace(std::vector const& calldata, auto ret = trace_builder.op_revert(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), std::get(inst.operands.at(2))); - returndata.insert(returndata.end(), ret.begin(), ret.end()); + error = ret.error; + returndata.insert(returndata.end(), ret.return_data.begin(), ret.return_data.end()); break; } // Misc case OpCode::DEBUGLOG: - // We want a noop, but we need to execute something that both advances the PC, - // and adds a valid row to the trace. - trace_builder.op_jump(pc + Deserialization::get_pc_increment(OpCode::DEBUGLOG)); + error = trace_builder.op_debug_log(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4))); break; // Gadgets case OpCode::POSEIDON2PERM: - trace_builder.op_poseidon2_permutation(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2))); + error = trace_builder.op_poseidon2_permutation(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2))); break; case OpCode::SHA256COMPRESSION: - trace_builder.op_sha256_compression(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3))); + error = trace_builder.op_sha256_compression(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3))); break; case OpCode::KECCAKF1600: - trace_builder.op_keccakf1600(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2))); + error = trace_builder.op_keccakf1600(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2))); break; case OpCode::ECADD: - trace_builder.op_ec_add(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), - std::get(inst.operands.at(5)), - std::get(inst.operands.at(6)), - std::get(inst.operands.at(7))); + error = trace_builder.op_ec_add(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(5)), + std::get(inst.operands.at(6)), + std::get(inst.operands.at(7))); break; case OpCode::MSM: - trace_builder.op_variable_msm(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4))); + error = trace_builder.op_variable_msm(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4))); break; // Conversions case OpCode::TORADIXBE: - trace_builder.op_to_radix_be(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3)), - std::get(inst.operands.at(4)), - std::get(inst.operands.at(5))); + error = trace_builder.op_to_radix_be(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(5))); break; default: @@ -780,6 +786,15 @@ std::vector Execution::gen_trace(std::vector const& calldata, } } + if (error != AvmError::NO_ERROR) { + info("AVM stopped due to exceptional halting condition. Error: ", + to_name(error), + " at PC: ", + pc, + " IC: ", + counter - 1); // Need adjustement as counter increment occurs in loop body + } + auto trace = trace_builder.finalize(); show_trace_info(trace); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution_hints.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution_hints.hpp index 4e9fe566bb8..a653054fba5 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution_hints.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution_hints.hpp @@ -9,12 +9,12 @@ using FF = AvmFlavorSettings::FF; using AffinePoint = grumpkin::g1::affine_element; struct ExternalCallHint { - FF success; + FF success{}; std::vector return_data; uint32_t l2_gas_used; uint32_t da_gas_used; - FF end_side_effect_counter; - FF contract_address; + FF end_side_effect_counter{}; + FF contract_address{}; }; // Add support for deserialization of ExternalCallHint. This is implicitly used by serialize::read @@ -31,9 +31,9 @@ inline void read(uint8_t const*& it, ExternalCallHint& hint) } struct ContractClassIdHint { - FF artifact_hash; - FF private_fn_root; - FF public_bytecode_commitment; + FF artifact_hash{}; + FF private_fn_root{}; + FF public_bytecode_commitment{}; }; inline void read(uint8_t const*& it, ContractClassIdHint& preimage) @@ -61,12 +61,12 @@ struct PublicKeysHint { }; struct ContractInstanceHint { - FF address; + FF address{}; bool exists; // Useful for membership checks - FF salt; - FF deployer_addr; - FF contract_class_id; - FF initialisation_hash; + FF salt{}; + FF deployer_addr{}; + FF contract_class_id{}; + FF initialisation_hash{}; PublicKeysHint public_keys; }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp index bb9eda6172e..79e6e4a69c8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp @@ -83,7 +83,7 @@ const std::unordered_map GAS_COST_TABLE = { { OpCode::RETURN, make_cost(AVM_RETURN_BASE_L2_GAS, 0, AVM_RETURN_DYN_L2_GAS, 0) }, { OpCode::REVERT_8, make_cost(AVM_REVERT_BASE_L2_GAS, 0, AVM_REVERT_DYN_L2_GAS, 0) }, { OpCode::REVERT_16, make_cost(AVM_REVERT_BASE_L2_GAS, 0, AVM_REVERT_DYN_L2_GAS, 0) }, - { OpCode::DEBUGLOG, make_cost(AVM_DEBUGLOG_BASE_L2_GAS, 0, 0, 0) }, + { OpCode::DEBUGLOG, make_cost(AVM_DEBUGLOG_BASE_L2_GAS, 0, AVM_DEBUGLOG_DYN_L2_GAS, 0) }, { OpCode::POSEIDON2PERM, make_cost(AVM_POSEIDON2_BASE_L2_GAS, 0, 0, 0) }, { OpCode::SHA256COMPRESSION, make_cost(AVM_SHA256COMPRESSION_BASE_L2_GAS, 0, 0, 0) }, { OpCode::KECCAKF1600, make_cost(AVM_KECCAKF1600_BASE_L2_GAS, 0, 0, 0) }, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp index 6c44d1b01e1..1960cac37b3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp @@ -71,27 +71,27 @@ bool is_operand_indirect(uint8_t ind_value, uint8_t operand_idx) return (ind_value & (1 << operand_idx)) != 0; } -std::string to_hex(bb::avm_trace::AvmMemoryTag tag) +std::string to_hex(AvmMemoryTag tag) { return to_hex(static_cast(tag)); } -std::string to_name(bb::avm_trace::AvmMemoryTag tag) +std::string to_name(AvmMemoryTag tag) { switch (tag) { - case bb::avm_trace::AvmMemoryTag::FF: + case AvmMemoryTag::FF: return "Field"; - case bb::avm_trace::AvmMemoryTag::U1: + case AvmMemoryTag::U1: return "Uint1"; - case bb::avm_trace::AvmMemoryTag::U8: + case AvmMemoryTag::U8: return "Uint8"; - case bb::avm_trace::AvmMemoryTag::U16: + case AvmMemoryTag::U16: return "Uint16"; - case bb::avm_trace::AvmMemoryTag::U32: + case AvmMemoryTag::U32: return "Uint32"; - case bb::avm_trace::AvmMemoryTag::U64: + case AvmMemoryTag::U64: return "Uint64"; - case bb::avm_trace::AvmMemoryTag::U128: + case AvmMemoryTag::U128: return "Uint128"; default: throw std::runtime_error("Invalid memory tag"); @@ -99,6 +99,29 @@ std::string to_name(bb::avm_trace::AvmMemoryTag tag) } } +std::string to_name(AvmError error) +{ + switch (error) { + case AvmError::NO_ERROR: + return "NO ERROR"; + case AvmError::TAG_ERROR: + return "TAG ERROR"; + case AvmError::ADDR_RES_ERROR: + return "ADDRESS RESOLUTION ERROR"; + case AvmError::DIV_ZERO: + return "DIVISION BY ZERO"; + case AvmError::PARSING_ERROR: + return "PARSING ERROR"; + case AvmError::ENV_VAR_UNKNOWN: + return "ENVIRONMENT VARIABLE UNKNOWN"; + case AvmError::CONTRACT_INST_MEM_UNKNOWN: + return "CONTRACT INSTANCE MEMBER UNKNOWN"; + default: + throw std::runtime_error("Invalid error type"); + break; + } +} + /** * * ONLY FOR TESTS - Required by dsl module and therefore cannot be moved to test/helpers.test.cpp diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp index bd45a1b472c..cc1976dc501 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp @@ -232,6 +232,8 @@ std::string to_hex(bb::avm_trace::AvmMemoryTag tag); std::string to_name(bb::avm_trace::AvmMemoryTag tag); +std::string to_name(AvmError error); + // Mutate the inputs void inject_end_gas_values(VmPublicInputs& public_inputs, std::vector& trace); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index 15ff1512c82..58bd15bd44f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -109,6 +109,21 @@ template std::array vec_to_arr(std::vector return arr; } +bool check_tag_integral(AvmMemoryTag tag) +{ + switch (tag) { + case AvmMemoryTag::U1: + case AvmMemoryTag::U8: + case AvmMemoryTag::U16: + case AvmMemoryTag::U32: + case AvmMemoryTag::U64: + case AvmMemoryTag::U128: + return true; + default: + return false; + } +} + } // anonymous namespace /************************************************************************************************** @@ -206,6 +221,21 @@ AvmMemoryTag AvmTraceBuilder::unconstrained_get_memory_tag(AddressWithMode addr) return mem_trace_builder.unconstrained_get_memory_tag(call_ptr, offset); } +bool AvmTraceBuilder::check_tag(AvmMemoryTag tag, AddressWithMode addr) +{ + return unconstrained_get_memory_tag(addr) == tag; +} + +bool AvmTraceBuilder::check_tag_range(AvmMemoryTag tag, AddressWithMode start_offset, uint32_t size) +{ + for (uint32_t i = 0; i < size; i++) { + if (!check_tag(tag, start_offset + i)) { + return false; + } + } + return true; +} + FF AvmTraceBuilder::unconstrained_read_from_memory(AddressWithMode addr) { auto offset = addr.offset; @@ -296,7 +326,7 @@ AvmTraceBuilder::AvmTraceBuilder(VmPublicInputs public_inputs, * @param dst_offset An index in memory pointing to the output of the addition. * @param in_tag The instruction memory tag of the operands. */ -void AvmTraceBuilder::op_add( +AvmError AvmTraceBuilder::op_add( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -358,6 +388,7 @@ void AvmTraceBuilder::op_add( ASSERT(op_code == OpCode::ADD_8 || op_code == OpCode::ADD_16); pc += Deserialization::get_pc_increment(op_code); + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /** @@ -369,7 +400,7 @@ void AvmTraceBuilder::op_add( * @param dst_offset An index in memory pointing to the output of the subtraction. * @param in_tag The instruction memory tag of the operands. */ -void AvmTraceBuilder::op_sub( +AvmError AvmTraceBuilder::op_sub( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -431,6 +462,7 @@ void AvmTraceBuilder::op_sub( ASSERT(op_code == OpCode::SUB_8 || op_code == OpCode::SUB_16); pc += Deserialization::get_pc_increment(op_code); + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /** @@ -442,7 +474,7 @@ void AvmTraceBuilder::op_sub( * @param dst_offset An index in memory pointing to the output of the multiplication. * @param in_tag The instruction memory tag of the operands. */ -void AvmTraceBuilder::op_mul( +AvmError AvmTraceBuilder::op_mul( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -504,6 +536,7 @@ void AvmTraceBuilder::op_mul( ASSERT(op_code == OpCode::MUL_8 || op_code == OpCode::MUL_16); pc += Deserialization::get_pc_increment(op_code); + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /** @@ -515,7 +548,7 @@ void AvmTraceBuilder::op_mul( * @param dst_offset An index in memory pointing to the output of the division. * @param in_tag The instruction memory tag of the operands. */ -void AvmTraceBuilder::op_div( +AvmError AvmTraceBuilder::op_div( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -539,17 +572,16 @@ void AvmTraceBuilder::op_div( // output (c) in memory. FF c; FF inv; - FF error; + bool div_error = false; if (!b.is_zero()) { // If b is not zero, we prove it is not by providing its inverse as well inv = b.invert(); c = tag_match ? alu_trace_builder.op_div(a, b, in_tag, clk) : FF(0); - error = 0; } else { inv = 1; c = 0; - error = 1; + div_error = true; } // Write into memory value c from intermediate register ic. @@ -573,7 +605,7 @@ void AvmTraceBuilder::op_div( .main_mem_addr_a = FF(read_a.direct_address), .main_mem_addr_b = FF(read_b.direct_address), .main_mem_addr_c = FF(write_dst.direct_address), - .main_op_err = tag_match ? error : FF(1), + .main_op_err = tag_match ? FF(static_cast(div_error)) : FF(1), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(in_tag)), .main_rwc = FF(1), @@ -590,6 +622,7 @@ void AvmTraceBuilder::op_div( ASSERT(op_code == OpCode::DIV_8 || op_code == OpCode::DIV_16); pc += Deserialization::get_pc_increment(op_code); + return !tag_match ? AvmError::TAG_ERROR : div_error ? AvmError::DIV_ZERO : AvmError::NO_ERROR; } /** @@ -601,7 +634,7 @@ void AvmTraceBuilder::op_div( * @param dst_offset An index in memory pointing to the output of the division. * @param in_tag The instruction memory tag of the operands. */ -void AvmTraceBuilder::op_fdiv( +AvmError AvmTraceBuilder::op_fdiv( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -623,16 +656,15 @@ void AvmTraceBuilder::op_fdiv( FF b = read_b.val; FF c; FF inv; - FF error; + bool div_error = false; if (!b.is_zero()) { inv = b.invert(); c = a * inv; - error = 0; } else { inv = 1; c = 0; - error = 1; + div_error = true; } // Write into memory value c from intermediate register ic. @@ -656,7 +688,7 @@ void AvmTraceBuilder::op_fdiv( .main_mem_addr_a = FF(read_a.direct_address), .main_mem_addr_b = FF(read_b.direct_address), .main_mem_addr_c = FF(write_c.direct_address), - .main_op_err = tag_match ? error : FF(1), + .main_op_err = tag_match ? FF(static_cast(div_error)) : FF(1), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(AvmMemoryTag::FF)), .main_rwc = FF(1), @@ -673,6 +705,7 @@ void AvmTraceBuilder::op_fdiv( ASSERT(op_code == OpCode::FDIV_8 || op_code == OpCode::FDIV_16); pc += Deserialization::get_pc_increment(op_code); + return !tag_match ? AvmError::TAG_ERROR : div_error ? AvmError::DIV_ZERO : AvmError::NO_ERROR; } /************************************************************************************************** @@ -688,7 +721,8 @@ void AvmTraceBuilder::op_fdiv( * @param dst_offset An index in memory pointing to the output of the equality. * @param in_tag The instruction memory tag of the operands. */ -void AvmTraceBuilder::op_eq(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) +AvmError AvmTraceBuilder::op_eq( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -747,9 +781,11 @@ void AvmTraceBuilder::op_eq(uint8_t indirect, uint32_t a_offset, uint32_t b_offs ASSERT(op_code == OpCode::EQ_8 || op_code == OpCode::EQ_16); pc += Deserialization::get_pc_increment(op_code); + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_lt(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) +AvmError AvmTraceBuilder::op_lt( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -804,9 +840,10 @@ void AvmTraceBuilder::op_lt(uint8_t indirect, uint32_t a_offset, uint32_t b_offs ASSERT(op_code == OpCode::LT_8 || op_code == OpCode::LT_16); pc += Deserialization::get_pc_increment(op_code); + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_lte( +AvmError AvmTraceBuilder::op_lte( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -863,13 +900,14 @@ void AvmTraceBuilder::op_lte( ASSERT(op_code == OpCode::LTE_8 || op_code == OpCode::LTE_16); pc += Deserialization::get_pc_increment(op_code); + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /************************************************************************************************** * COMPUTE - BITWISE **************************************************************************************************/ -void AvmTraceBuilder::op_and( +AvmError AvmTraceBuilder::op_and( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -882,12 +920,15 @@ void AvmTraceBuilder::op_and( // Reading from memory and loading into ia resp. ib. auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, in_tag, IntermRegister::IA); auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, in_tag, in_tag, IntermRegister::IB); + bool tag_match = read_a.tag_match && read_b.tag_match; + // No need to add check_tag_integral(read_b.tag) as this follows from tag matching and that a has integral tag. + bool op_valid = tag_match && check_tag_integral(read_a.tag); FF a = tag_match ? read_a.val : FF(0); FF b = tag_match ? read_b.val : FF(0); - FF c = tag_match ? bin_trace_builder.op_and(a, b, in_tag, clk) : FF(0); + FF c = op_valid ? bin_trace_builder.op_and(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); @@ -909,10 +950,11 @@ void AvmTraceBuilder::op_and( .main_mem_addr_a = FF(read_a.direct_address), .main_mem_addr_b = FF(read_b.direct_address), .main_mem_addr_c = FF(write_c.direct_address), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(in_tag)), .main_rwc = FF(1), - .main_sel_bin = FF(1), + .main_sel_bin = FF(static_cast(op_valid)), .main_sel_mem_op_a = FF(1), .main_sel_mem_op_b = FF(1), .main_sel_mem_op_c = FF(1), @@ -926,9 +968,11 @@ void AvmTraceBuilder::op_and( ASSERT(op_code == OpCode::AND_8 || op_code == OpCode::AND_16); pc += Deserialization::get_pc_increment(op_code); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_or(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) +AvmError AvmTraceBuilder::op_or( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; auto [resolved_a, resolved_b, resolved_c] = @@ -939,12 +983,15 @@ void AvmTraceBuilder::op_or(uint8_t indirect, uint32_t a_offset, uint32_t b_offs // Reading from memory and loading into ia resp. ib. auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, in_tag, IntermRegister::IA); auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, in_tag, in_tag, IntermRegister::IB); + bool tag_match = read_a.tag_match && read_b.tag_match; + // No need to add check_tag_integral(read_b.tag) as this follows from tag matching and that a has integral tag. + bool op_valid = tag_match && check_tag_integral(read_a.tag); FF a = tag_match ? read_a.val : FF(0); FF b = tag_match ? read_b.val : FF(0); - FF c = tag_match ? bin_trace_builder.op_or(a, b, in_tag, clk) : FF(0); + FF c = op_valid ? bin_trace_builder.op_or(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); @@ -966,10 +1013,11 @@ void AvmTraceBuilder::op_or(uint8_t indirect, uint32_t a_offset, uint32_t b_offs .main_mem_addr_a = FF(read_a.direct_address), .main_mem_addr_b = FF(read_b.direct_address), .main_mem_addr_c = FF(write_c.direct_address), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(in_tag)), .main_rwc = FF(1), - .main_sel_bin = FF(1), + .main_sel_bin = FF(static_cast(op_valid)), .main_sel_mem_op_a = FF(1), .main_sel_mem_op_b = FF(1), .main_sel_mem_op_c = FF(1), @@ -983,9 +1031,10 @@ void AvmTraceBuilder::op_or(uint8_t indirect, uint32_t a_offset, uint32_t b_offs ASSERT(op_code == OpCode::OR_8 || op_code == OpCode::OR_16); pc += Deserialization::get_pc_increment(op_code); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_xor( +AvmError AvmTraceBuilder::op_xor( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -998,12 +1047,15 @@ void AvmTraceBuilder::op_xor( // Reading from memory and loading into ia resp. ib. auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, in_tag, IntermRegister::IA); auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, in_tag, in_tag, IntermRegister::IB); + bool tag_match = read_a.tag_match && read_b.tag_match; + // No need to add check_tag_integral(read_b.tag) as this follows from tag matching and that a has integral tag. + bool op_valid = tag_match && check_tag_integral(read_a.tag); FF a = tag_match ? read_a.val : FF(0); FF b = tag_match ? read_b.val : FF(0); - FF c = tag_match ? bin_trace_builder.op_xor(a, b, in_tag, clk) : FF(0); + FF c = op_valid ? bin_trace_builder.op_xor(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); @@ -1025,10 +1077,11 @@ void AvmTraceBuilder::op_xor( .main_mem_addr_a = FF(read_a.direct_address), .main_mem_addr_b = FF(read_b.direct_address), .main_mem_addr_c = FF(write_c.direct_address), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(in_tag)), .main_rwc = FF(1), - .main_sel_bin = FF(1), + .main_sel_bin = FF(static_cast(op_valid)), .main_sel_mem_op_a = FF(1), .main_sel_mem_op_b = FF(1), .main_sel_mem_op_c = FF(1), @@ -1042,6 +1095,7 @@ void AvmTraceBuilder::op_xor( ASSERT(op_code == OpCode::XOR_8 || op_code == OpCode::XOR_16); pc += Deserialization::get_pc_increment(op_code); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /** @@ -1051,7 +1105,7 @@ void AvmTraceBuilder::op_xor( * @param a_offset An index in memory pointing to the only operand of Not. * @param dst_offset An index in memory pointing to the output of Not. */ -void AvmTraceBuilder::op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, OpCode op_code) +AvmError AvmTraceBuilder::op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -1064,14 +1118,14 @@ void AvmTraceBuilder::op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_o // Reading from memory and loading into ia auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, in_tag, IntermRegister::IA); - bool tag_match = read_a.tag_match; + bool op_valid = check_tag_integral(read_a.tag); // ~a = c FF a = read_a.val; - // In case of a memory tag error, we do not perform the computation. + // In case of an error (tag of type FF), we do not perform the computation. // Therefore, we do not create any entry in ALU table and store the value 0 as // output (c) in memory. - FF c = tag_match ? alu_trace_builder.op_not(a, in_tag, clk) : FF(0); + FF c = op_valid ? alu_trace_builder.op_not(a, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); @@ -1090,6 +1144,7 @@ void AvmTraceBuilder::op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_o .main_internal_return_ptr = FF(internal_return_ptr), .main_mem_addr_a = FF(read_a.direct_address), .main_mem_addr_c = FF(write_c.direct_address), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(in_tag)), .main_rwc = FF(1), @@ -1098,15 +1153,15 @@ void AvmTraceBuilder::op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_o .main_sel_op_not = FF(1), .main_sel_resolve_ind_addr_a = FF(static_cast(read_a.is_indirect)), .main_sel_resolve_ind_addr_c = FF(static_cast(write_c.is_indirect)), - .main_tag_err = FF(static_cast(!read_a.tag_match)), .main_w_in_tag = FF(static_cast(in_tag)), }); ASSERT(op_code == OpCode::NOT_8 || op_code == OpCode::NOT_16); pc += Deserialization::get_pc_increment(op_code); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_shl( +AvmError AvmTraceBuilder::op_shl( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -1117,18 +1172,17 @@ void AvmTraceBuilder::op_shl( // We get our representative memory tag from the resolved_a memory address. AvmMemoryTag in_tag = unconstrained_get_memory_tag(resolved_a); // Reading from memory and loading into ia resp. ib. - // TODO(9497): if simulator fails tag check here, witgen will not. Raise error flag if in_tag is FF! auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, in_tag, IntermRegister::IA); // TODO(8603): once instructions can have multiple different tags for reads, constrain b's read & tag // auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, AvmMemoryTag::U8, AvmMemoryTag::U8, // IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; - auto read_b = unconstrained_read_from_memory(resolved_b); // should be tagged as U8 - bool tag_match = read_a.tag_match; + auto read_b = unconstrained_read_from_memory(resolved_b); + bool op_valid = check_tag_integral(read_a.tag) && check_tag(AvmMemoryTag::U8, resolved_b); - FF a = tag_match ? read_a.val : FF(0); - FF b = tag_match ? read_b : FF(0); + FF a = op_valid ? read_a.val : FF(0); + FF b = op_valid ? read_b : FF(0); - FF c = tag_match ? alu_trace_builder.op_shl(a, b, in_tag, clk) : FF(0); + FF c = op_valid ? alu_trace_builder.op_shl(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); @@ -1149,6 +1203,7 @@ void AvmTraceBuilder::op_shl( .main_mem_addr_a = FF(read_a.direct_address), //.main_mem_addr_b = FF(read_b.direct_address), .main_mem_addr_c = FF(write_c.direct_address), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(in_tag)), .main_rwc = FF(1), @@ -1159,15 +1214,15 @@ void AvmTraceBuilder::op_shl( .main_sel_resolve_ind_addr_a = FF(static_cast(read_a.is_indirect)), //.main_sel_resolve_ind_addr_b = FF(static_cast(read_b.is_indirect)), .main_sel_resolve_ind_addr_c = FF(static_cast(write_c.is_indirect)), - .main_tag_err = FF(static_cast(!tag_match)), .main_w_in_tag = FF(static_cast(in_tag)), }); ASSERT(op_code == OpCode::SHL_8 || op_code == OpCode::SHL_16); pc += Deserialization::get_pc_increment(op_code); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_shr( +AvmError AvmTraceBuilder::op_shr( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code) { auto clk = static_cast(main_trace.size()) + 1; @@ -1178,18 +1233,17 @@ void AvmTraceBuilder::op_shr( // We get our representative memory tag from the resolved_a memory address. AvmMemoryTag in_tag = unconstrained_get_memory_tag(resolved_a); // Reading from memory and loading into ia resp. ib. - // TODO(9497): if simulator fails tag check here, witgen will not. Raise error flag if in_tag is FF! auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, in_tag, IntermRegister::IA); // TODO(8603): once instructions can have multiple different tags for reads, constrain b's read & tag // auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, AvmMemoryTag::U8, AvmMemoryTag::U8, // IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; - auto read_b = unconstrained_read_from_memory(resolved_b); // should be tagged as U8 - bool tag_match = read_a.tag_match; + auto read_b = unconstrained_read_from_memory(resolved_b); + bool op_valid = check_tag_integral(read_a.tag) && check_tag(AvmMemoryTag::U8, resolved_b); - FF a = tag_match ? read_a.val : FF(0); - FF b = tag_match ? read_b : FF(0); + FF a = op_valid ? read_a.val : FF(0); + FF b = op_valid ? read_b : FF(0); - FF c = tag_match ? alu_trace_builder.op_shr(a, b, in_tag, clk) : FF(0); + FF c = op_valid ? alu_trace_builder.op_shr(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. auto write_c = constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, in_tag, IntermRegister::IC); @@ -1212,6 +1266,7 @@ void AvmTraceBuilder::op_shr( // TODO(8603): uncomment //.main_mem_addr_b = FF(read_b.direct_address), .main_mem_addr_c = FF(write_c.direct_address), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(in_tag)), .main_rwc = FF(1), @@ -1224,12 +1279,12 @@ void AvmTraceBuilder::op_shr( // TODO(8603): uncomment //.main_sel_resolve_ind_addr_b = FF(static_cast(read_b.is_indirect)), .main_sel_resolve_ind_addr_c = FF(static_cast(write_c.is_indirect)), - .main_tag_err = FF(static_cast(!tag_match)), .main_w_in_tag = FF(static_cast(in_tag)), }); ASSERT(op_code == OpCode::SHR_8 || op_code == OpCode::SHR_16); pc += Deserialization::get_pc_increment(op_code); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /************************************************************************************************** @@ -1245,23 +1300,22 @@ void AvmTraceBuilder::op_shr( * @param dst_offset Offset of destination memory cell. * @param dst_tag Destination tag specifying the type the source value must be casted to. */ -void AvmTraceBuilder::op_cast( +AvmError AvmTraceBuilder::op_cast( uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, AvmMemoryTag dst_tag, OpCode op_code) { auto const clk = static_cast(main_trace.size()) + 1; - bool tag_match = true; auto [resolved_a, resolved_c] = Addressing<2>::fromWire(indirect, call_ptr).resolve({ a_offset, dst_offset }, mem_trace_builder); // Reading from memory and loading into ia + // There cannot be any tag error in this case. auto memEntry = mem_trace_builder.read_and_load_cast_opcode(call_ptr, clk, resolved_a, dst_tag); FF a = memEntry.val; - // In case of a memory tag error, we do not perform the computation. // Therefore, we do not create any entry in ALU table and store the value 0 as // output (c) in memory. - FF c = tag_match ? alu_trace_builder.op_cast(a, dst_tag, clk) : FF(0); + FF c = alu_trace_builder.op_cast(a, dst_tag, clk); // Write into memory value c from intermediate register ic. mem_trace_builder.write_into_memory(call_ptr, clk, IntermRegister::IC, resolved_c, c, memEntry.tag, dst_tag); @@ -1284,12 +1338,12 @@ void AvmTraceBuilder::op_cast( .main_sel_mem_op_a = FF(1), .main_sel_mem_op_c = FF(1), .main_sel_op_cast = FF(1), - .main_tag_err = FF(static_cast(!tag_match)), .main_w_in_tag = FF(static_cast(dst_tag)), }); ASSERT(op_code == OpCode::CAST_8 || op_code == OpCode::CAST_16); pc += Deserialization::get_pc_increment(op_code); + return AvmError::NO_ERROR; } /************************************************************************************************** @@ -1305,7 +1359,6 @@ void AvmTraceBuilder::op_cast( * * @param indirect - Perform indirect memory resolution * @param dst_offset - Memory address to write the lookup result to - * @param selector - The index of the kernel input lookup column * @param value - The value read from the memory address * @param w_tag - The memory tag of the value read * @return Row @@ -1335,7 +1388,7 @@ Row AvmTraceBuilder::create_kernel_lookup_opcode(uint8_t indirect, uint32_t dst_ }; } -void AvmTraceBuilder::op_get_env_var(uint8_t indirect, uint8_t env_var, uint32_t dst_offset) +AvmError AvmTraceBuilder::op_get_env_var(uint8_t indirect, uint8_t env_var, uint32_t dst_offset) { if (env_var >= static_cast(EnvironmentVariable::MAX_ENV_VAR)) { // Error, bad enum operand @@ -1346,14 +1399,14 @@ void AvmTraceBuilder::op_get_env_var(uint8_t indirect, uint8_t env_var, uint32_t .main_call_ptr = call_ptr, .main_internal_return_ptr = internal_return_ptr, .main_op_err = FF(1), - .main_pc = pc++, + .main_pc = pc, .main_sel_op_address = FF(1), // TODO(9407): what selector should this be? }; // Constrain gas cost gas_trace_builder.constrain_gas(static_cast(row.main_clk), OpCode::GETENVVAR_16); - main_trace.push_back(row); + return AvmError::ENV_VAR_UNKNOWN; } else { EnvironmentVariable var = static_cast(env_var); @@ -1398,11 +1451,13 @@ void AvmTraceBuilder::op_get_env_var(uint8_t indirect, uint8_t env_var, uint32_t op_dagasleft(indirect, dst_offset); break; default: + // Cannot happen thanks to the first if clause. This is to make the compiler happy. throw std::runtime_error("Invalid environment variable"); break; } + pc += Deserialization::get_pc_increment(OpCode::GETENVVAR_16); + return AvmError::NO_ERROR; } - pc += Deserialization::get_pc_increment(OpCode::GETENVVAR_16); } void AvmTraceBuilder::op_address(uint8_t indirect, uint32_t dst_offset) @@ -1574,10 +1629,10 @@ void AvmTraceBuilder::op_fee_per_da_gas(uint8_t indirect, uint32_t dst_offset) * @param copy_size_offset The number of finite field elements to be copied into memory. * @param dst_offset The starting index of memory where calldata will be copied to. */ -void AvmTraceBuilder::op_calldata_copy(uint8_t indirect, - uint32_t cd_offset_address, - uint32_t copy_size_address, - uint32_t dst_offset) +AvmError AvmTraceBuilder::op_calldata_copy(uint8_t indirect, + uint32_t cd_offset_address, + uint32_t copy_size_address, + uint32_t dst_offset) { auto clk = static_cast(main_trace.size()) + 1; @@ -1587,16 +1642,14 @@ void AvmTraceBuilder::op_calldata_copy(uint8_t indirect, // This boolean will not be a trivial constant anymore once we constrain address resolution. bool tag_match = true; - - // The only memory operations performed from the main trace are indirect load (address resolutions) - // which are still unconstrained. - // All the other memory operations are triggered by the slice gadget. + bool op_valid = tag_match && check_tag(AvmMemoryTag::U32, cd_offset_resolved) && + check_tag(AvmMemoryTag::U32, copy_size_offset_resolved); // TODO: constrain these. const uint32_t cd_offset = static_cast(unconstrained_read_from_memory(cd_offset_resolved)); const uint32_t copy_size = static_cast(unconstrained_read_from_memory(copy_size_offset_resolved)); - if (tag_match) { + if (op_valid) { slice_trace_builder.create_calldata_copy_slice( calldata, clk, call_ptr, cd_offset, copy_size, dst_offset_resolved); mem_trace_builder.write_calldata_copy(calldata, clk, call_ptr, cd_offset, copy_size, dst_offset_resolved); @@ -1612,18 +1665,20 @@ void AvmTraceBuilder::op_calldata_copy(uint8_t indirect, .main_ib = copy_size, .main_internal_return_ptr = FF(internal_return_ptr), .main_mem_addr_c = dst_offset_resolved, + .main_op_err = static_cast(!op_valid), .main_pc = pc, .main_r_in_tag = static_cast(AvmMemoryTag::FF), .main_sel_op_calldata_copy = 1, - .main_sel_slice_gadget = static_cast(tag_match), + .main_sel_slice_gadget = static_cast(op_valid), .main_tag_err = static_cast(!tag_match), .main_w_in_tag = static_cast(AvmMemoryTag::FF), }); pc += Deserialization::get_pc_increment(OpCode::CALLDATACOPY); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_returndata_size(uint8_t indirect, uint32_t dst_offset) +AvmError AvmTraceBuilder::op_returndata_size(uint8_t indirect, uint32_t dst_offset) { auto const clk = static_cast(main_trace.size()) + 1; // This boolean will not be a trivial constant anymore once we constrain address resolution. @@ -1649,12 +1704,13 @@ void AvmTraceBuilder::op_returndata_size(uint8_t indirect, uint32_t dst_offset) }); pc += Deserialization::get_pc_increment(OpCode::RETURNDATASIZE); + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_returndata_copy(uint8_t indirect, - uint32_t rd_offset_address, - uint32_t copy_size_offset, - uint32_t dst_offset) +AvmError AvmTraceBuilder::op_returndata_copy(uint8_t indirect, + uint32_t rd_offset_address, + uint32_t copy_size_offset, + uint32_t dst_offset) { auto clk = static_cast(main_trace.size()) + 1; @@ -1664,6 +1720,8 @@ void AvmTraceBuilder::op_returndata_copy(uint8_t indirect, // This boolean will not be a trivial constant anymore once we constrain address resolution. bool tag_match = true; + bool op_valid = tag_match && check_tag(AvmMemoryTag::U32, rd_offset_address) && + check_tag(AvmMemoryTag::U32, copy_size_offset_resolved); // TODO: constrain these. const uint32_t rd_offset = static_cast(unconstrained_read_from_memory(rd_offset_resolved)); @@ -1676,21 +1734,25 @@ void AvmTraceBuilder::op_returndata_copy(uint8_t indirect, main_trace.push_back(Row{ .main_clk = clk, .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = static_cast(!op_valid), .main_pc = FF(pc), .main_sel_op_returndata_copy = FF(1), .main_tag_err = FF(static_cast(!tag_match)), }); - // Write the return data to memory - // TODO: validate bounds - auto returndata_slice = - std::vector(nested_returndata.begin() + rd_offset, nested_returndata.begin() + rd_offset + copy_size); + if (op_valid) { + // Write the return data to memory + // TODO: validate bounds + auto returndata_slice = + std::vector(nested_returndata.begin() + rd_offset, nested_returndata.begin() + rd_offset + copy_size); - pc += Deserialization::get_pc_increment(OpCode::RETURNDATACOPY); + pc += Deserialization::get_pc_increment(OpCode::RETURNDATACOPY); - // Crucial to perform this operation after having incremented pc because write_slice_to_memory - // is implemented with opcodes (SET and JUMP). - write_slice_to_memory(dst_offset_resolved, AvmMemoryTag::FF, returndata_slice); + // Crucial to perform this operation after having incremented pc because write_slice_to_memory + // is implemented with opcodes (SET and JUMP). + write_slice_to_memory(dst_offset_resolved, AvmMemoryTag::FF, returndata_slice); + } + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /************************************************************************************************** @@ -1700,7 +1762,7 @@ void AvmTraceBuilder::op_returndata_copy(uint8_t indirect, // Helper for "gas left" related opcodes void AvmTraceBuilder::execute_gasleft(EnvironmentVariable var, uint8_t indirect, uint32_t dst_offset) { - assert(var == EnvironmentVariable::L2GASLEFT || var == EnvironmentVariable::DAGASLEFT); + ASSERT(var == EnvironmentVariable::L2GASLEFT || var == EnvironmentVariable::DAGASLEFT); auto clk = static_cast(main_trace.size()) + 1; @@ -1763,7 +1825,7 @@ void AvmTraceBuilder::op_dagasleft(uint8_t indirect, uint32_t dst_offset) * * @param jmp_dest - The destination to jump to */ -void AvmTraceBuilder::op_jump(uint32_t jmp_dest, bool skip_gas) +AvmError AvmTraceBuilder::op_jump(uint32_t jmp_dest, bool skip_gas) { auto clk = static_cast(main_trace.size()) + 1; @@ -1783,6 +1845,7 @@ void AvmTraceBuilder::op_jump(uint32_t jmp_dest, bool skip_gas) // Adjust parameters for the next row pc = jmp_dest; + return AvmError::NO_ERROR; } /** @@ -1795,7 +1858,7 @@ void AvmTraceBuilder::op_jump(uint32_t jmp_dest, bool skip_gas) * @param jmp_dest The destination to jump to * @param cond_offset Offset of the condition */ -void AvmTraceBuilder::op_jumpi(uint8_t indirect, uint32_t jmp_dest, uint32_t cond_offset) +AvmError AvmTraceBuilder::op_jumpi(uint8_t indirect, uint32_t jmp_dest, uint32_t cond_offset) { auto clk = static_cast(main_trace.size()) + 1; @@ -1834,6 +1897,7 @@ void AvmTraceBuilder::op_jumpi(uint8_t indirect, uint32_t jmp_dest, uint32_t con // Adjust parameters for the next row pc = next_pc; + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /** @@ -1849,7 +1913,7 @@ void AvmTraceBuilder::op_jumpi(uint8_t indirect, uint32_t jmp_dest, uint32_t con * * @param jmp_dest - The destination to jump to */ -void AvmTraceBuilder::op_internal_call(uint32_t jmp_dest) +AvmError AvmTraceBuilder::op_internal_call(uint32_t jmp_dest) { auto clk = static_cast(main_trace.size()) + 1; const auto next_pc = pc + Deserialization::get_pc_increment(OpCode::INTERNALCALL); @@ -1882,6 +1946,7 @@ void AvmTraceBuilder::op_internal_call(uint32_t jmp_dest) // Adjust parameters for the next row pc = jmp_dest; internal_return_ptr++; + return AvmError::NO_ERROR; } /** @@ -1895,7 +1960,7 @@ void AvmTraceBuilder::op_internal_call(uint32_t jmp_dest) * TODO(https://github.com/AztecProtocol/aztec-packages/issues/3740): This function MUST come after a call * instruction. */ -void AvmTraceBuilder::op_internal_return() +AvmError AvmTraceBuilder::op_internal_return() { auto clk = static_cast(main_trace.size()) + 1; @@ -1923,6 +1988,7 @@ void AvmTraceBuilder::op_internal_return() pc = uint32_t(read_a.val); internal_return_ptr--; + return AvmError::NO_ERROR; } /************************************************************************************************** @@ -1943,7 +2009,7 @@ void AvmTraceBuilder::op_internal_return() * @param dst_offset Memory destination offset where val is written to * @param in_tag The instruction memory tag */ -void AvmTraceBuilder::op_set( +AvmError AvmTraceBuilder::op_set( uint8_t indirect, FF val_ff, uint32_t dst_offset, AvmMemoryTag in_tag, OpCode op_code, bool skip_gas) { auto const clk = static_cast(main_trace.size()) + 1; @@ -1978,6 +2044,7 @@ void AvmTraceBuilder::op_set( OpCode::SET_64, OpCode::SET_128, OpCode::SET_FF }; ASSERT(set_family.contains(op_code)); pc += Deserialization::get_pc_increment(op_code); + return write_c.tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /** @@ -1988,7 +2055,7 @@ void AvmTraceBuilder::op_set( * @param src_offset Offset of source memory cell * @param dst_offset Offset of destination memory cell */ -void AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset, OpCode op_code) +AvmError AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset, OpCode op_code) { auto const clk = static_cast(main_trace.size()) + 1; @@ -2029,6 +2096,7 @@ void AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst ASSERT(op_code == OpCode::MOV_8 || op_code == OpCode::MOV_16); pc += Deserialization::get_pc_increment(op_code); + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /************************************************************************************************** @@ -2131,20 +2199,15 @@ Row AvmTraceBuilder::create_kernel_output_opcode_with_metadata(uint8_t indirect, * @return Row */ Row AvmTraceBuilder::create_kernel_output_opcode_with_set_metadata_output_from_hint( - uint8_t indirect, uint32_t clk, uint32_t data_offset, uint32_t address_offset, uint32_t metadata_offset) + uint32_t clk, uint32_t data_offset, [[maybe_unused]] uint32_t address_offset, uint32_t metadata_offset) { FF exists = execution_hints.get_side_effect_hints().at(side_effect_counter); - // TODO: resolved_address should be used - auto [resolved_data, resolved_address, resolved_metadata] = - Addressing<3>::fromWire(indirect, call_ptr) - .resolve({ data_offset, address_offset, metadata_offset }, mem_trace_builder); - auto read_a = constrained_read_from_memory( - call_ptr, clk, resolved_data, AvmMemoryTag::FF, AvmMemoryTag::U1, IntermRegister::IA); + call_ptr, clk, data_offset, AvmMemoryTag::FF, AvmMemoryTag::U1, IntermRegister::IA); auto write_b = constrained_write_to_memory( - call_ptr, clk, resolved_metadata, exists, AvmMemoryTag::FF, AvmMemoryTag::U1, IntermRegister::IB); + call_ptr, clk, metadata_offset, exists, AvmMemoryTag::FF, AvmMemoryTag::U1, IntermRegister::IB); bool tag_match = read_a.tag_match && write_b.tag_match; return Row{ @@ -2265,7 +2328,7 @@ Row AvmTraceBuilder::create_kernel_output_opcode_with_set_value_from_hint(uint8_ * WORLD STATE **************************************************************************************************/ -void AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t size, uint32_t dest_offset) +AvmError AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t size, uint32_t dest_offset) { auto clk = static_cast(main_trace.size()) + 1; @@ -2296,6 +2359,7 @@ void AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t // gas_trace_builder.constrain_gas(clk, OpCode::SLOAD); // clk++; + bool accumulated_tag_match = true; AddressWithMode write_dst = resolved_dest; // Loop over the size and write the hints to memory for (uint32_t i = 0; i < size; i++) { @@ -2321,6 +2385,7 @@ void AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t .main_w_in_tag = static_cast(AvmMemoryTag::FF), }; + accumulated_tag_match = accumulated_tag_match && write_a.tag_match; // Output storage read to kernel outputs (performs lookup) // Tuples of (slot, value) in the kernel lookup kernel_trace_builder.op_sload(clk, side_effect_counter, row.main_ib, row.main_ia); @@ -2340,9 +2405,10 @@ void AvmTraceBuilder::op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t write_dst = AddressWithMode{ AddressingMode::DIRECT, write_a.direct_address + 1 }; } pc += Deserialization::get_pc_increment(OpCode::SLOAD); + return accumulated_tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t size, uint32_t slot_offset) +AvmError AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t size, uint32_t slot_offset) { auto clk = static_cast(main_trace.size()) + 1; @@ -2374,6 +2440,7 @@ void AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t // clk++; AddressWithMode read_src = resolved_src; + bool accumulated_tag_match = true; // This loop reads a _size_ number of elements from memory and places them into a tuple of (ele, slot) // in the kernel lookup. @@ -2398,6 +2465,7 @@ void AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t }; row.main_sel_op_sstore = FF(1); kernel_trace_builder.op_sstore(clk, side_effect_counter, row.main_ib, row.main_ia); + accumulated_tag_match = accumulated_tag_match && read_a.tag_match; // Constrain gas cost // TODO: when/if we move this to its own gadget, and we have 1 row only, we should pass the size as @@ -2414,12 +2482,13 @@ void AvmTraceBuilder::op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t } pc += Deserialization::get_pc_increment(OpCode::SSTORE); + return accumulated_tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_note_hash_exists(uint8_t indirect, - uint32_t note_hash_offset, - uint32_t leaf_index_offset, - uint32_t dest_offset) +AvmError AvmTraceBuilder::op_note_hash_exists(uint8_t indirect, + uint32_t note_hash_offset, + uint32_t leaf_index_offset, + uint32_t dest_offset) { auto const clk = static_cast(main_trace.size()) + 1; @@ -2428,15 +2497,28 @@ void AvmTraceBuilder::op_note_hash_exists(uint8_t indirect, .resolve({ note_hash_offset, leaf_index_offset, dest_offset }, mem_trace_builder); const auto leaf_index = unconstrained_read_from_memory(resolved_leaf_index); - - Row row = create_kernel_output_opcode_for_leaf_index( - clk, resolved_note_hash, static_cast(leaf_index), resolved_dest); - - kernel_trace_builder.op_note_hash_exists(clk, - /*side_effect_counter*/ static_cast(leaf_index), - row.main_ia, - /*safe*/ static_cast(row.main_ib)); - row.main_sel_op_note_hash_exists = FF(1); + bool op_valid = check_tag(AvmMemoryTag::FF, resolved_leaf_index); + Row row; + + if (op_valid) { + row = create_kernel_output_opcode_for_leaf_index( + clk, resolved_note_hash, static_cast(leaf_index), resolved_dest); + + kernel_trace_builder.op_note_hash_exists(clk, + /*side_effect_counter*/ static_cast(leaf_index), + row.main_ia, + /*safe*/ static_cast(row.main_ib)); + row.main_sel_op_note_hash_exists = FF(1); + op_valid = op_valid && row.main_tag_err == FF(0); + } else { + row = Row{ + .main_clk = clk, + .main_internal_return_ptr = internal_return_ptr, + .main_op_err = FF(1), + .main_pc = pc, + .main_sel_op_note_hash_exists = FF(1), + }; + } // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::NOTEHASHEXISTS); @@ -2445,9 +2527,10 @@ void AvmTraceBuilder::op_note_hash_exists(uint8_t indirect, debug("note_hash_exists side-effect cnt: ", side_effect_counter); pc += Deserialization::get_pc_increment(OpCode::NOTEHASHEXISTS); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_emit_note_hash(uint8_t indirect, uint32_t note_hash_offset) +AvmError AvmTraceBuilder::op_emit_note_hash(uint8_t indirect, uint32_t note_hash_offset) { auto const clk = static_cast(main_trace.size()) + 1; @@ -2464,20 +2547,40 @@ void AvmTraceBuilder::op_emit_note_hash(uint8_t indirect, uint32_t note_hash_off side_effect_counter++; pc += Deserialization::get_pc_increment(OpCode::EMITNOTEHASH); + return row.main_tag_err == FF(0) ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_nullifier_exists(uint8_t indirect, - uint32_t nullifier_offset, - uint32_t address_offset, - uint32_t dest_offset) +AvmError AvmTraceBuilder::op_nullifier_exists(uint8_t indirect, + uint32_t nullifier_offset, + uint32_t address_offset, + uint32_t dest_offset) { auto const clk = static_cast(main_trace.size()) + 1; - Row row = create_kernel_output_opcode_with_set_metadata_output_from_hint( - indirect, clk, nullifier_offset, address_offset, dest_offset); - kernel_trace_builder.op_nullifier_exists( - clk, side_effect_counter, row.main_ia, /*safe*/ static_cast(row.main_ib)); - row.main_sel_op_nullifier_exists = FF(1); + auto [resolved_nullifier_offset, resolved_address, resolved_dest] = + Addressing<3>::fromWire(indirect, call_ptr) + .resolve({ nullifier_offset, address_offset, dest_offset }, mem_trace_builder); + + bool op_valid = check_tag(AvmMemoryTag::FF, resolved_address); + + Row row; + + if (op_valid) { + row = create_kernel_output_opcode_with_set_metadata_output_from_hint( + clk, resolved_nullifier_offset, resolved_address, resolved_dest); + kernel_trace_builder.op_nullifier_exists( + clk, side_effect_counter, row.main_ia, /*safe*/ static_cast(row.main_ib)); + row.main_sel_op_nullifier_exists = FF(1); + op_valid = op_valid && row.main_tag_err == FF(0); + } else { + row = Row{ + .main_clk = clk, + .main_internal_return_ptr = internal_return_ptr, + .main_op_err = FF(1), + .main_pc = pc, + .main_sel_op_nullifier_exists = FF(1), + }; + } // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::NULLIFIEREXISTS); @@ -2488,9 +2591,10 @@ void AvmTraceBuilder::op_nullifier_exists(uint8_t indirect, side_effect_counter++; pc += Deserialization::get_pc_increment(OpCode::NULLIFIEREXISTS); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_emit_nullifier(uint8_t indirect, uint32_t nullifier_offset) +AvmError AvmTraceBuilder::op_emit_nullifier(uint8_t indirect, uint32_t nullifier_offset) { auto const clk = static_cast(main_trace.size()) + 1; @@ -2507,12 +2611,13 @@ void AvmTraceBuilder::op_emit_nullifier(uint8_t indirect, uint32_t nullifier_off side_effect_counter++; pc += Deserialization::get_pc_increment(OpCode::EMITNULLIFIER); + return row.main_tag_err == FF(0) ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_l1_to_l2_msg_exists(uint8_t indirect, - uint32_t log_offset, - uint32_t leaf_index_offset, - uint32_t dest_offset) +AvmError AvmTraceBuilder::op_l1_to_l2_msg_exists(uint8_t indirect, + uint32_t log_offset, + uint32_t leaf_index_offset, + uint32_t dest_offset) { auto const clk = static_cast(main_trace.size()) + 1; @@ -2521,14 +2626,27 @@ void AvmTraceBuilder::op_l1_to_l2_msg_exists(uint8_t indirect, .resolve({ log_offset, leaf_index_offset, dest_offset }, mem_trace_builder); const auto leaf_index = unconstrained_read_from_memory(resolved_leaf_index); - - Row row = - create_kernel_output_opcode_for_leaf_index(clk, resolved_log, static_cast(leaf_index), resolved_dest); - kernel_trace_builder.op_l1_to_l2_msg_exists(clk, - static_cast(leaf_index) /*side_effect_counter*/, - row.main_ia, - /*safe*/ static_cast(row.main_ib)); - row.main_sel_op_l1_to_l2_msg_exists = FF(1); + bool op_valid = check_tag(AvmMemoryTag::FF, resolved_leaf_index); + Row row; + + if (op_valid) { + row = create_kernel_output_opcode_for_leaf_index( + clk, resolved_log, static_cast(leaf_index), resolved_dest); + kernel_trace_builder.op_l1_to_l2_msg_exists(clk, + static_cast(leaf_index) /*side_effect_counter*/, + row.main_ia, + /*safe*/ static_cast(row.main_ib)); + row.main_sel_op_l1_to_l2_msg_exists = FF(1); + op_valid = op_valid && row.main_tag_err == FF(0); + } else { + row = Row{ + .main_clk = clk, + .main_internal_return_ptr = internal_return_ptr, + .main_op_err = FF(1), + .main_pc = pc, + .main_sel_op_l1_to_l2_msg_exists = FF(1), + }; + } // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::L1TOL2MSGEXISTS); @@ -2538,9 +2656,10 @@ void AvmTraceBuilder::op_l1_to_l2_msg_exists(uint8_t indirect, debug("l1_to_l2_msg_exists side-effect cnt: ", side_effect_counter); pc += Deserialization::get_pc_increment(OpCode::L1TOL2MSGEXISTS); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_get_contract_instance( +AvmError AvmTraceBuilder::op_get_contract_instance( uint8_t indirect, uint8_t member_enum, uint16_t address_offset, uint16_t dst_offset, uint16_t exists_offset) { auto clk = static_cast(main_trace.size()) + 1; @@ -2560,93 +2679,92 @@ void AvmTraceBuilder::op_get_contract_instance( }; main_trace.push_back(row); pc += Deserialization::get_pc_increment(OpCode::GETCONTRACTINSTANCE); - } else { - - ContractInstanceMember chosen_member = static_cast(member_enum); - - auto [resolved_address_offset, resolved_dst_offset, resolved_exists_offset] = - Addressing<3>::fromWire(indirect, call_ptr) - .resolve({ address_offset, dst_offset, exists_offset }, mem_trace_builder); - - auto read_address = constrained_read_from_memory( - call_ptr, clk, resolved_address_offset, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); - bool tag_match = read_address.tag_match; + return AvmError::CONTRACT_INST_MEM_UNKNOWN; + }; - // Read the contract instance - ContractInstanceHint instance = execution_hints.contract_instance_hints.at(read_address.val); + ContractInstanceMember chosen_member = static_cast(member_enum); - FF member_value; - switch (chosen_member) { - case ContractInstanceMember::DEPLOYER: - member_value = instance.deployer_addr; - break; - case ContractInstanceMember::CLASS_ID: - member_value = instance.contract_class_id; - break; - case ContractInstanceMember::INIT_HASH: - member_value = instance.initialisation_hash; - break; - default: - member_value = 0; - break; - } + auto [resolved_address_offset, resolved_dst_offset, resolved_exists_offset] = + Addressing<3>::fromWire(indirect, call_ptr) + .resolve({ address_offset, dst_offset, exists_offset }, mem_trace_builder); + + auto read_address = constrained_read_from_memory( + call_ptr, clk, resolved_address_offset, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IA); + bool tag_match = read_address.tag_match; + + // Read the contract instance + ContractInstanceHint instance = execution_hints.contract_instance_hints.at(read_address.val); + + FF member_value; + switch (chosen_member) { + case ContractInstanceMember::DEPLOYER: + member_value = instance.deployer_addr; + break; + case ContractInstanceMember::CLASS_ID: + member_value = instance.contract_class_id; + break; + case ContractInstanceMember::INIT_HASH: + member_value = instance.initialisation_hash; + break; + default: + member_value = 0; + break; + } - // TODO(8603): once instructions can have multiple different tags for writes, write dst as FF and exists as U1 - // auto write_dst = constrained_write_to_memory(call_ptr, clk, resolved_dst_offset, member_value, - // AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IC); auto write_exists = - // constrained_write_to_memory(call_ptr, clk, resolved_exists_offset, instance.instance_found_in_address, - // AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::ID); + // TODO(8603): once instructions can have multiple different tags for writes, write dst as FF and exists as + // U1 auto write_dst = constrained_write_to_memory(call_ptr, clk, resolved_dst_offset, member_value, + // AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::IC); auto write_exists = + // constrained_write_to_memory(call_ptr, clk, resolved_exists_offset, instance.instance_found_in_address, + // AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::ID); - main_trace.push_back(Row{ - .main_clk = clk, - .main_call_ptr = call_ptr, - .main_ia = read_address.val, - // TODO(8603): uncomment this and below blocks once instructions can have multiple different tags for - // writes - //.main_ic = write_dst.val, - //.main_id = write_exists.val, - .main_ind_addr_a = FF(read_address.indirect_address), - //.main_ind_addr_c = FF(write_dst.indirect_address), - //.main_ind_addr_d = FF(write_exists.indirect_address), - .main_internal_return_ptr = FF(internal_return_ptr), - .main_mem_addr_a = FF(read_address.direct_address), - //.main_mem_addr_c = FF(write_dst.direct_address), - //.main_mem_addr_d = FF(write_exists.direct_address), - .main_pc = FF(pc), - .main_r_in_tag = FF(static_cast(AvmMemoryTag::FF)), - .main_sel_mem_op_a = FF(1), - //.main_sel_mem_op_c = FF(1), - //.main_sel_mem_op_d = FF(1), - .main_sel_op_get_contract_instance = FF(1), - .main_sel_resolve_ind_addr_a = FF(static_cast(read_address.is_indirect)), - //.main_sel_resolve_ind_addr_c = FF(static_cast(write_dst.is_indirect)), - //.main_sel_resolve_ind_addr_d = FF(static_cast(write_exists.is_indirect)), - .main_tag_err = FF(static_cast(!tag_match)), - }); + main_trace.push_back(Row{ + .main_clk = clk, + .main_call_ptr = call_ptr, + .main_ia = read_address.val, + // TODO(8603): uncomment this and below blocks once instructions can have multiple different tags for + // writes + //.main_ic = write_dst.val, + //.main_id = write_exists.val, + .main_ind_addr_a = FF(read_address.indirect_address), + //.main_ind_addr_c = FF(write_dst.indirect_address), + //.main_ind_addr_d = FF(write_exists.indirect_address), + .main_internal_return_ptr = FF(internal_return_ptr), + .main_mem_addr_a = FF(read_address.direct_address), + //.main_mem_addr_c = FF(write_dst.direct_address), + //.main_mem_addr_d = FF(write_exists.direct_address), + .main_pc = FF(pc), + .main_r_in_tag = FF(static_cast(AvmMemoryTag::FF)), + .main_sel_mem_op_a = FF(1), + //.main_sel_mem_op_c = FF(1), + //.main_sel_mem_op_d = FF(1), + .main_sel_op_get_contract_instance = FF(1), + .main_sel_resolve_ind_addr_a = FF(static_cast(read_address.is_indirect)), + //.main_sel_resolve_ind_addr_c = FF(static_cast(write_dst.is_indirect)), + //.main_sel_resolve_ind_addr_d = FF(static_cast(write_exists.is_indirect)), + .main_tag_err = FF(static_cast(!tag_match)), + }); - pc += Deserialization::get_pc_increment(OpCode::GETCONTRACTINSTANCE); + pc += Deserialization::get_pc_increment(OpCode::GETCONTRACTINSTANCE); - // Crucial to perform this operation after having incremented pc because write_slice_to_memory - // is implemented with opcodes (SET and JUMP). - // TODO(8603): once instructions can have multiple different tags for writes, remove this and do a constrained - // writes - write_to_memory(resolved_dst_offset, member_value, AvmMemoryTag::FF); - write_to_memory(resolved_exists_offset, FF(static_cast(instance.exists)), AvmMemoryTag::U1); + // Crucial to perform this operation after having incremented pc because write_slice_to_memory + // is implemented with opcodes (SET and JUMP). + // TODO(8603): once instructions can have multiple different tags for writes, remove this and do a + // constrained writes + write_to_memory(resolved_dst_offset, member_value, AvmMemoryTag::FF); + write_to_memory(resolved_exists_offset, FF(static_cast(instance.exists)), AvmMemoryTag::U1); - // TODO(dbanks12): compute contract address nullifier from instance preimage and perform membership check + // TODO(dbanks12): compute contract address nullifier from instance preimage and perform membership check - debug("contract_instance cnt: ", side_effect_counter); - side_effect_counter++; - } + debug("contract_instance cnt: ", side_effect_counter); + side_effect_counter++; + return tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /************************************************************************************************** * ACCRUED SUBSTATE **************************************************************************************************/ -void AvmTraceBuilder::op_emit_unencrypted_log(uint8_t indirect, - uint32_t log_offset, - [[maybe_unused]] uint32_t log_size_offset) +AvmError AvmTraceBuilder::op_emit_unencrypted_log(uint8_t indirect, uint32_t log_offset, uint32_t log_size_offset) { std::vector bytes_to_hash; @@ -2657,7 +2775,7 @@ void AvmTraceBuilder::op_emit_unencrypted_log(uint8_t indirect, Addressing<2>::fromWire(indirect, call_ptr).resolve({ log_offset, log_size_offset }, mem_trace_builder); // This is a hack to get the contract address from the first contract instance - // Once we have 1-enqueued call and proper nested contexts, this should use that address of the current contextt + // Once we have 1-enqueued call and proper nested contexts, this should use that address of the current context FF contract_address = execution_hints.all_contract_bytecode.at(0).contract_instance.address; std::vector contract_address_bytes = contract_address.to_buffer(); @@ -2666,46 +2784,68 @@ void AvmTraceBuilder::op_emit_unencrypted_log(uint8_t indirect, std::make_move_iterator(contract_address_bytes.begin()), std::make_move_iterator(contract_address_bytes.end())); - uint32_t log_size = static_cast(unconstrained_read_from_memory(resolved_log_size_offset)); - // The size is in fields of 32 bytes, the length used for the hash is in terms of bytes - uint32_t num_bytes = log_size * 32; - std::vector log_size_bytes = to_buffer(num_bytes); - // Add the log size to the hash to bytes - bytes_to_hash.insert(bytes_to_hash.end(), - std::make_move_iterator(log_size_bytes.begin()), - std::make_move_iterator(log_size_bytes.end())); - - AddressWithMode direct_field_addr = AddressWithMode(static_cast(resolved_log_offset)); - // We need to read the rest of the log_size number of elements - std::vector log_value_bytes; - for (uint32_t i = 0; i < log_size; i++) { - FF log_value = unconstrained_read_from_memory(direct_field_addr + i); - std::vector log_value_byte = log_value.to_buffer(); + bool op_valid = + check_tag(AvmMemoryTag::FF, resolved_log_offset) && check_tag(AvmMemoryTag::U32, resolved_log_size_offset); + + Row row; + uint32_t log_size = 0; + AddressWithMode direct_field_addr; + uint32_t num_bytes = 0; + + if (op_valid) { + log_size = static_cast(unconstrained_read_from_memory(resolved_log_size_offset)); + + // The size is in fields of 32 bytes, the length used for the hash is in terms of bytes + num_bytes = log_size * 32; + std::vector log_size_bytes = to_buffer(num_bytes); + // Add the log size to the hash to bytes bytes_to_hash.insert(bytes_to_hash.end(), - std::make_move_iterator(log_value_byte.begin()), - std::make_move_iterator(log_value_byte.end())); - } - - std::array output = crypto::sha256(bytes_to_hash); - // Truncate the hash to 31 bytes so it will be a valid field element - FF trunc_hash = FF(from_buffer(output.data()) >> 8); - - // The + 32 here is for the contract_address in bytes, the +4 is for the extra 4 bytes that contain log_size and - // is prefixed to message see toBuffer in unencrypted_l2_log.ts - FF length_of_preimage = num_bytes + 32 + 4; - // The + 4 is because the kernels store the length of the - // processed log as 4 bytes; thus for this length value to match the log length stored in the kernels, we need - // to add four to the length here. [Copied from unencrypted_l2_log.ts] - FF metadata_log_length = length_of_preimage + 4; - Row row = Row{ - .main_clk = clk, - .main_ia = trunc_hash, - .main_ib = metadata_log_length, - .main_internal_return_ptr = internal_return_ptr, - .main_pc = pc, - }; - kernel_trace_builder.op_emit_unencrypted_log(clk, side_effect_counter, trunc_hash, metadata_log_length); - row.main_sel_op_emit_unencrypted_log = FF(1); + std::make_move_iterator(log_size_bytes.begin()), + std::make_move_iterator(log_size_bytes.end())); + + direct_field_addr = AddressWithMode(static_cast(resolved_log_offset)); + op_valid = op_valid && check_tag_range(AvmMemoryTag::FF, direct_field_addr, log_size); + } + + if (op_valid) { + // We need to read the rest of the log_size number of elements + for (uint32_t i = 0; i < log_size; i++) { + FF log_value = unconstrained_read_from_memory(direct_field_addr + i); + std::vector log_value_byte = log_value.to_buffer(); + bytes_to_hash.insert(bytes_to_hash.end(), + std::make_move_iterator(log_value_byte.begin()), + std::make_move_iterator(log_value_byte.end())); + } + + std::array output = crypto::sha256(bytes_to_hash); + // Truncate the hash to 31 bytes so it will be a valid field element + FF trunc_hash = FF(from_buffer(output.data()) >> 8); + + // The + 32 here is for the contract_address in bytes, the +4 is for the extra 4 bytes that contain log_size + // and is prefixed to message see toBuffer in unencrypted_l2_log.ts + FF length_of_preimage = num_bytes + 32 + 4; + // The + 4 is because the kernels store the length of the + // processed log as 4 bytes; thus for this length value to match the log length stored in the kernels, we + // need to add four to the length here. [Copied from unencrypted_l2_log.ts] + FF metadata_log_length = length_of_preimage + 4; + row = Row{ + .main_clk = clk, + .main_ia = trunc_hash, + .main_ib = metadata_log_length, + .main_internal_return_ptr = internal_return_ptr, + .main_pc = pc, + }; + kernel_trace_builder.op_emit_unencrypted_log(clk, side_effect_counter, trunc_hash, metadata_log_length); + row.main_sel_op_emit_unencrypted_log = FF(1); + } else { + row = Row{ + .main_clk = clk, + .main_internal_return_ptr = internal_return_ptr, + .main_op_err = FF(1), + .main_pc = pc, + .main_sel_op_emit_unencrypted_log = FF(1), + }; + } // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::EMITUNENCRYPTEDLOG, static_cast(log_size)); @@ -2715,9 +2855,10 @@ void AvmTraceBuilder::op_emit_unencrypted_log(uint8_t indirect, debug("emit_unencrypted_log side-effect cnt: ", side_effect_counter); side_effect_counter++; pc += Deserialization::get_pc_increment(OpCode::EMITUNENCRYPTEDLOG); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } -void AvmTraceBuilder::op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipient_offset, uint32_t content_offset) +AvmError AvmTraceBuilder::op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipient_offset, uint32_t content_offset) { auto const clk = static_cast(main_trace.size()) + 1; @@ -2736,6 +2877,7 @@ void AvmTraceBuilder::op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipient_ side_effect_counter++; pc += Deserialization::get_pc_increment(OpCode::SENDL2TOL1MSG); + return row.main_tag_err == FF(0) ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /************************************************************************************************** @@ -2743,13 +2885,13 @@ void AvmTraceBuilder::op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipient_ **************************************************************************************************/ // Helper/implementation for CALL and STATICCALL -void AvmTraceBuilder::constrain_external_call(OpCode opcode, - uint16_t indirect, - uint32_t gas_offset, - uint32_t addr_offset, - uint32_t args_offset, - uint32_t args_size_offset, - uint32_t success_offset) +AvmError AvmTraceBuilder::constrain_external_call(OpCode opcode, + uint16_t indirect, + uint32_t gas_offset, + uint32_t addr_offset, + uint32_t args_offset, + uint32_t args_size_offset, + uint32_t success_offset) { ASSERT(opcode == OpCode::CALL || opcode == OpCode::STATICCALL); auto clk = static_cast(main_trace.size()) + 1; @@ -2774,8 +2916,10 @@ void AvmTraceBuilder::constrain_external_call(OpCode opcode, call_ptr, clk, resolved_args_offset, AvmMemoryTag::FF, AvmMemoryTag::FF, IntermRegister::ID); bool tag_match = read_gas_l2.tag_match && read_gas_da.tag_match && read_addr.tag_match && read_args.tag_match; + bool op_valid = check_tag(AvmMemoryTag::U32, resolved_args_size_offset); + // TODO: constrain this - auto args_size = static_cast(unconstrained_read_from_memory(resolved_args_size_offset)); + auto args_size = op_valid ? static_cast(unconstrained_read_from_memory(resolved_args_size_offset)) : 0; gas_trace_builder.constrain_gas(clk, opcode, @@ -2797,6 +2941,7 @@ void AvmTraceBuilder::constrain_external_call(OpCode opcode, .main_mem_addr_b = FF(read_gas_l2.direct_address + 1), .main_mem_addr_c = FF(read_addr.direct_address), .main_mem_addr_d = FF(read_args.direct_address), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(AvmMemoryTag::FF)), .main_sel_mem_op_a = FF(1), @@ -2826,6 +2971,7 @@ void AvmTraceBuilder::constrain_external_call(OpCode opcode, if (opcode == OpCode::CALL) { side_effect_counter = static_cast(hint.end_side_effect_counter); } + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /** @@ -2841,12 +2987,12 @@ void AvmTraceBuilder::constrain_external_call(OpCode opcode, * @param success_offset An index in memory pointing to where the success flag (U1) of the external call should be * stored */ -void AvmTraceBuilder::op_call(uint16_t indirect, - uint32_t gas_offset, - uint32_t addr_offset, - uint32_t args_offset, - uint32_t args_size_offset, - uint32_t success_offset) +AvmError AvmTraceBuilder::op_call(uint16_t indirect, + uint32_t gas_offset, + uint32_t addr_offset, + uint32_t args_offset, + uint32_t args_size_offset, + uint32_t success_offset) { return constrain_external_call( OpCode::CALL, indirect, gas_offset, addr_offset, args_offset, args_size_offset, success_offset); @@ -2865,12 +3011,12 @@ void AvmTraceBuilder::op_call(uint16_t indirect, * @param success_offset An index in memory pointing to where the success flag (U8) of the static call should be * stored */ -void AvmTraceBuilder::op_static_call(uint16_t indirect, - uint32_t gas_offset, - uint32_t addr_offset, - uint32_t args_offset, - uint32_t args_size_offset, - uint32_t success_offset) +AvmError AvmTraceBuilder::op_static_call(uint16_t indirect, + uint32_t gas_offset, + uint32_t addr_offset, + uint32_t args_offset, + uint32_t args_size_offset, + uint32_t success_offset) { return constrain_external_call( OpCode::STATICCALL, indirect, gas_offset, addr_offset, args_offset, args_size_offset, success_offset); @@ -2891,7 +3037,7 @@ void AvmTraceBuilder::op_static_call(uint16_t indirect, * @param ret_size The number of elements to be returned. * @return The returned memory region as a std::vector. */ -std::vector AvmTraceBuilder::op_return(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size_offset) +ReturnDataError AvmTraceBuilder::op_return(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size_offset) { auto clk = static_cast(main_trace.size()) + 1; @@ -2901,6 +3047,8 @@ std::vector AvmTraceBuilder::op_return(uint8_t indirect, uint32_t ret_offset // Resolve operands auto [resolved_ret_offset, resolved_ret_size_offset] = Addressing<2>::fromWire(indirect, call_ptr).resolve({ ret_offset, ret_size_offset }, mem_trace_builder); + + bool op_valid = tag_match && check_tag(AvmMemoryTag::U32, resolved_ret_size_offset); const auto ret_size = static_cast(unconstrained_read_from_memory(resolved_ret_size_offset)); gas_trace_builder.constrain_gas(clk, OpCode::RETURN, ret_size); @@ -2911,12 +3059,17 @@ std::vector AvmTraceBuilder::op_return(uint8_t indirect, uint32_t ret_offset .main_call_ptr = call_ptr, .main_ib = ret_size, .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = static_cast(!op_valid), .main_pc = pc, .main_sel_op_external_return = 1, }); pc = UINT32_MAX; // This ensures that no subsequent opcode will be executed. - return {}; + + return ReturnDataError{ + .return_data = {}, + .error = op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR, + }; } // The only memory operation performed from the main trace is a possible indirect load for resolving the @@ -2934,6 +3087,7 @@ std::vector AvmTraceBuilder::op_return(uint8_t indirect, uint32_t ret_offset .main_ib = ret_size, .main_internal_return_ptr = FF(internal_return_ptr), .main_mem_addr_c = resolved_ret_offset, + .main_op_err = static_cast(!op_valid), .main_pc = pc, .main_r_in_tag = static_cast(AvmMemoryTag::FF), .main_sel_op_external_return = 1, @@ -2943,10 +3097,14 @@ std::vector AvmTraceBuilder::op_return(uint8_t indirect, uint32_t ret_offset }); pc = UINT32_MAX; // This ensures that no subsequent opcode will be executed. - return returndata; + + return ReturnDataError{ + .return_data = returndata, + .error = op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR, + }; } -std::vector AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size_offset) +ReturnDataError AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size_offset) { // TODO: This opcode is still masquerading as RETURN. auto clk = static_cast(main_trace.size()) + 1; @@ -2956,7 +3114,10 @@ std::vector AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset auto [resolved_ret_offset, resolved_ret_size_offset] = Addressing<2>::fromWire(indirect, call_ptr).resolve({ ret_offset, ret_size_offset }, mem_trace_builder); - const auto ret_size = static_cast(unconstrained_read_from_memory(resolved_ret_size_offset)); + + bool op_valid = check_tag(AvmMemoryTag::U32, ret_size_offset); + const auto ret_size = + op_valid ? static_cast(unconstrained_read_from_memory(resolved_ret_size_offset)) : 0; gas_trace_builder.constrain_gas(clk, OpCode::REVERT_8, ret_size); @@ -2967,12 +3128,16 @@ std::vector AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset .main_call_ptr = call_ptr, .main_ib = ret_size, .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = pc, .main_sel_op_external_return = 1, }); pc = UINT32_MAX; // This ensures that no subsequent opcode will be executed. - return {}; + return ReturnDataError{ + .return_data = {}, + .error = op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR, + }; } // The only memory operation performed from the main trace is a possible indirect load for resolving the @@ -2983,6 +3148,7 @@ std::vector AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset slice_trace_builder.create_return_slice(returndata, clk, call_ptr, resolved_ret_offset, ret_size); } + // TODO: fix and set sel_op_revert main_trace.push_back(Row{ .main_clk = clk, .main_call_ptr = call_ptr, @@ -2998,7 +3164,55 @@ std::vector AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset }); pc = UINT32_MAX; // This ensures that no subsequent opcode will be executed. - return returndata; + + // op_valid == true otherwise, ret_size == 0 and we would have returned above. + return ReturnDataError{ + .return_data = returndata, + .error = tag_match ? AvmError::NO_ERROR : AvmError::TAG_ERROR, + }; +} + +/************************************************************************************************** + * MISC + **************************************************************************************************/ + +AvmError AvmTraceBuilder::op_debug_log(uint8_t indirect, + uint32_t message_offset, + uint32_t message_size, + uint32_t fields_offset, + uint32_t fields_size_offset) +{ + auto clk = static_cast(main_trace.size()) + 1; + + auto [resolved_message_offset, resolved_fields_offset, resolved_fields_size_offset] = + Addressing<3>::fromWire(indirect, call_ptr) + .resolve({ message_offset, fields_offset, fields_size_offset }, mem_trace_builder); + + // Tags checking + bool op_valid = check_tag(AvmMemoryTag::U32, resolved_fields_size_offset); + + const uint32_t fields_size = + op_valid ? static_cast(unconstrained_read_from_memory(resolved_fields_size_offset)) : 0; + + // Constrain gas cost + gas_trace_builder.constrain_gas(clk, OpCode::DEBUGLOG, message_size + fields_size); + + if (op_valid) { + op_valid = op_valid && check_tag_range(AvmMemoryTag::U8, resolved_message_offset, message_size) && + check_tag_range(AvmMemoryTag::FF, resolved_fields_offset, fields_size); + } + + main_trace.push_back(Row{ + .main_clk = clk, + .main_call_ptr = call_ptr, + .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = FF(static_cast(!op_valid)), + .main_pc = FF(pc), + .main_sel_op_debug_log = FF(1), + }); + + pc += Deserialization::get_pc_increment(OpCode::DEBUGLOG); + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /************************************************************************************************** @@ -3014,7 +3228,7 @@ std::vector AvmTraceBuilder::op_revert(uint8_t indirect, uint32_t ret_offset * @param output_offset An index in memory pointing to where the first Field value of the output array should be * stored. */ -void AvmTraceBuilder::op_poseidon2_permutation(uint8_t indirect, uint32_t input_offset, uint32_t output_offset) +AvmError AvmTraceBuilder::op_poseidon2_permutation(uint8_t indirect, uint32_t input_offset, uint32_t output_offset) { auto clk = static_cast(main_trace.size()) + 1; @@ -3029,16 +3243,6 @@ void AvmTraceBuilder::op_poseidon2_permutation(uint8_t indirect, uint32_t input_ // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::POSEIDON2PERM); - // Main trace contains on operand values from the bytecode and resolved indirects - main_trace.push_back(Row{ - .main_clk = clk, - .main_internal_return_ptr = FF(internal_return_ptr), - .main_mem_addr_a = resolved_input_offset, - .main_mem_addr_b = resolved_output_offset, - .main_pc = FF(pc), - .main_sel_op_poseidon2 = FF(1), - }); - // These read patterns will be refactored - we perform them here instead of in the poseidon gadget trace // even though they are "performed" by the gadget. AddressWithMode direct_src_offset = { AddressingMode::DIRECT, resolved_input_offset }; @@ -3072,51 +3276,70 @@ void AvmTraceBuilder::op_poseidon2_permutation(uint8_t indirect, uint32_t input_ IntermRegister::ID, AvmMemTraceBuilder::POSEIDON2); - std::array input = { read_a.val, read_b.val, read_c.val, read_d.val }; - std::array result = poseidon2_trace_builder.poseidon2_permutation( - input, call_ptr, clk, resolved_input_offset, resolved_output_offset); + bool op_valid = read_a.tag_match && read_b.tag_match && read_c.tag_match && read_d.tag_match; - std::vector ff_result; - for (uint32_t i = 0; i < 4; i++) { - ff_result.emplace_back(result[i]); + if (op_valid) { + std::array input = { read_a.val, read_b.val, read_c.val, read_d.val }; + std::array result = poseidon2_trace_builder.poseidon2_permutation( + input, call_ptr, clk, resolved_input_offset, resolved_output_offset); + + std::vector ff_result; + for (uint32_t i = 0; i < 4; i++) { + ff_result.emplace_back(result[i]); + } + // Write the result to memory after, see the comments at read to understand why this happens here. + AddressWithMode direct_dst_offset = { AddressingMode::DIRECT, resolved_output_offset }; + auto write_a = constrained_write_to_memory(call_ptr, + clk, + direct_dst_offset, + ff_result[0], + AvmMemoryTag::FF, + AvmMemoryTag::FF, + IntermRegister::IA, + AvmMemTraceBuilder::POSEIDON2); + auto write_b = constrained_write_to_memory(call_ptr, + clk, + direct_dst_offset + 1, + ff_result[1], + AvmMemoryTag::FF, + AvmMemoryTag::FF, + IntermRegister::IB, + AvmMemTraceBuilder::POSEIDON2); + auto write_c = constrained_write_to_memory(call_ptr, + clk, + direct_dst_offset + 2, + ff_result[2], + AvmMemoryTag::FF, + AvmMemoryTag::FF, + IntermRegister::IC, + AvmMemTraceBuilder::POSEIDON2); + + auto write_d = constrained_write_to_memory(call_ptr, + clk, + direct_dst_offset + 3, + ff_result[3], + AvmMemoryTag::FF, + AvmMemoryTag::FF, + IntermRegister::ID, + AvmMemTraceBuilder::POSEIDON2); + + op_valid = write_a.tag_match && write_b.tag_match && write_c.tag_match && write_d.tag_match; } - // Write the result to memory after, see the comments at read to understand why this happens here. - AddressWithMode direct_dst_offset = { AddressingMode::DIRECT, resolved_output_offset }; - constrained_write_to_memory(call_ptr, - clk, - direct_dst_offset, - ff_result[0], - AvmMemoryTag::FF, - AvmMemoryTag::FF, - IntermRegister::IA, - AvmMemTraceBuilder::POSEIDON2); - constrained_write_to_memory(call_ptr, - clk, - direct_dst_offset + 1, - ff_result[1], - AvmMemoryTag::FF, - AvmMemoryTag::FF, - IntermRegister::IB, - AvmMemTraceBuilder::POSEIDON2); - constrained_write_to_memory(call_ptr, - clk, - direct_dst_offset + 2, - ff_result[2], - AvmMemoryTag::FF, - AvmMemoryTag::FF, - IntermRegister::IC, - AvmMemTraceBuilder::POSEIDON2); - - constrained_write_to_memory(call_ptr, - clk, - direct_dst_offset + 3, - ff_result[3], - AvmMemoryTag::FF, - AvmMemoryTag::FF, - IntermRegister::ID, - AvmMemTraceBuilder::POSEIDON2); + + // Main trace contains on operand values from the bytecode and resolved indirects + main_trace.push_back(Row{ + .main_clk = clk, + .main_internal_return_ptr = FF(internal_return_ptr), + .main_mem_addr_a = resolved_input_offset, + .main_mem_addr_b = resolved_output_offset, + .main_op_err = FF(static_cast(!op_valid)), + .main_pc = FF(pc), + .main_sel_op_poseidon2 = FF(1), + }); pc += Deserialization::get_pc_increment(OpCode::POSEIDON2PERM); + + return op_valid ? AvmError::NO_ERROR : AvmError::TAG_ERROR; } /** @@ -3130,11 +3353,14 @@ void AvmTraceBuilder::op_poseidon2_permutation(uint8_t indirect, uint32_t input_ * @param output_offset An index in memory pointing to where the first U32 value of the output array should be * stored. */ -void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, - uint32_t output_offset, - uint32_t state_offset, - uint32_t inputs_offset) +AvmError AvmTraceBuilder::op_sha256_compression(uint8_t indirect, + uint32_t output_offset, + uint32_t state_offset, + uint32_t inputs_offset) { + const uint32_t STATE_SIZE = 8; + const uint32_t INPUTS_SIZE = 16; + // The clk plays a crucial role in this function as we attempt to write across multiple lines in the main trace. auto clk = static_cast(main_trace.size()) + 1; @@ -3150,6 +3376,9 @@ void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, call_ptr, clk, resolved_inputs_offset, AvmMemoryTag::U32, AvmMemoryTag::FF, IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; + bool op_valid = tag_match && check_tag_range(AvmMemoryTag::U32, resolved_state_offset, STATE_SIZE) && + check_tag_range(AvmMemoryTag::U32, resolved_inputs_offset, INPUTS_SIZE); + // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::SHA256COMPRESSION); @@ -3170,6 +3399,7 @@ void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, .main_internal_return_ptr = FF(internal_return_ptr), .main_mem_addr_a = FF(read_a.direct_address), .main_mem_addr_b = FF(read_b.direct_address), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(AvmMemoryTag::U32)), .main_sel_mem_op_a = FF(1), @@ -3179,6 +3409,11 @@ void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, .main_sel_resolve_ind_addr_b = FF(static_cast(read_b.is_indirect)), .main_tag_err = FF(static_cast(!tag_match)), }); + + if (!op_valid) { + return AvmError::TAG_ERROR; + } + // We store the current clk this main trace row occurred so that we can line up the sha256 gadget operation at // the same clk later. auto sha_op_clk = clk; @@ -3211,6 +3446,8 @@ void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, // Crucial to perform this operation after having incremented pc because write_slice_to_memory // is implemented with opcodes (SET and JUMP). write_slice_to_memory(resolved_output_offset, AvmMemoryTag::U32, ff_result); + + return AvmError::NO_ERROR; } /** @@ -3221,39 +3458,39 @@ void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, * @param input_offset An index in memory pointing to the first u64 value of the input array to be used in the next * instance of keccakf1600. */ -void AvmTraceBuilder::op_keccakf1600(uint8_t indirect, uint32_t output_offset, uint32_t input_offset) +AvmError AvmTraceBuilder::op_keccakf1600(uint8_t indirect, uint32_t output_offset, uint32_t input_offset) { auto clk = static_cast(main_trace.size()) + 1; auto [resolved_output_offset, resolved_input_offset] = Addressing<2>::fromWire(indirect, call_ptr).resolve({ output_offset, input_offset }, mem_trace_builder); auto input_read = constrained_read_from_memory( call_ptr, clk, resolved_input_offset, AvmMemoryTag::U64, AvmMemoryTag::FF, IntermRegister::IA); - auto output_read = constrained_read_from_memory( - call_ptr, clk, resolved_output_offset, AvmMemoryTag::U64, AvmMemoryTag::FF, IntermRegister::IC); - bool tag_match = input_read.tag_match && output_read.tag_match; + bool tag_match = input_read.tag_match; + + bool op_valid = tag_match && check_tag_range(AvmMemoryTag::U64, resolved_input_offset, KECCAKF1600_INPUT_SIZE); // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::KECCAKF1600); main_trace.push_back(Row{ .main_clk = clk, - .main_ia = input_read.val, // First element of input - .main_ic = output_read.val, // First element of output + .main_ia = input_read.val, // First element of input .main_ind_addr_a = FF(input_read.indirect_address), - .main_ind_addr_c = FF(output_read.indirect_address), .main_internal_return_ptr = FF(internal_return_ptr), .main_mem_addr_a = FF(input_read.direct_address), - .main_mem_addr_c = FF(output_read.direct_address), + .main_op_err = FF(static_cast(!op_valid)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(AvmMemoryTag::U64)), .main_sel_mem_op_a = FF(1), - .main_sel_mem_op_c = FF(1), .main_sel_op_keccak = FF(1), .main_sel_resolve_ind_addr_a = FF(static_cast(input_read.is_indirect)), - .main_sel_resolve_ind_addr_c = FF(static_cast(output_read.is_indirect)), .main_tag_err = FF(static_cast(!tag_match)), }); + if (!op_valid) { + return AvmError::TAG_ERROR; + } + // Array input is fixed to 1600 bits std::vector input_vec; // Read results are written to input array @@ -3270,16 +3507,18 @@ void AvmTraceBuilder::op_keccakf1600(uint8_t indirect, uint32_t output_offset, u // Crucial to perform this operation after having incremented pc because write_slice_to_memory // is implemented with opcodes (SET and JUMP). write_slice_to_memory(resolved_output_offset, AvmMemoryTag::U64, result); + + return AvmError::NO_ERROR; } -void AvmTraceBuilder::op_ec_add(uint16_t indirect, - uint32_t lhs_x_offset, - uint32_t lhs_y_offset, - uint32_t lhs_is_inf_offset, - uint32_t rhs_x_offset, - uint32_t rhs_y_offset, - uint32_t rhs_is_inf_offset, - uint32_t output_offset) +AvmError AvmTraceBuilder::op_ec_add(uint16_t indirect, + uint32_t lhs_x_offset, + uint32_t lhs_y_offset, + uint32_t lhs_is_inf_offset, + uint32_t rhs_x_offset, + uint32_t rhs_y_offset, + uint32_t rhs_is_inf_offset, + uint32_t output_offset) { auto clk = static_cast(main_trace.size()) + 1; auto [resolved_lhs_x_offset, @@ -3298,6 +3537,25 @@ void AvmTraceBuilder::op_ec_add(uint16_t indirect, output_offset }, mem_trace_builder); + // Tag checking + bool op_valid = + check_tag(AvmMemoryTag::FF, resolved_lhs_x_offset) && check_tag(AvmMemoryTag::FF, resolved_lhs_y_offset) && + check_tag(AvmMemoryTag::U1, resolved_lhs_is_inf_offset) && check_tag(AvmMemoryTag::FF, resolved_rhs_x_offset) && + check_tag(AvmMemoryTag::FF, resolved_rhs_y_offset) && check_tag(AvmMemoryTag::U1, resolved_rhs_is_inf_offset); + + gas_trace_builder.constrain_gas(clk, OpCode::ECADD); + + if (!op_valid) { + main_trace.push_back(Row{ + .main_clk = clk, + .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = FF(1), + .main_pc = FF(pc), + .main_sel_op_ecadd = 1, + }); + return AvmError::TAG_ERROR; + } + // Load lhs point auto lhs_x_read = unconstrained_read_from_memory(resolved_lhs_x_offset); auto lhs_y_read = unconstrained_read_from_memory(resolved_lhs_y_offset); @@ -3324,8 +3582,6 @@ void AvmTraceBuilder::op_ec_add(uint16_t indirect, .main_tag_err = FF(0), }); - gas_trace_builder.constrain_gas(clk, OpCode::ECADD); - pc += Deserialization::get_pc_increment(OpCode::ECADD); // Crucial to perform this operation after having incremented pc because write_slice_to_memory @@ -3333,29 +3589,58 @@ void AvmTraceBuilder::op_ec_add(uint16_t indirect, // Write point coordinates write_to_memory(resolved_output_offset, result.x, AvmMemoryTag::FF); write_to_memory(resolved_output_offset + 1, result.y, AvmMemoryTag::FF); - write_to_memory(resolved_output_offset + 2, result.is_point_at_infinity(), AvmMemoryTag::U8); + write_to_memory(resolved_output_offset + 2, result.is_point_at_infinity(), AvmMemoryTag::U1); + + return AvmError::NO_ERROR; } -void AvmTraceBuilder::op_variable_msm(uint8_t indirect, - uint32_t points_offset, - uint32_t scalars_offset, - uint32_t output_offset, - uint32_t point_length_offset) +AvmError AvmTraceBuilder::op_variable_msm(uint8_t indirect, + uint32_t points_offset, + uint32_t scalars_offset, + uint32_t output_offset, + uint32_t point_length_offset) { auto clk = static_cast(main_trace.size()) + 1; auto [resolved_points_offset, resolved_scalars_offset, resolved_output_offset, resolved_point_length_offset] = Addressing<4>::fromWire(indirect, call_ptr) .resolve({ points_offset, scalars_offset, output_offset, point_length_offset }, mem_trace_builder); - auto points_length = unconstrained_read_from_memory(resolved_point_length_offset); + bool op_valid = check_tag(AvmMemoryTag::U32, resolved_point_length_offset); + const FF points_length = op_valid ? unconstrained_read_from_memory(resolved_point_length_offset) : 0; // Points are stored as [x1, y1, inf1, x2, y2, inf2, ...] with the types [FF, FF, U8, FF, FF, U8, ...] - uint32_t num_points = uint32_t(points_length) / 3; // 3 elements per point + const uint32_t num_points = uint32_t(points_length) / 3; // 3 elements per point // We need to split up the reads due to the memory tags, std::vector points_coords_vec; std::vector points_inf_vec; std::vector scalars_vec; + for (uint32_t i = 0; i < num_points; i++) { + op_valid = op_valid && check_tag_range(AvmMemoryTag::FF, resolved_points_offset + 3 * i, 2) && + check_tag(AvmMemoryTag::U1, resolved_points_offset + 3 * i + 2); + } + + // Scalar read length is num_points* 2 since scalars are stored as lo and hi limbs + uint32_t scalar_read_length = num_points * 2; + + op_valid = op_valid && check_tag_range(AvmMemoryTag::FF, resolved_scalars_offset, scalar_read_length); + + // TODO(dbanks12): length needs to fit into u32 here or it will certainly + // run out of gas. Casting/truncating here is not secure. + gas_trace_builder.constrain_gas(clk, OpCode::MSM, static_cast(points_length)); + + if (!op_valid) { + main_trace.push_back(Row{ + .main_clk = clk, + .main_internal_return_ptr = FF(internal_return_ptr), + .main_op_err = FF(static_cast(!op_valid)), + .main_pc = FF(pc), + .main_sel_op_msm = 1, + }); + + return AvmError::TAG_ERROR; + } + // Loading the points is a bit more complex since we need to read the coordinates and the infinity flags // separately The current circuit constraints does not allow for multiple memory tags to be loaded from within // the same row. If we could we would be able to replace the following loops with a single read_slice_to_memory @@ -3370,8 +3655,7 @@ void AvmTraceBuilder::op_variable_msm(uint8_t indirect, points_coords_vec.insert(points_coords_vec.end(), { point_x1, point_y1 }); points_inf_vec.emplace_back(infty); } - // Scalar read length is num_points* 2 since scalars are stored as lo and hi limbs - uint32_t scalar_read_length = num_points * 2; + // Scalars are easy to read since they are stored as [lo1, hi1, lo2, hi2, ...] with the types [FF, FF, FF,FF, // ...] read_slice_from_memory(resolved_scalars_offset, scalar_read_length, scalars_vec); @@ -3409,10 +3693,6 @@ void AvmTraceBuilder::op_variable_msm(uint8_t indirect, .main_tag_err = FF(0), }); - // TODO(dbanks12): length needs to fit into u32 here or it will certainly - // run out of gas. Casting/truncating here is not secure. - gas_trace_builder.constrain_gas(clk, OpCode::MSM, static_cast(points_length)); - pc += Deserialization::get_pc_increment(OpCode::MSM); // Crucial to perform this operation after having incremented pc because write_slice_to_memory @@ -3420,7 +3700,9 @@ void AvmTraceBuilder::op_variable_msm(uint8_t indirect, // Write the result back to memory [x, y, inf] with tags [FF, FF, U8] write_to_memory(resolved_output_offset, result.x, AvmMemoryTag::FF); write_to_memory(resolved_output_offset + 1, result.y, AvmMemoryTag::FF); - write_to_memory(resolved_output_offset + 2, result.is_point_at_infinity(), AvmMemoryTag::U8); + write_to_memory(resolved_output_offset + 2, result.is_point_at_infinity(), AvmMemoryTag::U1); + + return AvmError::NO_ERROR; } /************************************************************************************************** @@ -3433,17 +3715,17 @@ void AvmTraceBuilder::op_variable_msm(uint8_t indirect, * @param indirect A byte encoding information about indirect/direct memory access. * @param src_offset An index in memory pointing to the input of the To_Radix_BE conversion. * @param dst_offset An index in memory pointing to the output of the To_Radix_BE conversion. - * @param radix_offset An index in memory pointing to the strict upper bound of each converted limb, i.e., 0 <= limb < - * radix. + * @param radix_offset An index in memory pointing to the strict upper bound of each converted limb, i.e., 0 <= limb + * < radix. * @param num_limbs The number of limbs to the value into. * @param output_bits Should the output be U1s instead of U8s? */ -void AvmTraceBuilder::op_to_radix_be(uint8_t indirect, - uint32_t src_offset, - uint32_t dst_offset, - uint32_t radix_offset, - uint32_t num_limbs, - uint8_t output_bits) +AvmError AvmTraceBuilder::op_to_radix_be(uint8_t indirect, + uint32_t src_offset, + uint32_t dst_offset, + uint32_t radix_offset, + uint32_t num_limbs, + uint8_t output_bits) { auto clk = static_cast(main_trace.size()) + 1; @@ -3455,12 +3737,18 @@ void AvmTraceBuilder::op_to_radix_be(uint8_t indirect, Addressing<3>::fromWire(indirect, call_ptr) .resolve({ src_offset, dst_offset, radix_offset }, mem_trace_builder); + // Constrain gas cost + gas_trace_builder.constrain_gas(clk, OpCode::TORADIXBE, num_limbs); + auto read_src = constrained_read_from_memory( call_ptr, clk, resolved_src_offset, AvmMemoryTag::FF, w_in_tag, IntermRegister::IA); // TODO(8603): once instructions can have multiple different tags for reads, constrain the radix's read // TODO(9497): if simulator fails tag check here, witgen will not. Raise error flag! // auto read_radix = constrained_read_from_memory( // call_ptr, clk, resolved_radix_offset, AvmMemoryTag::U32, AvmMemoryTag::U32, IntermRegister::IB); + + bool op_valid = check_tag(AvmMemoryTag::U32, resolved_radix_offset); + auto read_radix = unconstrained_read_from_memory(resolved_radix_offset); FF input = read_src.val; @@ -3469,7 +3757,7 @@ void AvmTraceBuilder::op_to_radix_be(uint8_t indirect, uint32_t radix = static_cast(read_radix); bool radix_out_of_bounds = radix > 256; - bool error = radix_out_of_bounds || !read_src.tag_match; // || !read_radix.tag_match; + bool error = !op_valid || radix_out_of_bounds || !read_src.tag_match; // || !read_radix.tag_match; // In case of an error, we do not perform the computation. // Therefore, we do not create any entry in gadget table and we return a vector of 0. @@ -3477,9 +3765,6 @@ void AvmTraceBuilder::op_to_radix_be(uint8_t indirect, ? std::vector(num_limbs, 0) : conversion_trace_builder.op_to_radix_be(input, radix, num_limbs, output_bits, clk); - // Constrain gas cost - gas_trace_builder.constrain_gas(clk, OpCode::TORADIXBE, num_limbs); - // This is the row that contains the selector to trigger the sel_op_radix_be // In this row, we read the input value and the destination address into register A and B respectively main_trace.push_back(Row{ @@ -3496,7 +3781,7 @@ void AvmTraceBuilder::op_to_radix_be(uint8_t indirect, .main_mem_addr_a = read_src.direct_address, // TODO(8603): uncomment //.main_mem_addr_b = read_radix.direct_address, - .main_op_err = error ? FF(1) : FF(0), + .main_op_err = FF(static_cast(error)), .main_pc = FF(pc), .main_r_in_tag = FF(static_cast(AvmMemoryTag::FF)), .main_sel_mem_op_a = FF(1), @@ -3514,6 +3799,7 @@ void AvmTraceBuilder::op_to_radix_be(uint8_t indirect, // Crucial to perform this operation after having incremented pc because write_slice_to_memory // is implemented with opcodes (SET and JUMP). write_slice_to_memory(resolved_dst_offset, w_in_tag, res); + return error ? AvmError::TAG_ERROR : AvmError::NO_ERROR; } /************************************************************************************************** @@ -3616,7 +3902,7 @@ std::vector AvmTraceBuilder::finalize() dest.incl_mem_tag_err_counts = FF(static_cast(src.m_tag_err_count_relevant)); - // TODO: Should be a cleaner way to do this in the future. Perhaps an "into_canoncal" function in + // TODO: Should be a cleaner way to do this in the future. Perhaps an "into_canonical" function in // mem_trace_builder if (!src.m_sel_op_slice) { switch (src.m_sub_clk) { @@ -3844,12 +4130,16 @@ std::vector AvmTraceBuilder::finalize() for (size_t i = 0; i < new_trace_size; i++) { auto& r = main_trace.at(i); + if (r.main_tag_err == FF(1)) { + r.main_op_err = FF(1); // Consolidation of errors into main_op_err + } + if ((r.main_sel_op_add == FF(1) || r.main_sel_op_sub == FF(1) || r.main_sel_op_mul == FF(1) || r.main_sel_op_eq == FF(1) || r.main_sel_op_not == FF(1) || r.main_sel_op_lt == FF(1) || r.main_sel_op_lte == FF(1) || r.main_sel_op_cast == FF(1) || r.main_sel_op_shr == FF(1) || r.main_sel_op_shl == FF(1) || r.main_sel_op_div == FF(1)) && - r.main_tag_err == FF(0) && r.main_op_err == FF(0)) { - r.main_sel_alu = FF(1); + r.main_op_err == FF(0)) { + r.main_sel_alu = FF(1); // From error consolidation, this is set only if tag_err == 0. } if (r.main_sel_op_internal_call == FF(1) || r.main_sel_op_internal_return == FF(1)) { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp index 26f67e10c81..cfe330881df 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp @@ -23,6 +23,11 @@ namespace bb::avm_trace { using Row = bb::AvmFullRow; +struct ReturnDataError { + std::vector return_data; + AvmError error; +}; + // This is the internal context that we keep along the lifecycle of bytecode execution // to iteratively build the whole trace. This is effectively performing witness generation. // At the end of circuit building, mainTrace can be moved to AvmCircuitBuilder by calling @@ -40,47 +45,47 @@ class AvmTraceBuilder { uint32_t get_da_gas_left() const { return gas_trace_builder.get_da_gas_left(); } // Compute - Arithmetic - void op_add( + AvmError op_add( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::ADD_16); - void op_sub( + AvmError op_sub( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::SUB_16); - void op_mul( + AvmError op_mul( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::MUL_16); - void op_div( + AvmError op_div( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::DIV_16); - void op_fdiv( + AvmError op_fdiv( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::FDIV_16); // Compute - Comparators - void op_eq( + AvmError op_eq( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::EQ_16); - void op_lt( + AvmError op_lt( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::LT_16); - void op_lte( + AvmError op_lte( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::LTE_16); // Compute - Bitwise - void op_and( + AvmError op_and( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::AND_16); - void op_or( + AvmError op_or( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::OR_16); - void op_xor( + AvmError op_xor( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::XOR_16); - void op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, OpCode op_code = OpCode::NOT_16); - void op_shl( + AvmError op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_offset, OpCode op_code = OpCode::NOT_16); + AvmError op_shl( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::SHL_16); - void op_shr( + AvmError op_shr( uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, OpCode op_code = OpCode::SHR_16); // Compute - Type Conversions - void op_cast(uint8_t indirect, - uint32_t a_offset, - uint32_t dst_offset, - AvmMemoryTag dst_tag, - OpCode op_code = OpCode::CAST_16); + AvmError op_cast(uint8_t indirect, + uint32_t a_offset, + uint32_t dst_offset, + AvmMemoryTag dst_tag, + OpCode op_code = OpCode::CAST_16); // Execution Environment - void op_get_env_var(uint8_t indirect, uint8_t env_var, uint32_t dst_offset); + AvmError op_get_env_var(uint8_t indirect, uint8_t env_var, uint32_t dst_offset); void op_address(uint8_t indirect, uint32_t dst_offset); void op_sender(uint8_t indirect, uint32_t dst_offset); void op_function_selector(uint8_t indirect, uint32_t dst_offset); @@ -96,12 +101,15 @@ class AvmTraceBuilder { void op_fee_per_da_gas(uint8_t indirect, uint32_t dst_offset); // Execution Environment - Calldata - void op_calldata_copy(uint8_t indirect, uint32_t cd_offset_address, uint32_t copy_size_offset, uint32_t dst_offset); - void op_returndata_size(uint8_t indirect, uint32_t dst_offset); - void op_returndata_copy(uint8_t indirect, - uint32_t rd_offset_address, - uint32_t copy_size_offset, - uint32_t dst_offset); + AvmError op_calldata_copy(uint8_t indirect, + uint32_t cd_offset_address, + uint32_t copy_size_offset, + uint32_t dst_offset); + AvmError op_returndata_size(uint8_t indirect, uint32_t dst_offset); + AvmError op_returndata_copy(uint8_t indirect, + uint32_t rd_offset_address, + uint32_t copy_size_offset, + uint32_t dst_offset); // Machine State - Gas void op_l2gasleft(uint8_t indirect, uint32_t dst_offset); @@ -109,89 +117,97 @@ class AvmTraceBuilder { // Machine State - Internal Control Flow // TODO(8945): skip_gas boolean is temporary and should be removed once all fake rows are removed - void op_jump(uint32_t jmp_dest, bool skip_gas = false); - void op_jumpi(uint8_t indirect, uint32_t jmp_dest, uint32_t cond_offset); - // TODO(md): this program counter MUST be an operand to the OPCODE. - void op_internal_call(uint32_t jmp_dest); - void op_internal_return(); + AvmError op_jump(uint32_t jmp_dest, bool skip_gas = false); + AvmError op_jumpi(uint8_t indirect, uint32_t jmp_dest, uint32_t cond_offset); + AvmError op_internal_call(uint32_t jmp_dest); + AvmError op_internal_return(); // Machine State - Memory // TODO(8945): skip_gas boolean is temporary and should be removed once all fake rows are removed - void op_set(uint8_t indirect, - FF val, - uint32_t dst_offset, - AvmMemoryTag in_tag, - OpCode op_code = OpCode::SET_FF, - bool skip_gas = false); - void op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset, OpCode op_code = OpCode::MOV_16); + AvmError op_set(uint8_t indirect, + FF val, + uint32_t dst_offset, + AvmMemoryTag in_tag, + OpCode op_code = OpCode::SET_FF, + bool skip_gas = false); + AvmError op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset, OpCode op_code = OpCode::MOV_16); // World State - void op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t size, uint32_t dest_offset); - void op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t size, uint32_t slot_offset); - void op_note_hash_exists(uint8_t indirect, - uint32_t note_hash_offset, - uint32_t leaf_index_offset, - uint32_t dest_offset); - void op_emit_note_hash(uint8_t indirect, uint32_t note_hash_offset); - void op_nullifier_exists(uint8_t indirect, - uint32_t nullifier_offset, - uint32_t address_offset, - uint32_t dest_offset); - void op_emit_nullifier(uint8_t indirect, uint32_t nullifier_offset); - void op_l1_to_l2_msg_exists(uint8_t indirect, - uint32_t log_offset, - uint32_t leaf_index_offset, - uint32_t dest_offset); - void op_get_contract_instance( + AvmError op_sload(uint8_t indirect, uint32_t slot_offset, uint32_t size, uint32_t dest_offset); + AvmError op_sstore(uint8_t indirect, uint32_t src_offset, uint32_t size, uint32_t slot_offset); + AvmError op_note_hash_exists(uint8_t indirect, + uint32_t note_hash_offset, + uint32_t leaf_index_offset, + uint32_t dest_offset); + AvmError op_emit_note_hash(uint8_t indirect, uint32_t note_hash_offset); + AvmError op_nullifier_exists(uint8_t indirect, + uint32_t nullifier_offset, + uint32_t address_offset, + uint32_t dest_offset); + AvmError op_emit_nullifier(uint8_t indirect, uint32_t nullifier_offset); + AvmError op_l1_to_l2_msg_exists(uint8_t indirect, + uint32_t log_offset, + uint32_t leaf_index_offset, + uint32_t dest_offset); + AvmError op_get_contract_instance( uint8_t indirect, uint8_t member_enum, uint16_t address_offset, uint16_t dst_offset, uint16_t exists_offset); // Accrued Substate - void op_emit_unencrypted_log(uint8_t indirect, uint32_t log_offset, uint32_t log_size_offset); - void op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipient_offset, uint32_t content_offset); + AvmError op_emit_unencrypted_log(uint8_t indirect, uint32_t log_offset, uint32_t log_size_offset); + AvmError op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipient_offset, uint32_t content_offset); // Control Flow - Contract Calls - void op_call(uint16_t indirect, - uint32_t gas_offset, - uint32_t addr_offset, - uint32_t args_offset, - uint32_t args_size, - uint32_t success_offset); - void op_static_call(uint16_t indirect, - uint32_t gas_offset, - uint32_t addr_offset, - uint32_t args_offset, - uint32_t args_size, - uint32_t success_offset); - std::vector op_return(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size_offset); + AvmError op_call(uint16_t indirect, + uint32_t gas_offset, + uint32_t addr_offset, + uint32_t args_offset, + uint32_t args_size, + uint32_t success_offset); + AvmError op_static_call(uint16_t indirect, + uint32_t gas_offset, + uint32_t addr_offset, + uint32_t args_offset, + uint32_t args_size, + uint32_t success_offset); + ReturnDataError op_return(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size_offset); // REVERT Opcode (that just call return under the hood for now) - std::vector op_revert(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size_offset); + ReturnDataError op_revert(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size_offset); + + // Misc + AvmError op_debug_log(uint8_t indirect, + uint32_t message_offset, + uint32_t message_size, + uint32_t fields_offset, + uint32_t fields_size_offset); // Gadgets - void op_poseidon2_permutation(uint8_t indirect, uint32_t input_offset, uint32_t output_offset); - void op_ec_add(uint16_t indirect, - uint32_t lhs_x_offset, - uint32_t lhs_y_offset, - uint32_t lhs_is_inf_offset, - uint32_t rhs_x_offset, - uint32_t rhs_y_offset, - uint32_t rhs_is_inf_offset, - uint32_t output_offset); - void op_variable_msm(uint8_t indirect, - uint32_t points_offset, - uint32_t scalars_offset, - uint32_t output_offset, - uint32_t point_length_offset); + AvmError op_poseidon2_permutation(uint8_t indirect, uint32_t input_offset, uint32_t output_offset); + AvmError op_sha256_compression(uint8_t indirect, + uint32_t output_offset, + uint32_t state_offset, + uint32_t inputs_offset); + AvmError op_keccakf1600(uint8_t indirect, uint32_t output_offset, uint32_t input_offset); + + AvmError op_ec_add(uint16_t indirect, + uint32_t lhs_x_offset, + uint32_t lhs_y_offset, + uint32_t lhs_is_inf_offset, + uint32_t rhs_x_offset, + uint32_t rhs_y_offset, + uint32_t rhs_is_inf_offset, + uint32_t output_offset); + AvmError op_variable_msm(uint8_t indirect, + uint32_t points_offset, + uint32_t scalars_offset, + uint32_t output_offset, + uint32_t point_length_offset); // Conversions - void op_to_radix_be(uint8_t indirect, - uint32_t src_offset, - uint32_t dst_offset, - uint32_t radix_offset, - uint32_t num_limbs, - uint8_t output_bits); - - // Future Gadgets -- pending changes in noir - void op_sha256_compression(uint8_t indirect, uint32_t output_offset, uint32_t state_offset, uint32_t inputs_offset); - void op_keccakf1600(uint8_t indirect, uint32_t output_offset, uint32_t input_offset); + AvmError op_to_radix_be(uint8_t indirect, + uint32_t src_offset, + uint32_t dst_offset, + uint32_t radix_offset, + uint32_t num_limbs, + uint8_t output_bits); std::vector finalize(); void reset(); @@ -260,8 +276,10 @@ class AvmTraceBuilder { uint32_t metadata_offset, AvmMemoryTag metadata_r_tag); - Row create_kernel_output_opcode_with_set_metadata_output_from_hint( - uint8_t indirect, uint32_t clk, uint32_t data_offset, uint32_t address_offset, uint32_t metadata_offset); + Row create_kernel_output_opcode_with_set_metadata_output_from_hint(uint32_t clk, + uint32_t data_offset, + uint32_t address_offset, + uint32_t metadata_offset); Row create_kernel_output_opcode_for_leaf_index(uint32_t clk, uint32_t data_offset, @@ -273,13 +291,13 @@ class AvmTraceBuilder { uint32_t data_offset, uint32_t metadata_offset); - void constrain_external_call(OpCode opcode, - uint16_t indirect, - uint32_t gas_offset, - uint32_t addr_offset, - uint32_t args_offset, - uint32_t args_size_offset, - uint32_t success_offset); + AvmError constrain_external_call(OpCode opcode, + uint16_t indirect, + uint32_t gas_offset, + uint32_t addr_offset, + uint32_t args_offset, + uint32_t args_size_offset, + uint32_t success_offset); void execute_gasleft(EnvironmentVariable var, uint8_t indirect, uint32_t dst_offset); @@ -308,6 +326,8 @@ class AvmTraceBuilder { // TODO: remove these once everything is constrained. AvmMemoryTag unconstrained_get_memory_tag(AddressWithMode addr); + bool check_tag(AvmMemoryTag tag, AddressWithMode addr); + bool check_tag_range(AvmMemoryTag tag, AddressWithMode start_offset, uint32_t size); FF unconstrained_read_from_memory(AddressWithMode addr); template void read_slice_from_memory(AddressWithMode addr, size_t slice_len, std::vector& slice); void write_to_memory(AddressWithMode addr, FF val, AvmMemoryTag w_tag); diff --git a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp index f0f473ee91d..495856339ff 100644 --- a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp @@ -37,7 +37,7 @@ #define PUBLIC_CONTEXT_INPUTS_LENGTH 41 #define AVM_ACCUMULATED_DATA_LENGTH 318 #define AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS 86 -#define AVM_PROOF_LENGTH_IN_FIELDS 4261 +#define AVM_PROOF_LENGTH_IN_FIELDS 4266 #define AVM_PUBLIC_COLUMN_MAX_SIZE 1024 #define AVM_PUBLIC_INPUTS_FLATTENED_SIZE 2914 #define MEM_TAG_FF 0 @@ -112,6 +112,7 @@ #define AVM_RETURN_BASE_L2_GAS 28 #define AVM_REVERT_BASE_L2_GAS 28 #define AVM_DEBUGLOG_BASE_L2_GAS 12 +#define AVM_DEBUGLOG_DYN_L2_GAS 3 #define AVM_POSEIDON2_BASE_L2_GAS 78 #define AVM_SHA256COMPRESSION_BASE_L2_GAS 261 #define AVM_KECCAKF1600_BASE_L2_GAS 300 diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 2a1a0e3b2aa..767c391cd8a 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -537,7 +537,7 @@ pub global AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS: u32 = 2 + 21 * 4; // `AVM_PROOF_LENGTH_IN_FIELDS` must be updated when AVM circuit changes. // To determine latest value, hover `COMPUTED_AVM_PROOF_LENGTH_IN_FIELDS` // in barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp -pub global AVM_PROOF_LENGTH_IN_FIELDS: u32 = 4261; +pub global AVM_PROOF_LENGTH_IN_FIELDS: u32 = 4266; pub global AVM_PUBLIC_COLUMN_MAX_SIZE: u32 = 1024; pub global AVM_PUBLIC_INPUTS_FLATTENED_SIZE: u32 = 2 * AVM_PUBLIC_COLUMN_MAX_SIZE + PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH; @@ -708,7 +708,8 @@ pub global AVM_CALL_BASE_L2_GAS: u32 = 45 + (2 * L2_GAS_PER_NULLIFIER_READ_REQUE pub global AVM_STATICCALL_BASE_L2_GAS: u32 = 45 + (2 * L2_GAS_PER_NULLIFIER_READ_REQUEST); pub global AVM_RETURN_BASE_L2_GAS: u32 = 28; pub global AVM_REVERT_BASE_L2_GAS: u32 = 28; -pub global AVM_DEBUGLOG_BASE_L2_GAS: u32 = 12; // Must be equal to AVM_JUMP_BASE_L2_GAS as long as circuit implements debugLog as a jump +pub global AVM_DEBUGLOG_BASE_L2_GAS: u32 = 12; +pub global AVM_DEBUGLOG_DYN_L2_GAS: u32 = 3; pub global AVM_POSEIDON2_BASE_L2_GAS: u32 = 78; pub global AVM_SHA256COMPRESSION_BASE_L2_GAS: u32 = 261; pub global AVM_KECCAKF1600_BASE_L2_GAS: u32 = 300; diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index d584a2a21dd..1e5ecc441fe 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -229,7 +229,7 @@ export const TUBE_PROOF_LENGTH = 463; export const HONK_VERIFICATION_KEY_LENGTH_IN_FIELDS = 128; export const CLIENT_IVC_VERIFICATION_KEY_LENGTH_IN_FIELDS = 143; export const AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS = 86; -export const AVM_PROOF_LENGTH_IN_FIELDS = 4261; +export const AVM_PROOF_LENGTH_IN_FIELDS = 4266; export const AVM_PUBLIC_COLUMN_MAX_SIZE = 1024; export const AVM_PUBLIC_INPUTS_FLATTENED_SIZE = 2914; export const MEM_TAG_FF = 0; @@ -304,6 +304,7 @@ export const AVM_STATICCALL_BASE_L2_GAS = 4845; export const AVM_RETURN_BASE_L2_GAS = 28; export const AVM_REVERT_BASE_L2_GAS = 28; export const AVM_DEBUGLOG_BASE_L2_GAS = 12; +export const AVM_DEBUGLOG_DYN_L2_GAS = 3; export const AVM_POSEIDON2_BASE_L2_GAS = 78; export const AVM_SHA256COMPRESSION_BASE_L2_GAS = 261; export const AVM_KECCAKF1600_BASE_L2_GAS = 300; diff --git a/yarn-project/simulator/src/avm/avm_gas.ts b/yarn-project/simulator/src/avm/avm_gas.ts index 7d571a7c907..84fcfa353ff 100644 --- a/yarn-project/simulator/src/avm/avm_gas.ts +++ b/yarn-project/simulator/src/avm/avm_gas.ts @@ -136,6 +136,7 @@ const DYNAMIC_GAS_COSTS = new Map([ [Opcode.RETURN, makeCost(c.AVM_RETURN_DYN_L2_GAS, 0)], [Opcode.REVERT_8, makeCost(c.AVM_REVERT_DYN_L2_GAS, 0)], [Opcode.REVERT_16, makeCost(c.AVM_REVERT_DYN_L2_GAS, 0)], + [Opcode.DEBUGLOG, makeCost(c.AVM_DEBUGLOG_DYN_L2_GAS, 0)], [Opcode.MSM, makeCost(c.AVM_MSM_DYN_L2_GAS, 0)], [Opcode.TORADIXBE, makeCost(c.AVM_TORADIXBE_DYN_L2_GAS, 0)], ]); diff --git a/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts b/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts index 6370740b3eb..0a8bd01f140 100644 --- a/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts +++ b/yarn-project/simulator/src/avm/opcodes/accrued_substate.ts @@ -255,6 +255,7 @@ export class SendL2ToL1Message extends Instruction { const operands = [this.recipientOffset, this.contentOffset]; const addressing = Addressing.fromWire(this.indirect, operands.length); const [recipientOffset, contentOffset] = addressing.resolve(operands, memory); + memory.checkTags(TypeTag.FIELD, recipientOffset, contentOffset); const recipient = memory.get(recipientOffset).toFr(); const content = memory.get(contentOffset).toFr(); diff --git a/yarn-project/simulator/src/avm/opcodes/ec_add.test.ts b/yarn-project/simulator/src/avm/opcodes/ec_add.test.ts index 46629398e38..7fe9e7ac199 100644 --- a/yarn-project/simulator/src/avm/opcodes/ec_add.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/ec_add.test.ts @@ -4,7 +4,7 @@ import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { beforeEach } from '@jest/globals'; import { type AvmContext } from '../avm_context.js'; -import { Field, Uint32 } from '../avm_memory_types.js'; +import { Field, Uint1, Uint32 } from '../avm_memory_types.js'; import { initContext } from '../fixtures/index.js'; import { EcAdd } from './ec_add.js'; @@ -47,7 +47,7 @@ describe('EC Instructions', () => { it(`Should double correctly`, async () => { const x = new Field(grumpkin.generator().x); const y = new Field(grumpkin.generator().y); - const zero = new Uint32(0); + const zero = new Uint1(0); context.machineState.memory.set(0, x); context.machineState.memory.set(1, y); @@ -81,7 +81,7 @@ describe('EC Instructions', () => { it('Should add correctly', async () => { const G2 = grumpkin.add(grumpkin.generator(), grumpkin.generator()); - const zero = new Uint32(0); + const zero = new Uint1(0); const x1 = new Field(grumpkin.generator().x); const y1 = new Field(grumpkin.generator().y); diff --git a/yarn-project/simulator/src/avm/opcodes/ec_add.ts b/yarn-project/simulator/src/avm/opcodes/ec_add.ts index c3d8015af9a..0f29954a967 100644 --- a/yarn-project/simulator/src/avm/opcodes/ec_add.ts +++ b/yarn-project/simulator/src/avm/opcodes/ec_add.ts @@ -2,7 +2,7 @@ import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { Point } from '@aztec/foundation/fields'; import { type AvmContext } from '../avm_context.js'; -import { Field } from '../avm_memory_types.js'; +import { Field, TypeTag, Uint1 } from '../avm_memory_types.js'; import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; import { Addressing } from './addressing_mode.js'; import { Instruction } from './instruction.js'; @@ -54,6 +54,9 @@ export class EcAdd extends Instruction { const [p1XOffset, p1YOffset, p1IsInfiniteOffset, p2XOffset, p2YOffset, p2IsInfiniteOffset, dstOffset] = addressing.resolve(operands, memory); + memory.checkTags(TypeTag.FIELD, p1XOffset, p1YOffset, p2XOffset, p2YOffset); + memory.checkTags(TypeTag.UINT1, p1IsInfiniteOffset, p2IsInfiniteOffset); + const p1X = memory.get(p1XOffset); const p1Y = memory.get(p1YOffset); const p1IsInfinite = memory.get(p1IsInfiniteOffset).toNumber() === 1; @@ -80,16 +83,11 @@ export class EcAdd extends Instruction { } else { dest = grumpkin.add(p1, p2); } - // Temporary, - if (p1IsInfinite) { - dest = p2; - } else if (p2IsInfinite) { - dest = p1; - } + memory.set(dstOffset, new Field(dest.x)); memory.set(dstOffset + 1, new Field(dest.y)); // Check representation of infinity for grumpkin - memory.set(dstOffset + 2, new Field(dest.equals(Point.ZERO) ? 1 : 0)); + memory.set(dstOffset + 2, new Uint1(dest.equals(Point.ZERO) ? 1 : 0)); memory.assert({ reads: 6, writes: 3, addressing }); } diff --git a/yarn-project/simulator/src/avm/opcodes/misc.ts b/yarn-project/simulator/src/avm/opcodes/misc.ts index 88f1f4a9581..4e92531052f 100644 --- a/yarn-project/simulator/src/avm/opcodes/misc.ts +++ b/yarn-project/simulator/src/avm/opcodes/misc.ts @@ -37,11 +37,12 @@ export class DebugLog extends Instruction { const addressing = Addressing.fromWire(this.indirect, operands.length); const [messageOffset, fieldsOffset, fieldsSizeOffset] = addressing.resolve(operands, memory); + memory.checkTag(TypeTag.UINT32, fieldsSizeOffset); const fieldsSize = memory.get(fieldsSizeOffset).toNumber(); memory.checkTagsRange(TypeTag.UINT8, messageOffset, this.messageSize); memory.checkTagsRange(TypeTag.FIELD, fieldsOffset, fieldsSize); - context.machineState.consumeGas(this.gasCost()); + context.machineState.consumeGas(this.gasCost(this.messageSize + fieldsSize)); const rawMessage = memory.getSlice(messageOffset, this.messageSize); const fields = memory.getSlice(fieldsOffset, fieldsSize); diff --git a/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.ts b/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.ts index d0f536e8c3e..a3e24bb48fd 100644 --- a/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.ts +++ b/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.ts @@ -2,7 +2,7 @@ import { Fq, Point } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { type AvmContext } from '../avm_context.js'; -import { Field, TypeTag } from '../avm_memory_types.js'; +import { Field, TypeTag, Uint1 } from '../avm_memory_types.js'; import { InstructionExecutionError } from '../errors.js'; import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; import { Addressing } from './addressing_mode.js'; @@ -105,9 +105,11 @@ export class MultiScalarMul extends Instruction { return grumpkin.add(acc, grumpkin.mul(curr[0], curr[1])); } }, grumpkin.mul(firstBaseScalarPair[0], firstBaseScalarPair[1])); - const output = outputPoint.toFields().map(f => new Field(f)); - memory.setSlice(outputOffset, output); + memory.set(outputOffset, new Field(outputPoint.x)); + memory.set(outputOffset + 1, new Field(outputPoint.y)); + // Check representation of infinity for grumpkin + memory.set(outputOffset + 2, new Uint1(outputPoint.equals(Point.ZERO) ? 1 : 0)); memory.assert({ reads: 1 + pointsReadLength + scalarReadLength /* points and scalars */,