diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index ac13de7477f..53cb8d86ccd 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -55,8 +55,9 @@ namespace avm_main(256); // Helper selector to characterize a Binary chiplet selector pol commit bin_sel; - // Instruction memory tag (1: u8, 2: u16, 3: u32, 4: u64, 5: u128, 6: field) - pol commit in_tag; + // Instruction memory tags read/write (1: u8, 2: u16, 3: u32, 4: u64, 5: u128, 6: field) + pol commit r_in_tag; + pol commit w_in_tag; // Errors pol commit op_err; // Boolean flag pertaining to an operation error @@ -144,7 +145,12 @@ namespace avm_main(256); // TODO - Constraints: // - mem_idx_a, mem_idx_b, mem_idx_c to u32 type // - ind_a, ind_b, ind_c to u32 type - // - 0 <= in_tag <= 6 + // - 0 <= r_in_tag, w_in_tag <= 6 // Maybe not needed as probably derived by the operation decomposition. + + //====== COMPARATOR OPCODES CONSTRAINTS ===================================== + // Enforce that the tag for the ouput of EQ opcode is u8 (i.e. equal to 1). + #[EQ_OUTPUT_U8] + sel_op_eq * (w_in_tag - 1) = 0; // Relation for division over the finite field // If tag_err == 1 in a division, then ib == 0 and op_err == 1. @@ -230,6 +236,8 @@ namespace avm_main(256); //====== MEMORY OPCODES CONSTRAINTS ========================================= #[MOV_SAME_VALUE] sel_mov * (ia - ic) = 0; // Ensure that the correct value is moved/copied. + #[MOV_MAIN_SAME_TAG] + sel_mov * (r_in_tag - w_in_tag) = 0; //====== Inter-table Constraints ============================================ #[INCL_MAIN_TAG_ERR] @@ -246,7 +254,7 @@ namespace avm_main(256); #[PERM_MAIN_ALU] alu_sel {clk, ia, ib, ic, sel_op_add, sel_op_sub, sel_op_mul, sel_op_eq, - sel_op_not, in_tag} + sel_op_not, r_in_tag} is avm_alu.alu_sel {avm_alu.alu_clk, avm_alu.alu_ia, avm_alu.alu_ib, avm_alu.alu_ic, avm_alu.alu_op_add, avm_alu.alu_op_sub, avm_alu.alu_op_mul, avm_alu.alu_op_eq, @@ -267,25 +275,28 @@ namespace avm_main(256); bin_sel = sel_op_and + sel_op_or + sel_op_xor; #[PERM_MAIN_BIN] - bin_sel {ia, ib, ic, bin_op_id, in_tag} + bin_sel {ia, ib, ic, bin_op_id, r_in_tag} is avm_binary.start {avm_binary.acc_ia, avm_binary.acc_ib, avm_binary.acc_ic, avm_binary.op_id, avm_binary.in_tag}; #[PERM_MAIN_MEM_A] - mem_op_a {clk, mem_idx_a, ia, rwa, in_tag, sel_mov} + mem_op_a {clk, mem_idx_a, ia, rwa, r_in_tag, w_in_tag, sel_mov} is - avm_mem.m_op_a {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val, avm_mem.m_rw, avm_mem.m_in_tag, avm_mem.m_sel_mov}; + avm_mem.m_op_a {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val, avm_mem.m_rw, + avm_mem.r_in_tag, avm_mem.w_in_tag, avm_mem.m_sel_mov}; #[PERM_MAIN_MEM_B] - mem_op_b {clk, mem_idx_b, ib, rwb, in_tag} + mem_op_b {clk, mem_idx_b, ib, rwb, r_in_tag, w_in_tag} is - avm_mem.m_op_b {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val, avm_mem.m_rw, avm_mem.m_in_tag}; + avm_mem.m_op_b {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val, avm_mem.m_rw, + avm_mem.r_in_tag, avm_mem.w_in_tag}; #[PERM_MAIN_MEM_C] - mem_op_c {clk, mem_idx_c, ic, rwc, in_tag} + mem_op_c {clk, mem_idx_c, ic, rwc, r_in_tag, w_in_tag} is - avm_mem.m_op_c {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val, avm_mem.m_rw, avm_mem.m_in_tag}; + avm_mem.m_op_c {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val, avm_mem.m_rw, + avm_mem.r_in_tag, avm_mem.w_in_tag}; #[PERM_MAIN_MEM_IND_A] ind_op_a {clk, ind_a, mem_idx_a} diff --git a/barretenberg/cpp/pil/avm/avm_mem.pil b/barretenberg/cpp/pil/avm/avm_mem.pil index f6d995b030e..fb23e57adcf 100644 --- a/barretenberg/cpp/pil/avm/avm_mem.pil +++ b/barretenberg/cpp/pil/avm/avm_mem.pil @@ -13,7 +13,8 @@ namespace avm_mem(256); pol commit m_last; // Boolean indicating the last row of the memory trace (not execution trace) pol commit m_rw; // Enum: 0 (read), 1 (write) - pol commit m_in_tag; // Instruction memory tag ("foreign key" pointing to avm_main.in_tag) + pol commit r_in_tag; // Instruction memory tag ("foreign key" pointing to avm_main.r_in_tag) + pol commit w_in_tag; // Instruction memory tag ("foreign key" pointing to avm_main.w_in_tag) // Indicator of the intermediate register pertaining to the memory operation (foreign key to avm_main.mem_op_XXX) pol commit m_op_a; @@ -30,10 +31,10 @@ namespace avm_mem(256); pol commit m_sel_mov; // Error columns - pol commit m_tag_err; // Boolean (1 if m_in_tag != m_tag is detected) + pol commit m_tag_err; // Boolean (1 if r_in_tag != m_tag is detected) // Helper columns - pol commit m_one_min_inv; // Extra value to prove m_in_tag != m_tag with error handling + pol commit m_one_min_inv; // Extra value to prove r_in_tag != m_tag with error handling // Type constraints m_lastAccess * (1 - m_lastAccess) = 0; @@ -48,7 +49,7 @@ namespace avm_mem(256); m_ind_op_c * (1 - m_ind_op_c) = 0; // TODO: m_addr is u32 and 0 <= m_tag <= 6 - // (m_in_tag will be constrained through inclusion check to main trace) + // (r_in_tag, w_in_tag will be constrained through inclusion check to main trace) // Maximum one memory operation enabled per row pol MEM_SEL = m_op_a + m_op_b + m_op_c + m_ind_op_a + m_ind_op_b + m_ind_op_c; @@ -105,46 +106,52 @@ namespace avm_mem(256); #[MEM_ZERO_INIT] m_lastAccess * (1 - m_rw') * m_val' = 0; - // Memory tag consistency check - // We want to prove that m_in_tag == m_tag <==> m_tag_err == 0 - // We want to show that we can invert (m_in_tag - m_tag) when m_tag_err == 1, - // i.e., m_tag_err == 1 ==> m_in_tag != m_tag + // Memory tag consistency check for load operations, i.e., m_rw == 0. + // We want to prove that r_in_tag == m_tag <==> m_tag_err == 0 + // We want to show that we can invert (r_in_tag - m_tag) when m_tag_err == 1, + // i.e., m_tag_err == 1 ==> r_in_tag != m_tag // For this purpose, we need an extra column to store a witness - // which can be used to show that (m_in_tag - m_tag) is invertible (non-zero). + // which can be used to show that (r_in_tag - m_tag) is invertible (non-zero). // We re-use the same zero (non)-equality technique as in SUBOP_DIVISION_ZERO_ERR1/2 applied - // to (m_in_tag - m_tag) by replacing m_tag_err by 1 - m_tag_err because here + // to (r_in_tag - m_tag) by replacing m_tag_err by 1 - m_tag_err because here // the equality to zero is not an error. Another modification - // consists in storing 1 - (m_in_tag - m_tag)^(-1) in the extra witness column - // instead of (m_in_tag - m_tag)^(-1) as this allows to store zero by default (i.e., when m_tag_err == 0). - // The new column m_one_min_inv is set to 1 - (m_in_tag - m_tag)^(-1) when m_tag_err == 1 + // consists in storing 1 - (r_in_tag - m_tag)^(-1) in the extra witness column + // instead of (r_in_tag - m_tag)^(-1) as this allows to store zero by default (i.e., when m_tag_err == 0). + // The new column m_one_min_inv is set to 1 - (r_in_tag - m_tag)^(-1) when m_tag_err == 1 // but must be set to 0 when tags are matching and m_tag_err = 0 #[MEM_IN_TAG_CONSISTENCY_1] - (m_in_tag - m_tag) * (1 - m_one_min_inv) - m_tag_err = 0; + (1 - m_rw) * ((r_in_tag - m_tag) * (1 - m_one_min_inv) - m_tag_err) = 0; #[MEM_IN_TAG_CONSISTENCY_2] (1 - m_tag_err) * m_one_min_inv = 0; - // Correctness of two above checks MEM_IN_TAG_CONSISTENCY_1/2: - // m_in_tag == m_tag ==> m_tag_err == 0 (first relation) - // m_tag_err == 0 ==> m_one_min_inv == 0 by second relation. First relation ==> m_in_tag - m_tag == 0 + // Correctness of two above checks MEM_IN_TAG_CONSISTENCY_1/2 (assuming m_rw == 0): + // r_in_tag == m_tag ==> m_tag_err == 0 (first relation) + // m_tag_err == 0 ==> m_one_min_inv == 0 by second relation. First relation ==> r_in_tag - m_tag == 0 + + // Enforce that a write instruction tag is equal to m_tag for a write operation + m_rw * (w_in_tag - m_tag) = 0; + + // Enforce that a write instruction never leads to a tag error + #[NO_TAG_ERR_WRITE] + m_rw * m_tag_err = 0; //====== Indirect Memory Constraints ===================================== - // Enforce m_in_tag == 3, i.e., in_tag must be U32 - m_ind_op_a * (m_in_tag - 3) = 0; - m_ind_op_b * (m_in_tag - 3) = 0; - m_ind_op_c * (m_in_tag - 3) = 0; + // Enforce r_in_tag == 3, i.e., r_in_tag must be U32 + m_ind_op_a * (r_in_tag - 3) = 0; + m_ind_op_b * (r_in_tag - 3) = 0; + m_ind_op_c * (r_in_tag - 3) = 0; // Indirect operation is always a load m_ind_op_a * m_rw = 0; m_ind_op_b * m_rw = 0; m_ind_op_c * m_rw = 0; - //====== MOV Opcode in_tag Constraint ===================================== - // The following constraint ensures that the m_in_tag is set to m_tag for + //====== MOV Opcode Tag Constraint ===================================== + // The following constraint ensures that the r_in_tag is set to m_tag for // the load operation pertaining to Ia. - // The permutation check #[PERM_MAIN_MEM_A] guarantees that the m_in_tag - // value load operation for Ia is copied back in the main trace. Then, - // #[PERM_MAIN_MEM_C] copies back m_in_tag for store operation from Ic. - // Finally, the following constraint guarantees that m_tag is correct for - // the output. + // The permutation check #[PERM_MAIN_MEM_A] guarantees that the r_in_tag + // value load operation for Ia is copied back in the main trace. + // Constraint #[MOV_MAIN_SAME_TAG] copies r_in_tag to w_in_tag in the main + // trace. Then, #[PERM_MAIN_MEM_C] copies w_in_tag for store operation from Ic. #[MOV_SAME_TAG] - m_sel_mov * m_tag_err = 0; // Equivalent to m_sel_mov * (m_in_tag - m_tag) = 0 + m_sel_mov * m_tag_err = 0; // Equivalent to m_sel_mov * (r_in_tag - m_tag) = 0 \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp index 654dbdd83b5..8fe200d9ff9 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,77 +7,77 @@ namespace bb::Avm_vm { template struct Avm_aluRow { - FF avm_alu_alu_u8_r0{}; - FF avm_alu_alu_op_eq_diff_inv{}; - FF avm_alu_alu_op_eq{}; - FF avm_alu_alu_u16_r3{}; - FF avm_alu_alu_u64_r0{}; - FF avm_alu_alu_u16_r4{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_u16_r1{}; FF avm_alu_alu_in_tag{}; - FF avm_alu_alu_cf{}; - FF avm_alu_alu_op_not{}; - FF avm_alu_alu_u16_r6{}; - FF avm_alu_alu_ib{}; - FF avm_alu_alu_op_add{}; - FF avm_alu_alu_u128_tag{}; FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_sel{}; - FF avm_alu_alu_u16_r7_shift{}; - FF avm_alu_alu_u16_r7{}; + FF avm_alu_alu_u8_tag{}; + FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r3_shift{}; FF avm_alu_alu_u16_r0{}; + FF avm_alu_alu_cf{}; + FF avm_alu_alu_op_mul{}; FF avm_alu_alu_u32_tag{}; + FF avm_alu_alu_u64_tag{}; + FF avm_alu_alu_u16_r1{}; + FF avm_alu_alu_u16_r1_shift{}; + FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u64_r0{}; + FF avm_alu_alu_u16_r7{}; + FF avm_alu_alu_ib{}; + FF avm_alu_alu_u16_r7_shift{}; FF avm_alu_alu_ia{}; - FF avm_alu_alu_ic{}; - FF avm_alu_alu_u8_tag{}; + FF avm_alu_alu_op_sub{}; + FF avm_alu_alu_u8_r0{}; + FF avm_alu_alu_op_not{}; + FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_u16_r2{}; + FF avm_alu_alu_u16_r4{}; FF avm_alu_alu_u8_r1{}; - FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_alu_alu_op_eq{}; + FF avm_alu_alu_op_add{}; + FF avm_alu_alu_op_eq_diff_inv{}; FF avm_alu_alu_u16_r5_shift{}; - FF avm_alu_alu_u16_r2{}; - FF avm_alu_alu_op_mul{}; - FF avm_alu_alu_ff_tag{}; - FF avm_alu_alu_u64_tag{}; - FF avm_alu_alu_op_sub{}; FF avm_alu_alu_u16_tag{}; + FF avm_alu_alu_u128_tag{}; + FF avm_alu_alu_u16_r6{}; + FF avm_alu_alu_u16_r3{}; FF avm_alu_alu_u16_r5{}; + FF avm_alu_alu_ic{}; + FF avm_alu_alu_sel{}; }; inline std::string get_relation_label_avm_alu(int index) { switch (index) { - case 20: - return "ALU_OP_EQ"; - case 13: return "ALU_MUL_COMMON_2"; - case 16: - return "ALU_MULTIPLICATION_OUT_U128"; + case 20: + return "ALU_OP_EQ"; - case 18: - return "ALU_OP_NOT"; + case 11: + return "ALU_MULTIPLICATION_FF"; case 19: return "ALU_RES_IS_BOOL"; - case 11: - return "ALU_MULTIPLICATION_FF"; + case 9: + return "ALU_ADD_SUB_1"; + + case 16: + return "ALU_MULTIPLICATION_OUT_U128"; case 12: return "ALU_MUL_COMMON_1"; - case 9: - return "ALU_ADD_SUB_1"; + case 10: + return "ALU_ADD_SUB_2"; case 17: return "ALU_FF_NOT_XOR"; - case 10: - return "ALU_ADD_SUB_2"; + case 18: + return "ALU_OP_NOT"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp index 4d5179c6579..ee9948c94f1 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_binary.hpp @@ -7,43 +7,43 @@ namespace bb::Avm_vm { template struct Avm_binaryRow { - FF avm_binary_bin_sel{}; - FF avm_binary_acc_ib{}; - FF avm_binary_mem_tag_ctr{}; + FF avm_binary_mem_tag_ctr_inv{}; FF avm_binary_bin_ic_bytes{}; - FF avm_binary_acc_ic_shift{}; FF avm_binary_acc_ia{}; - FF avm_binary_op_id_shift{}; + FF avm_binary_acc_ib{}; + FF avm_binary_acc_ic{}; + FF avm_binary_mem_tag_ctr_shift{}; FF avm_binary_acc_ia_shift{}; + FF avm_binary_op_id_shift{}; + FF avm_binary_bin_sel{}; + FF avm_binary_bin_ib_bytes{}; FF avm_binary_op_id{}; - FF avm_binary_mem_tag_ctr_shift{}; - FF avm_binary_acc_ic{}; FF avm_binary_bin_ia_bytes{}; - FF avm_binary_bin_ib_bytes{}; - FF avm_binary_mem_tag_ctr_inv{}; FF avm_binary_acc_ib_shift{}; + FF avm_binary_mem_tag_ctr{}; + FF avm_binary_acc_ic_shift{}; }; inline std::string get_relation_label_avm_binary(int index) { switch (index) { - case 1: - return "OP_ID_REL"; + case 9: + return "ACC_REL_C"; case 7: return "ACC_REL_A"; + case 1: + return "OP_ID_REL"; + + case 2: + return "MEM_TAG_REL"; + case 8: return "ACC_REL_B"; - case 9: - return "ACC_REL_C"; - case 3: return "BIN_SEL_CTR_REL"; - - case 2: - return "MEM_TAG_REL"; } return std::to_string(index); } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp index 316e839ed50..66d50ffe220 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -7,82 +7,90 @@ namespace bb::Avm_vm { template struct Avm_mainRow { - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_sel_internal_return{}; - FF avm_main_sel_op_sub{}; - FF avm_main_ind_op_b{}; - FF avm_main_mem_op_a{}; - FF avm_main_op_err{}; + FF avm_main_w_in_tag{}; + FF avm_main_sel_op_add{}; + FF avm_main_bin_sel{}; + FF avm_main_ind_op_a{}; + FF avm_main_r_in_tag{}; FF avm_main_sel_op_and{}; + FF avm_main_sel_op_mul{}; FF avm_main_mem_op_b{}; - FF avm_main_rwb{}; + FF avm_main_sel_op_or{}; + FF avm_main_mem_op_c{}; + FF avm_main_sel_halt{}; + FF avm_main_inv{}; FF avm_main_pc{}; - FF avm_main_bin_op_id{}; - FF avm_main_sel_op_xor{}; + FF avm_main_sel_op_not{}; FF avm_main_rwa{}; - FF avm_main_rwc{}; - FF avm_main_ind_op_a{}; - FF avm_main_sel_mov{}; - FF avm_main_sel_jump{}; - FF avm_main_inv{}; - FF avm_main_ia{}; - FF avm_main_ind_op_c{}; + FF avm_main_first{}; + FF avm_main_sel_op_div{}; FF avm_main_internal_return_ptr{}; - FF avm_main_sel_internal_call{}; FF avm_main_sel_op_eq{}; + FF avm_main_ind_op_c{}; + FF avm_main_ia{}; + FF avm_main_bin_op_id{}; + FF avm_main_sel_jump{}; + FF avm_main_sel_internal_call{}; + FF avm_main_op_err{}; + FF avm_main_rwb{}; + FF avm_main_sel_internal_return{}; FF avm_main_tag_err{}; + FF avm_main_mem_idx_b{}; + FF avm_main_sel_mov{}; + FF avm_main_ic{}; + FF avm_main_rwc{}; + FF avm_main_pc_shift{}; + FF avm_main_ind_op_b{}; + FF avm_main_ib{}; + FF avm_main_sel_op_sub{}; FF avm_main_mem_idx_a{}; + FF avm_main_mem_op_a{}; FF avm_main_alu_sel{}; - FF avm_main_sel_op_or{}; - FF avm_main_sel_op_add{}; - FF avm_main_sel_op_mul{}; - FF avm_main_first{}; - FF avm_main_ib{}; - FF avm_main_bin_sel{}; - FF avm_main_pc_shift{}; - FF avm_main_ic{}; - FF avm_main_mem_op_c{}; - FF avm_main_mem_idx_b{}; - FF avm_main_sel_op_div{}; - FF avm_main_sel_op_not{}; - FF avm_main_sel_halt{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_sel_op_xor{}; }; inline std::string get_relation_label_avm_main(int index) { switch (index) { case 28: - return "SUBOP_ERROR_RELEVANT_OP"; - - case 25: - return "SUBOP_DIVISION_FF"; - - case 27: return "SUBOP_DIVISION_ZERO_ERR2"; - case 42: + case 43: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 43: + case 45: + return "MOV_MAIN_SAME_TAG"; + + case 44: return "MOV_SAME_VALUE"; - case 26: + case 27: return "SUBOP_DIVISION_ZERO_ERR1"; - case 46: - return "BIN_SEL_2"; - - case 45: - return "BIN_SEL_1"; - - case 30: + case 31: return "RETURN_POINTER_INCREMENT"; - case 41: + case 42: return "PC_INCREMENT"; - case 36: + case 37: return "RETURN_POINTER_DECREMENT"; + + case 25: + return "EQ_OUTPUT_U8"; + + case 47: + return "BIN_SEL_1"; + + case 48: + return "BIN_SEL_2"; + + case 26: + return "SUBOP_DIVISION_FF"; + + case 29: + return "SUBOP_ERROR_RELEVANT_OP"; } return std::to_string(index); } @@ -91,9 +99,9 @@ template class avm_mainImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 2, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 2, }; template @@ -307,8 +315,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = - ((avm_main_sel_op_div * (-avm_main_op_err + FF(1))) * ((avm_main_ic * avm_main_ib) - avm_main_ia)); + auto tmp = (avm_main_sel_op_eq * (avm_main_w_in_tag - FF(1))); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -316,7 +323,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); + auto tmp = + ((avm_main_sel_op_div * (-avm_main_op_err + FF(1))) * ((avm_main_ic * avm_main_ib) - avm_main_ia)); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -324,7 +332,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); + auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -332,7 +340,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(28); - auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); + auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -340,7 +348,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(29); - auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -348,8 +356,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(30); - auto tmp = (avm_main_sel_internal_call * - (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr + FF(1)))); + auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -357,7 +364,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(31); - auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); + auto tmp = (avm_main_sel_internal_call * + (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr + FF(1)))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -365,7 +373,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(32); - auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -373,7 +381,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(33); - auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); + auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<33>(evals) += tmp; } @@ -381,7 +389,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(34); - auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); + auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -389,7 +397,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(35); - auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); + auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); tmp *= scaling_factor; std::get<35>(evals) += tmp; } @@ -397,8 +405,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(36); - auto tmp = (avm_main_sel_internal_return * - (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr - FF(1)))); + auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<36>(evals) += tmp; } @@ -406,7 +413,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(37); - auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); + auto tmp = (avm_main_sel_internal_return * + (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr - FF(1)))); tmp *= scaling_factor; std::get<37>(evals) += tmp; } @@ -414,7 +422,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(38); - auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); tmp *= scaling_factor; std::get<38>(evals) += tmp; } @@ -422,7 +430,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(39); - auto tmp = (avm_main_sel_internal_return * avm_main_rwa); + auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<39>(evals) += tmp; } @@ -430,7 +438,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(40); - auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + auto tmp = (avm_main_sel_internal_return * avm_main_rwa); tmp *= scaling_factor; std::get<40>(evals) += tmp; } @@ -438,6 +446,14 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(41); + auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + tmp *= scaling_factor; + std::get<41>(evals) += tmp; + } + // Contribution 42 + { + Avm_DECLARE_VIEWS(42); + auto tmp = ((((-avm_main_first + FF(1)) * (-avm_main_sel_halt + FF(1))) * ((((((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_div) + avm_main_sel_op_mul) + @@ -448,53 +464,61 @@ template class avm_mainImpl { avm_main_sel_op_xor)) * (avm_main_pc_shift - (avm_main_pc + FF(1)))); tmp *= scaling_factor; - std::get<41>(evals) += tmp; + std::get<42>(evals) += tmp; } - // Contribution 42 + // Contribution 43 { - Avm_DECLARE_VIEWS(42); + Avm_DECLARE_VIEWS(43); auto tmp = ((-(((avm_main_first + avm_main_sel_internal_call) + avm_main_sel_internal_return) + avm_main_sel_halt) + FF(1)) * (avm_main_internal_return_ptr_shift - avm_main_internal_return_ptr)); tmp *= scaling_factor; - std::get<42>(evals) += tmp; + std::get<43>(evals) += tmp; } - // Contribution 43 + // Contribution 44 { - Avm_DECLARE_VIEWS(43); + Avm_DECLARE_VIEWS(44); auto tmp = (avm_main_sel_mov * (avm_main_ia - avm_main_ic)); tmp *= scaling_factor; - std::get<43>(evals) += tmp; + std::get<44>(evals) += tmp; } - // Contribution 44 + // Contribution 45 { - Avm_DECLARE_VIEWS(44); + Avm_DECLARE_VIEWS(45); + + auto tmp = (avm_main_sel_mov * (avm_main_r_in_tag - avm_main_w_in_tag)); + tmp *= scaling_factor; + std::get<45>(evals) += tmp; + } + // Contribution 46 + { + Avm_DECLARE_VIEWS(46); auto tmp = (avm_main_alu_sel - (((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_mul) + avm_main_sel_op_not) + avm_main_sel_op_eq) * (-avm_main_tag_err + FF(1)))); tmp *= scaling_factor; - std::get<44>(evals) += tmp; + std::get<46>(evals) += tmp; } - // Contribution 45 + // Contribution 47 { - Avm_DECLARE_VIEWS(45); + Avm_DECLARE_VIEWS(47); auto tmp = (avm_main_bin_op_id - (avm_main_sel_op_or + (avm_main_sel_op_xor * FF(2)))); tmp *= scaling_factor; - std::get<45>(evals) += tmp; + std::get<47>(evals) += tmp; } - // Contribution 46 + // Contribution 48 { - Avm_DECLARE_VIEWS(46); + Avm_DECLARE_VIEWS(48); auto tmp = (avm_main_bin_sel - ((avm_main_sel_op_and + avm_main_sel_op_or) + avm_main_sel_op_xor)); tmp *= scaling_factor; - std::get<46>(evals) += tmp; + std::get<48>(evals) += tmp; } } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp index 29f83221e7a..6ea3004b2df 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -8,51 +8,55 @@ namespace bb::Avm_vm { template struct Avm_memRow { FF avm_mem_m_op_b{}; + FF avm_mem_m_lastAccess{}; + FF avm_mem_m_rw_shift{}; + FF avm_mem_m_ind_op_a{}; + FF avm_mem_m_ind_op_b{}; + FF avm_mem_m_sub_clk{}; + FF avm_mem_r_in_tag{}; FF avm_mem_m_tag_shift{}; + FF avm_mem_m_addr{}; FF avm_mem_m_rw{}; - FF avm_mem_m_ind_op_a{}; + FF avm_mem_m_op_a{}; + FF avm_mem_m_tag{}; FF avm_mem_m_val_shift{}; - FF avm_mem_m_ind_op_b{}; - FF avm_mem_m_in_tag{}; - FF avm_mem_m_sel_mov{}; + FF avm_mem_m_val{}; FF avm_mem_m_one_min_inv{}; + FF avm_mem_m_op_c{}; + FF avm_mem_w_in_tag{}; FF avm_mem_m_addr_shift{}; + FF avm_mem_m_sel_mov{}; FF avm_mem_m_last{}; - FF avm_mem_m_tag{}; - FF avm_mem_m_op_c{}; - FF avm_mem_m_rw_shift{}; - FF avm_mem_m_ind_op_c{}; - FF avm_mem_m_val{}; - FF avm_mem_m_lastAccess{}; FF avm_mem_m_tag_err{}; - FF avm_mem_m_addr{}; - FF avm_mem_m_sub_clk{}; - FF avm_mem_m_op_a{}; + FF avm_mem_m_ind_op_c{}; }; inline std::string get_relation_label_avm_mem(int index) { switch (index) { + case 14: + return "MEM_READ_WRITE_TAG_CONSISTENCY"; + case 12: return "MEM_LAST_ACCESS_DELIMITER"; - case 15: - return "MEM_ZERO_INIT"; + case 19: + return "NO_TAG_ERR_WRITE"; case 13: return "MEM_READ_WRITE_VAL_CONSISTENCY"; - case 16: - return "MEM_IN_TAG_CONSISTENCY_1"; + case 15: + return "MEM_ZERO_INIT"; - case 14: - return "MEM_READ_WRITE_TAG_CONSISTENCY"; + case 26: + return "MOV_SAME_TAG"; case 17: return "MEM_IN_TAG_CONSISTENCY_2"; - case 24: - return "MOV_SAME_TAG"; + case 16: + return "MEM_IN_TAG_CONSISTENCY_1"; } return std::to_string(index); } @@ -61,8 +65,8 @@ template class avm_memImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }; template @@ -217,7 +221,8 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(16); - auto tmp = (((avm_mem_m_in_tag - avm_mem_m_tag) * (-avm_mem_m_one_min_inv + FF(1))) - avm_mem_m_tag_err); + auto tmp = ((-avm_mem_m_rw + FF(1)) * + (((avm_mem_r_in_tag - avm_mem_m_tag) * (-avm_mem_m_one_min_inv + FF(1))) - avm_mem_m_tag_err)); tmp *= scaling_factor; std::get<16>(evals) += tmp; } @@ -233,7 +238,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(18); - auto tmp = (avm_mem_m_ind_op_a * (avm_mem_m_in_tag - FF(3))); + auto tmp = (avm_mem_m_rw * (avm_mem_w_in_tag - avm_mem_m_tag)); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -241,7 +246,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(19); - auto tmp = (avm_mem_m_ind_op_b * (avm_mem_m_in_tag - FF(3))); + auto tmp = (avm_mem_m_rw * avm_mem_m_tag_err); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -249,7 +254,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = (avm_mem_m_ind_op_c * (avm_mem_m_in_tag - FF(3))); + auto tmp = (avm_mem_m_ind_op_a * (avm_mem_r_in_tag - FF(3))); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -257,7 +262,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = (avm_mem_m_ind_op_a * avm_mem_m_rw); + auto tmp = (avm_mem_m_ind_op_b * (avm_mem_r_in_tag - FF(3))); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -265,7 +270,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = (avm_mem_m_ind_op_b * avm_mem_m_rw); + auto tmp = (avm_mem_m_ind_op_c * (avm_mem_r_in_tag - FF(3))); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -273,7 +278,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (avm_mem_m_ind_op_c * avm_mem_m_rw); + auto tmp = (avm_mem_m_ind_op_a * avm_mem_m_rw); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -281,10 +286,26 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = (avm_mem_m_sel_mov * avm_mem_m_tag_err); + auto tmp = (avm_mem_m_ind_op_b * avm_mem_m_rw); tmp *= scaling_factor; std::get<24>(evals) += tmp; } + // Contribution 25 + { + Avm_DECLARE_VIEWS(25); + + auto tmp = (avm_mem_m_ind_op_c * avm_mem_m_rw); + tmp *= scaling_factor; + std::get<25>(evals) += tmp; + } + // Contribution 26 + { + Avm_DECLARE_VIEWS(26); + + auto tmp = (avm_mem_m_sel_mov * avm_mem_m_tag_err); + tmp *= scaling_factor; + std::get<26>(evals) += tmp; + } } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp index 3afa82ed463..8220b92dcb7 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -12,7 +12,8 @@ [[maybe_unused]] auto avm_mem_m_lastAccess = View(new_term.avm_mem_m_lastAccess); \ [[maybe_unused]] auto avm_mem_m_last = View(new_term.avm_mem_m_last); \ [[maybe_unused]] auto avm_mem_m_rw = View(new_term.avm_mem_m_rw); \ - [[maybe_unused]] auto avm_mem_m_in_tag = View(new_term.avm_mem_m_in_tag); \ + [[maybe_unused]] auto avm_mem_r_in_tag = View(new_term.avm_mem_r_in_tag); \ + [[maybe_unused]] auto avm_mem_w_in_tag = View(new_term.avm_mem_w_in_tag); \ [[maybe_unused]] auto avm_mem_m_op_a = View(new_term.avm_mem_m_op_a); \ [[maybe_unused]] auto avm_mem_m_op_b = View(new_term.avm_mem_m_op_b); \ [[maybe_unused]] auto avm_mem_m_op_c = View(new_term.avm_mem_m_op_c); \ @@ -91,7 +92,8 @@ [[maybe_unused]] auto avm_main_sel_op_xor = View(new_term.avm_main_sel_op_xor); \ [[maybe_unused]] auto avm_main_alu_sel = View(new_term.avm_main_alu_sel); \ [[maybe_unused]] auto avm_main_bin_sel = View(new_term.avm_main_bin_sel); \ - [[maybe_unused]] auto avm_main_in_tag = View(new_term.avm_main_in_tag); \ + [[maybe_unused]] auto avm_main_r_in_tag = View(new_term.avm_main_r_in_tag); \ + [[maybe_unused]] auto avm_main_w_in_tag = View(new_term.avm_main_w_in_tag); \ [[maybe_unused]] auto avm_main_op_err = View(new_term.avm_main_op_err); \ [[maybe_unused]] auto avm_main_tag_err = View(new_term.avm_main_tag_err); \ [[maybe_unused]] auto avm_main_inv = View(new_term.avm_main_inv); \ @@ -131,22 +133,22 @@ [[maybe_unused]] auto lookup_byte_operations_counts = View(new_term.lookup_byte_operations_counts); \ [[maybe_unused]] auto incl_main_tag_err_counts = View(new_term.incl_main_tag_err_counts); \ [[maybe_unused]] auto incl_mem_tag_err_counts = View(new_term.incl_mem_tag_err_counts); \ - [[maybe_unused]] auto avm_binary_acc_ic_shift = View(new_term.avm_binary_acc_ic_shift); \ - [[maybe_unused]] auto avm_binary_op_id_shift = View(new_term.avm_binary_op_id_shift); \ - [[maybe_unused]] auto avm_binary_acc_ia_shift = View(new_term.avm_binary_acc_ia_shift); \ - [[maybe_unused]] auto avm_binary_mem_tag_ctr_shift = View(new_term.avm_binary_mem_tag_ctr_shift); \ - [[maybe_unused]] auto avm_binary_acc_ib_shift = View(new_term.avm_binary_acc_ib_shift); \ - [[maybe_unused]] auto avm_alu_alu_u16_r3_shift = View(new_term.avm_alu_alu_u16_r3_shift); \ - [[maybe_unused]] auto avm_alu_alu_u16_r6_shift = View(new_term.avm_alu_alu_u16_r6_shift); \ + [[maybe_unused]] auto avm_mem_m_rw_shift = View(new_term.avm_mem_m_rw_shift); \ + [[maybe_unused]] auto avm_mem_m_tag_shift = View(new_term.avm_mem_m_tag_shift); \ + [[maybe_unused]] auto avm_mem_m_val_shift = View(new_term.avm_mem_m_val_shift); \ + [[maybe_unused]] auto avm_mem_m_addr_shift = View(new_term.avm_mem_m_addr_shift); \ + [[maybe_unused]] auto avm_main_pc_shift = View(new_term.avm_main_pc_shift); \ + [[maybe_unused]] auto avm_main_internal_return_ptr_shift = View(new_term.avm_main_internal_return_ptr_shift); \ + [[maybe_unused]] auto avm_alu_alu_u16_r2_shift = View(new_term.avm_alu_alu_u16_r2_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r0_shift = View(new_term.avm_alu_alu_u16_r0_shift); \ + [[maybe_unused]] auto avm_alu_alu_u16_r3_shift = View(new_term.avm_alu_alu_u16_r3_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r1_shift = View(new_term.avm_alu_alu_u16_r1_shift); \ - [[maybe_unused]] auto avm_alu_alu_u16_r2_shift = View(new_term.avm_alu_alu_u16_r2_shift); \ - [[maybe_unused]] auto avm_alu_alu_u16_r7_shift = View(new_term.avm_alu_alu_u16_r7_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r4_shift = View(new_term.avm_alu_alu_u16_r4_shift); \ + [[maybe_unused]] auto avm_alu_alu_u16_r7_shift = View(new_term.avm_alu_alu_u16_r7_shift); \ + [[maybe_unused]] auto avm_alu_alu_u16_r6_shift = View(new_term.avm_alu_alu_u16_r6_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r5_shift = View(new_term.avm_alu_alu_u16_r5_shift); \ - [[maybe_unused]] auto avm_main_internal_return_ptr_shift = View(new_term.avm_main_internal_return_ptr_shift); \ - [[maybe_unused]] auto avm_main_pc_shift = View(new_term.avm_main_pc_shift); \ - [[maybe_unused]] auto avm_mem_m_tag_shift = View(new_term.avm_mem_m_tag_shift); \ - [[maybe_unused]] auto avm_mem_m_val_shift = View(new_term.avm_mem_m_val_shift); \ - [[maybe_unused]] auto avm_mem_m_addr_shift = View(new_term.avm_mem_m_addr_shift); \ - [[maybe_unused]] auto avm_mem_m_rw_shift = View(new_term.avm_mem_m_rw_shift); + [[maybe_unused]] auto avm_binary_mem_tag_ctr_shift = View(new_term.avm_binary_mem_tag_ctr_shift); \ + [[maybe_unused]] auto avm_binary_acc_ia_shift = View(new_term.avm_binary_acc_ia_shift); \ + [[maybe_unused]] auto avm_binary_op_id_shift = View(new_term.avm_binary_op_id_shift); \ + [[maybe_unused]] auto avm_binary_acc_ib_shift = View(new_term.avm_binary_acc_ib_shift); \ + [[maybe_unused]] auto avm_binary_acc_ic_shift = View(new_term.avm_binary_acc_ic_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp index a83ab5eafeb..434fe76f8fb 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp @@ -59,7 +59,7 @@ class perm_main_alu_permutation_settings { in.avm_main_sel_op_mul, in.avm_main_sel_op_eq, in.avm_main_sel_op_not, - in.avm_main_in_tag, + in.avm_main_r_in_tag, in.avm_alu_alu_clk, in.avm_alu_alu_ia, in.avm_alu_alu_ib, @@ -105,7 +105,7 @@ class perm_main_alu_permutation_settings { in.avm_main_sel_op_mul, in.avm_main_sel_op_eq, in.avm_main_sel_op_not, - in.avm_main_in_tag, + in.avm_main_r_in_tag, in.avm_alu_alu_clk, in.avm_alu_alu_ia, in.avm_alu_alu_ib, diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp index 1c68236d82f..842f5812b4f 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp @@ -54,7 +54,7 @@ class perm_main_bin_permutation_settings { in.avm_main_ib, in.avm_main_ic, in.avm_main_bin_op_id, - in.avm_main_in_tag, + in.avm_main_r_in_tag, in.avm_binary_acc_ia, in.avm_binary_acc_ib, in.avm_binary_acc_ic, @@ -90,7 +90,7 @@ class perm_main_bin_permutation_settings { in.avm_main_ib, in.avm_main_ic, in.avm_main_bin_op_id, - in.avm_main_in_tag, + in.avm_main_r_in_tag, in.avm_binary_acc_ia, in.avm_binary_acc_ib, in.avm_binary_acc_ic, diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_a.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_a.hpp index d7115275c10..2f98b563669 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_a.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_a.hpp @@ -12,7 +12,7 @@ namespace bb { class perm_main_mem_a_permutation_settings { public: // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 6; + constexpr static size_t COLUMNS_PER_SET = 7; /** * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the @@ -54,13 +54,15 @@ class perm_main_mem_a_permutation_settings { in.avm_main_mem_idx_a, in.avm_main_ia, in.avm_main_rwa, - in.avm_main_in_tag, + in.avm_main_r_in_tag, + in.avm_main_w_in_tag, in.avm_main_sel_mov, in.avm_mem_m_clk, in.avm_mem_m_addr, in.avm_mem_m_val, in.avm_mem_m_rw, - in.avm_mem_m_in_tag, + in.avm_mem_r_in_tag, + in.avm_mem_w_in_tag, in.avm_mem_m_sel_mov); } @@ -92,13 +94,15 @@ class perm_main_mem_a_permutation_settings { in.avm_main_mem_idx_a, in.avm_main_ia, in.avm_main_rwa, - in.avm_main_in_tag, + in.avm_main_r_in_tag, + in.avm_main_w_in_tag, in.avm_main_sel_mov, in.avm_mem_m_clk, in.avm_mem_m_addr, in.avm_mem_m_val, in.avm_mem_m_rw, - in.avm_mem_m_in_tag, + in.avm_mem_r_in_tag, + in.avm_mem_w_in_tag, in.avm_mem_m_sel_mov); } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_b.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_b.hpp index 071d5a6eb53..743b546a204 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_b.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_b.hpp @@ -12,7 +12,7 @@ namespace bb { class perm_main_mem_b_permutation_settings { public: // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 5; + constexpr static size_t COLUMNS_PER_SET = 6; /** * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the @@ -54,12 +54,14 @@ class perm_main_mem_b_permutation_settings { in.avm_main_mem_idx_b, in.avm_main_ib, in.avm_main_rwb, - in.avm_main_in_tag, + in.avm_main_r_in_tag, + in.avm_main_w_in_tag, in.avm_mem_m_clk, in.avm_mem_m_addr, in.avm_mem_m_val, in.avm_mem_m_rw, - in.avm_mem_m_in_tag); + in.avm_mem_r_in_tag, + in.avm_mem_w_in_tag); } /** @@ -90,12 +92,14 @@ class perm_main_mem_b_permutation_settings { in.avm_main_mem_idx_b, in.avm_main_ib, in.avm_main_rwb, - in.avm_main_in_tag, + in.avm_main_r_in_tag, + in.avm_main_w_in_tag, in.avm_mem_m_clk, in.avm_mem_m_addr, in.avm_mem_m_val, in.avm_mem_m_rw, - in.avm_mem_m_in_tag); + in.avm_mem_r_in_tag, + in.avm_mem_w_in_tag); } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_c.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_c.hpp index 41f22dc0193..cd1a4e071d2 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_c.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_c.hpp @@ -12,7 +12,7 @@ namespace bb { class perm_main_mem_c_permutation_settings { public: // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 5; + constexpr static size_t COLUMNS_PER_SET = 6; /** * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the @@ -54,12 +54,14 @@ class perm_main_mem_c_permutation_settings { in.avm_main_mem_idx_c, in.avm_main_ic, in.avm_main_rwc, - in.avm_main_in_tag, + in.avm_main_r_in_tag, + in.avm_main_w_in_tag, in.avm_mem_m_clk, in.avm_mem_m_addr, in.avm_mem_m_val, in.avm_mem_m_rw, - in.avm_mem_m_in_tag); + in.avm_mem_r_in_tag, + in.avm_mem_w_in_tag); } /** @@ -90,12 +92,14 @@ class perm_main_mem_c_permutation_settings { in.avm_main_mem_idx_c, in.avm_main_ic, in.avm_main_rwc, - in.avm_main_in_tag, + in.avm_main_r_in_tag, + in.avm_main_w_in_tag, in.avm_mem_m_clk, in.avm_mem_m_addr, in.avm_mem_m_val, in.avm_mem_m_rw, - in.avm_mem_m_in_tag); + in.avm_mem_r_in_tag, + in.avm_mem_w_in_tag); } }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp index c14fb217f66..3134bc021f6 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -128,11 +128,19 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; + // Compute - Comparators + case OpCode::EQ: + trace_builder.op_eq(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; // Compute - Bitwise case OpCode::NOT: trace_builder.op_not(std::get(inst.operands.at(0)), std::get(inst.operands.at(2)), - std::get(inst.operands.at(4)), + std::get(inst.operands.at(3)), std::get(inst.operands.at(1))); break; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp index 27a1ac9c63e..104f3de530f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp @@ -25,7 +25,8 @@ void log_avm_trace(std::vector const& trace, size_t beg, size_t end, bool e info("m_val: ", trace.at(i).avm_mem_m_val); info("m_rw: ", trace.at(i).avm_mem_m_rw); info("m_tag: ", trace.at(i).avm_mem_m_tag); - info("m_in_tag: ", trace.at(i).avm_mem_m_in_tag); + info("r_in_tag: ", trace.at(i).avm_mem_r_in_tag); + info("w_in_tag: ", trace.at(i).avm_mem_w_in_tag); info("m_tag_err: ", trace.at(i).avm_mem_m_tag_err); info("m_one_min_inv: ", trace.at(i).avm_mem_m_one_min_inv); @@ -50,7 +51,8 @@ void log_avm_trace(std::vector const& trace, size_t beg, size_t end, bool e info("ia: ", trace.at(i).avm_main_ia); info("ib: ", trace.at(i).avm_main_ib); info("ic: ", trace.at(i).avm_main_ic); - info("in_tag ", trace.at(i).avm_main_in_tag); + info("r_in_tag ", trace.at(i).avm_main_r_in_tag); + info("w_in_tag ", trace.at(i).avm_main_w_in_tag); info("tag_err ", trace.at(i).avm_main_tag_err); info("first: ", trace.at(i).avm_main_first); info("last: ", trace.at(i).avm_main_last); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.cpp index eeb56e30c76..99152396b46 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.cpp @@ -43,14 +43,18 @@ std::vector AvmMemTraceBuilder::finalize() * @param m_sub_clk Sub-clock used to order load/store sub operations * @param m_addr Address pertaining to the memory operation * @param m_val Value (FF) pertaining to the memory operation - * @param m_in_tag Memory tag pertaining to the instruction + * @param m_tag Memory tag associated with the value + * @param r_in_tag Read memory tag pertaining to the instruction + * @param w_in_tag Write memory tag pertaining to the instruction * @param m_rw Boolean telling whether it is a load (false) or store operation (true). */ void AvmMemTraceBuilder::insert_in_mem_trace(uint32_t const m_clk, uint32_t const m_sub_clk, uint32_t const m_addr, FF const& m_val, - AvmMemoryTag const m_in_tag, + AvmMemoryTag const m_tag, + AvmMemoryTag const r_in_tag, + AvmMemoryTag const w_in_tag, bool const m_rw) { mem_trace.emplace_back(MemoryTraceEntry{ @@ -58,8 +62,9 @@ void AvmMemTraceBuilder::insert_in_mem_trace(uint32_t const m_clk, .m_sub_clk = m_sub_clk, .m_addr = m_addr, .m_val = m_val, - .m_tag = m_in_tag, - .m_in_tag = m_in_tag, + .m_tag = m_tag, + .r_in_tag = r_in_tag, + .w_in_tag = w_in_tag, .m_rw = m_rw, }); } @@ -76,17 +81,19 @@ void AvmMemTraceBuilder::insert_in_mem_trace(uint32_t const m_clk, * @param m_sub_clk Sub-clock used to order load/store sub operations * @param m_addr Address pertaining to the memory operation * @param m_val Value (FF) pertaining to the memory operation - * @param m_in_tag Memory tag pertaining to the instruction + * @param r_in_tag Memory read tag pertaining to the instruction + * @param r_in_tag Memory write tag pertaining to the instruction * @param m_tag Memory tag pertaining to the address */ void AvmMemTraceBuilder::load_mismatch_tag_in_mem_trace(uint32_t const m_clk, uint32_t const m_sub_clk, uint32_t const m_addr, FF const& m_val, - AvmMemoryTag const m_in_tag, + AvmMemoryTag const r_in_tag, + AvmMemoryTag const w_in_tag, AvmMemoryTag const m_tag) { - FF one_min_inv = FF(1) - (FF(static_cast(m_in_tag)) - FF(static_cast(m_tag))).invert(); + FF one_min_inv = FF(1) - (FF(static_cast(r_in_tag)) - FF(static_cast(m_tag))).invert(); // Relevant for inclusion (lookup) check #[INCL_MEM_TAG_ERR]. We need to // flag the first memory entry per clk key. The number of memory entries @@ -103,7 +110,8 @@ void AvmMemTraceBuilder::load_mismatch_tag_in_mem_trace(uint32_t const m_clk, .m_addr = m_addr, .m_val = m_val, .m_tag = m_tag, - .m_in_tag = m_in_tag, + .r_in_tag = r_in_tag, + .w_in_tag = w_in_tag, .m_tag_err = true, .m_one_min_inv = one_min_inv, .m_tag_err_count_relevant = tag_err_count_relevant }); @@ -116,22 +124,23 @@ void AvmMemTraceBuilder::load_mismatch_tag_in_mem_trace(uint32_t const m_clk, * @param sub_clk The sub-clock pertaining to the memory operation * @param addr The memory address * @param val The value to be loaded - * @param m_in_tag The memory tag of the instruction + * @param r_in_tag The read memory tag of the instruction + * @param w_in_tag The write memory tag of the instruction * * @return A boolean indicating that memory tag matches (resp. does not match) the * instruction tag. Set to false in case of a mismatch. */ bool AvmMemTraceBuilder::load_from_mem_trace( - uint32_t clk, uint32_t sub_clk, uint32_t addr, FF const& val, AvmMemoryTag m_in_tag) + uint32_t clk, uint32_t sub_clk, uint32_t addr, FF const& val, AvmMemoryTag r_in_tag, AvmMemoryTag w_in_tag) { auto m_tag = memory_tag.at(addr); - if (m_tag == AvmMemoryTag::U0 || m_tag == m_in_tag) { - insert_in_mem_trace(clk, sub_clk, addr, val, m_in_tag, false); + if (m_tag == AvmMemoryTag::U0 || m_tag == r_in_tag) { + insert_in_mem_trace(clk, sub_clk, addr, val, r_in_tag, r_in_tag, w_in_tag, false); return true; } // Handle memory tag inconsistency - load_mismatch_tag_in_mem_trace(clk, sub_clk, addr, val, m_in_tag, m_tag); + load_mismatch_tag_in_mem_trace(clk, sub_clk, addr, val, r_in_tag, w_in_tag, m_tag); return false; } @@ -143,10 +152,11 @@ bool AvmMemTraceBuilder::load_from_mem_trace( * @param interm_reg The intermediate register * @param addr The memory address * @param val The value to be stored - * @param m_in_tag The memory tag of the instruction + * @param r_in_tag The write memory tag of the instruction + * @param w_in_tag The write memory tag of the instruction */ void AvmMemTraceBuilder::store_in_mem_trace( - uint32_t clk, IntermRegister interm_reg, uint32_t addr, FF const& val, AvmMemoryTag m_in_tag) + uint32_t clk, IntermRegister interm_reg, uint32_t addr, FF const& val, AvmMemoryTag r_in_tag, AvmMemoryTag w_in_tag) { uint32_t sub_clk = 0; switch (interm_reg) { @@ -161,7 +171,7 @@ void AvmMemTraceBuilder::store_in_mem_trace( break; } - insert_in_mem_trace(clk, sub_clk, addr, val, m_in_tag, true); + insert_in_mem_trace(clk, sub_clk, addr, val, w_in_tag, r_in_tag, w_in_tag, true); } /** @@ -188,7 +198,8 @@ std::pair AvmMemTraceBuilder::read_and_load_mov_opcode(uint32_ .m_addr = addr, .m_val = val, .m_tag = m_tag, - .m_in_tag = m_tag, + .r_in_tag = m_tag, + .w_in_tag = m_tag, .m_sel_mov = true, }); @@ -203,7 +214,8 @@ std::pair AvmMemTraceBuilder::read_and_load_mov_opcode(uint32_ * @param clk Main clock * @param interm_reg Intermediate register where we load the value * @param addr Memory address to be read and loaded - * @param m_in_tag Memory instruction tag + * @param r_in_tag Read memory instruction tag + * @param w_in_tag Write memory instruction tag * * @return Result of the read operation containing the value and a boolean telling * potential mismatch between instruction tag and memory tag of the address. @@ -211,7 +223,8 @@ std::pair AvmMemTraceBuilder::read_and_load_mov_opcode(uint32_ AvmMemTraceBuilder::MemRead AvmMemTraceBuilder::read_and_load_from_memory(uint32_t const clk, IntermRegister const interm_reg, uint32_t const addr, - AvmMemoryTag const m_in_tag) + AvmMemoryTag const r_in_tag, + AvmMemoryTag const w_in_tag) { uint32_t sub_clk = 0; switch (interm_reg) { @@ -227,7 +240,7 @@ AvmMemTraceBuilder::MemRead AvmMemTraceBuilder::read_and_load_from_memory(uint32 } FF val = memory.at(addr); - bool tagMatch = load_from_mem_trace(clk, sub_clk, addr, val, m_in_tag); + bool tagMatch = load_from_mem_trace(clk, sub_clk, addr, val, r_in_tag, w_in_tag); return MemRead{ .tag_match = tagMatch, @@ -253,7 +266,7 @@ AvmMemTraceBuilder::MemRead AvmMemTraceBuilder::indirect_read_and_load_from_memo } FF val = memory.at(addr); - bool tagMatch = load_from_mem_trace(clk, sub_clk, addr, val, AvmMemoryTag::U32); + bool tagMatch = load_from_mem_trace(clk, sub_clk, addr, val, AvmMemoryTag::U32, AvmMemoryTag::U0); return MemRead{ .tag_match = tagMatch, @@ -270,14 +283,19 @@ AvmMemTraceBuilder::MemRead AvmMemTraceBuilder::indirect_read_and_load_from_memo * @param interm_reg Intermediate register where we write the value * @param addr Memory address to be written to * @param val Value to be written into memory - * @param m_in_tag Memory instruction tag + * @param r_in_tag Read memory instruction tag + * @param w_in_tag Write memory instruction tag */ -void AvmMemTraceBuilder::write_into_memory( - uint32_t const clk, IntermRegister interm_reg, uint32_t addr, FF const& val, AvmMemoryTag m_in_tag) +void AvmMemTraceBuilder::write_into_memory(uint32_t const clk, + IntermRegister interm_reg, + uint32_t addr, + FF const& val, + AvmMemoryTag r_in_tag, + AvmMemoryTag w_in_tag) { memory.at(addr) = val; - memory_tag.at(addr) = m_in_tag; - store_in_mem_trace(clk, interm_reg, addr, val, m_in_tag); + memory_tag.at(addr) = w_in_tag; + store_in_mem_trace(clk, interm_reg, addr, val, r_in_tag, w_in_tag); } } // namespace bb::avm_trace \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.hpp index d31d22ab7eb..cca8f85f762 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_mem_trace.hpp @@ -29,7 +29,8 @@ class AvmMemTraceBuilder { uint32_t m_addr{}; FF m_val{}; AvmMemoryTag m_tag{}; - AvmMemoryTag m_in_tag{}; + AvmMemoryTag r_in_tag{}; + AvmMemoryTag w_in_tag{}; bool m_rw = false; bool m_tag_err = false; FF m_one_min_inv{}; @@ -77,10 +78,15 @@ class AvmMemTraceBuilder { std::vector finalize(); std::pair read_and_load_mov_opcode(uint32_t clk, uint32_t addr); - MemRead read_and_load_from_memory(uint32_t clk, IntermRegister interm_reg, uint32_t addr, AvmMemoryTag m_in_tag); + MemRead read_and_load_from_memory( + uint32_t clk, IntermRegister interm_reg, uint32_t addr, AvmMemoryTag r_in_tag, AvmMemoryTag w_in_tag); MemRead indirect_read_and_load_from_memory(uint32_t clk, IndirectRegister ind_reg, uint32_t addr); - void write_into_memory( - uint32_t clk, IntermRegister interm_reg, uint32_t addr, FF const& val, AvmMemoryTag m_in_tag); + void write_into_memory(uint32_t clk, + IntermRegister interm_reg, + uint32_t addr, + FF const& val, + AvmMemoryTag r_in_tag, + AvmMemoryTag w_in_tag); private: std::vector mem_trace; // Entries will be sorted by m_clk, m_sub_clk after finalize(). @@ -88,17 +94,30 @@ class AvmMemTraceBuilder { std::array memory_tag{}; // The tag of the corresponding memory // entry (aligned with the memory array). - void insert_in_mem_trace( - uint32_t m_clk, uint32_t m_sub_clk, uint32_t m_addr, FF const& m_val, AvmMemoryTag m_in_tag, bool m_rw); + void insert_in_mem_trace(uint32_t m_clk, + uint32_t m_sub_clk, + uint32_t m_addr, + FF const& m_val, + AvmMemoryTag m_tag, + AvmMemoryTag r_in_tag, + AvmMemoryTag w_in_tag, + bool m_rw); + void load_mismatch_tag_in_mem_trace(uint32_t m_clk, uint32_t m_sub_clk, uint32_t m_addr, FF const& m_val, - AvmMemoryTag m_in_tag, + AvmMemoryTag r_in_tag, + AvmMemoryTag w_in_tag, AvmMemoryTag m_tag); - bool load_from_mem_trace(uint32_t clk, uint32_t sub_clk, uint32_t addr, FF const& val, AvmMemoryTag m_in_tag); - void store_in_mem_trace( - uint32_t clk, IntermRegister interm_reg, uint32_t addr, FF const& val, AvmMemoryTag m_in_tag); + bool load_from_mem_trace( + uint32_t clk, uint32_t sub_clk, uint32_t addr, FF const& val, AvmMemoryTag r_in_tag, AvmMemoryTag w_in_tag); + void store_in_mem_trace(uint32_t clk, + IntermRegister interm_reg, + uint32_t addr, + FF const& val, + AvmMemoryTag r_in_tag, + AvmMemoryTag w_in_tag); }; } // namespace bb::avm_trace \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp index 24ec44192ab..49e6ac468f8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -99,8 +99,10 @@ void AvmTraceBuilder::op_add( bool tag_match = res.tag_match; // Reading from memory and loading into ia resp. ib. - auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); - auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + auto read_a = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag, in_tag); + auto read_b = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag, in_tag); tag_match = read_a.tag_match && read_b.tag_match; // a + b = c @@ -113,14 +115,15 @@ void AvmTraceBuilder::op_add( FF c = tag_match ? alu_trace_builder.op_add(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = FF(pc++), .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_add = FF(1), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_ia = a, .avm_main_ib = b, @@ -159,8 +162,10 @@ void AvmTraceBuilder::op_sub( bool tag_match = res.tag_match; // Reading from memory and loading into ia resp. ib. - auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); - auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + auto read_a = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag, in_tag); + auto read_b = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag, in_tag); tag_match = read_a.tag_match && read_b.tag_match; // a - b = c @@ -173,14 +178,15 @@ void AvmTraceBuilder::op_sub( FF c = tag_match ? alu_trace_builder.op_sub(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = FF(pc++), .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_sub = FF(1), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_ia = a, .avm_main_ib = b, @@ -219,8 +225,10 @@ void AvmTraceBuilder::op_mul( bool tag_match = res.tag_match; // Reading from memory and loading into ia resp. ib. - auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); - auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + auto read_a = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag, in_tag); + auto read_b = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag, in_tag); tag_match = read_a.tag_match && read_b.tag_match; // a * b = c @@ -233,14 +241,15 @@ void AvmTraceBuilder::op_mul( FF c = tag_match ? alu_trace_builder.op_mul(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = FF(pc++), .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_mul = FF(1), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_ia = a, .avm_main_ib = b, @@ -279,8 +288,10 @@ void AvmTraceBuilder::op_div( bool tag_match = res.tag_match; // Reading from memory and loading into ia resp. ib. - auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); - auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + auto read_a = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag, in_tag); + auto read_b = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag, in_tag); tag_match = read_a.tag_match && read_b.tag_match; // a * b^(-1) = c @@ -302,14 +313,15 @@ void AvmTraceBuilder::op_div( } // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = FF(pc++), .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_div = FF(1), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), .avm_main_op_err = tag_match ? error : FF(1), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_inv = tag_match ? inv : FF(1), @@ -364,7 +376,7 @@ 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 = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, direct_a_offset, in_tag); + auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, direct_a_offset, in_tag, in_tag); tag_match = read_a.tag_match && tag_match; // ~a = c FF a = read_a.val; @@ -375,14 +387,15 @@ void AvmTraceBuilder::op_not(uint8_t indirect, uint32_t a_offset, uint32_t dst_o FF c = tag_match ? alu_trace_builder.op_not(a, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, direct_dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, direct_dst_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = FF(pc++), .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_not = FF(1), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), .avm_main_tag_err = FF(static_cast(!read_a.tag_match)), .avm_main_ia = a, .avm_main_ic = c, @@ -416,8 +429,10 @@ void AvmTraceBuilder::op_eq( bool tag_match = res.tag_match; // Reading from memory and loading into ia resp. ib. - auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); - auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + auto read_a = mem_trace_builder.read_and_load_from_memory( + clk, IntermRegister::IA, res.direct_a_offset, in_tag, AvmMemoryTag::U8); + auto read_b = mem_trace_builder.read_and_load_from_memory( + clk, IntermRegister::IB, res.direct_b_offset, in_tag, AvmMemoryTag::U8); tag_match = read_a.tag_match && read_b.tag_match; FF a = read_a.val; @@ -429,14 +444,15 @@ void AvmTraceBuilder::op_eq( FF c = tag_match ? alu_trace_builder.op_eq(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, AvmMemoryTag::U8); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = FF(pc++), .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_eq = FF(1), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(AvmMemoryTag::U8)), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_ia = a, .avm_main_ib = b, @@ -466,8 +482,10 @@ void AvmTraceBuilder::op_and( bool tag_match = res.tag_match; // Reading from memory and loading into ia resp. ib. - auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); - auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + auto read_a = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag, in_tag); + auto read_b = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag, in_tag); tag_match = read_a.tag_match && read_b.tag_match; FF a = tag_match ? read_a.val : FF(0); @@ -476,7 +494,7 @@ void AvmTraceBuilder::op_and( FF c = tag_match ? bin_trace_builder.op_and(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -484,7 +502,8 @@ void AvmTraceBuilder::op_and( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_and = FF(1), .avm_main_bin_sel = FF(1), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_ia = a, .avm_main_ib = b, @@ -515,8 +534,10 @@ void AvmTraceBuilder::op_or( bool tag_match = res.tag_match; // Reading from memory and loading into ia resp. ib. - auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); - auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + auto read_a = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag, in_tag); + auto read_b = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag, in_tag); tag_match = read_a.tag_match && read_b.tag_match; FF a = tag_match ? read_a.val : FF(0); @@ -525,7 +546,7 @@ void AvmTraceBuilder::op_or( FF c = tag_match ? bin_trace_builder.op_or(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -533,7 +554,8 @@ void AvmTraceBuilder::op_or( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_or = FF(1), .avm_main_bin_sel = FF(1), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_ia = a, .avm_main_ib = b, @@ -564,8 +586,10 @@ void AvmTraceBuilder::op_xor( bool tag_match = res.tag_match; // Reading from memory and loading into ia resp. ib. - auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag); - auto read_b = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag); + auto read_a = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, res.direct_a_offset, in_tag, in_tag); + auto read_b = + mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, res.direct_b_offset, in_tag, in_tag); tag_match = read_a.tag_match && read_b.tag_match; FF a = tag_match ? read_a.val : FF(0); @@ -574,7 +598,7 @@ void AvmTraceBuilder::op_xor( FF c = tag_match ? bin_trace_builder.op_xor(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -582,7 +606,8 @@ void AvmTraceBuilder::op_xor( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_op_xor = FF(1), .avm_main_bin_sel = FF(1), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_ia = a, .avm_main_ib = b, @@ -622,13 +647,13 @@ void AvmTraceBuilder::set(uint128_t val, uint32_t dst_offset, AvmMemoryTag in_ta auto clk = static_cast(main_trace.size()); auto val_ff = FF{ uint256_t::from_uint128(val) }; - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, val_ff, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, val_ff, AvmMemoryTag::U0, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = FF(pc++), .avm_main_internal_return_ptr = FF(internal_return_ptr), - .avm_main_in_tag = FF(static_cast(in_tag)), + .avm_main_w_in_tag = FF(static_cast(in_tag)), .avm_main_ic = val_ff, .avm_main_mem_op_c = FF(1), .avm_main_rwc = FF(1), @@ -672,14 +697,15 @@ void AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst auto const [val, tag] = mem_trace_builder.read_and_load_mov_opcode(clk, direct_src_offset); // Write into memory from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, direct_dst_offset, val, tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, direct_dst_offset, val, tag, tag); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = pc++, .avm_main_internal_return_ptr = internal_return_ptr, .avm_main_sel_mov = 1, - .avm_main_in_tag = static_cast(tag), + .avm_main_r_in_tag = static_cast(tag), + .avm_main_w_in_tag = static_cast(tag), .avm_main_tag_err = static_cast(!tag_match), .avm_main_ia = val, .avm_main_ic = val, @@ -758,7 +784,7 @@ void AvmTraceBuilder::calldata_copy( uint32_t mem_idx_a = direct_dst_offset + pos; // Storing from Ia - mem_trace_builder.write_into_memory(clk, IntermRegister::IA, mem_idx_a, ia, AvmMemoryTag::FF); + mem_trace_builder.write_into_memory(clk, IntermRegister::IA, mem_idx_a, ia, AvmMemoryTag::U0, AvmMemoryTag::FF); if (copy_size - pos > 1) { ib = call_data_mem.at(cd_offset + pos + 1); @@ -767,7 +793,8 @@ void AvmTraceBuilder::calldata_copy( rwb = 1; // Storing from Ib - mem_trace_builder.write_into_memory(clk, IntermRegister::IB, mem_idx_b, ib, AvmMemoryTag::FF); + mem_trace_builder.write_into_memory( + clk, IntermRegister::IB, mem_idx_b, ib, AvmMemoryTag::U0, AvmMemoryTag::FF); } if (copy_size - pos > 2) { @@ -777,14 +804,15 @@ void AvmTraceBuilder::calldata_copy( rwc = 1; // Storing from Ic - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, mem_idx_c, ic, AvmMemoryTag::FF); + mem_trace_builder.write_into_memory( + clk, IntermRegister::IC, mem_idx_c, ic, AvmMemoryTag::U0, AvmMemoryTag::FF); } main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = FF(pc++), .avm_main_internal_return_ptr = FF(internal_return_ptr), - .avm_main_in_tag = FF(static_cast(AvmMemoryTag::FF)), + .avm_main_w_in_tag = FF(static_cast(AvmMemoryTag::FF)), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_ia = ia, .avm_main_ib = ib, @@ -796,7 +824,7 @@ void AvmTraceBuilder::calldata_copy( .avm_main_rwb = FF(rwb), .avm_main_rwc = FF(rwc), .avm_main_ind_a = indirect_flag ? FF(dst_offset) : FF(0), - .avm_main_ind_op_a = FF(indirect_flag), + .avm_main_ind_op_a = FF(static_cast(indirect_flag)), .avm_main_mem_idx_a = FF(mem_idx_a), .avm_main_mem_idx_b = FF(mem_idx_b), .avm_main_mem_idx_c = FF(mem_idx_c), @@ -868,7 +896,8 @@ std::vector AvmTraceBuilder::return_op(uint8_t indirect, uint32_t ret_offset uint32_t mem_idx_a = direct_ret_offset + pos; // Reading and loading to Ia - auto read_a = mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IA, mem_idx_a, AvmMemoryTag::FF); + auto read_a = mem_trace_builder.read_and_load_from_memory( + clk, IntermRegister::IA, mem_idx_a, AvmMemoryTag::FF, AvmMemoryTag::FF); tag_match = tag_match && read_a.tag_match; FF ia = read_a.val; @@ -879,8 +908,8 @@ std::vector AvmTraceBuilder::return_op(uint8_t indirect, uint32_t ret_offset mem_idx_b = direct_ret_offset + pos + 1; // Reading and loading to Ib - auto read_b = - mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IB, mem_idx_b, AvmMemoryTag::FF); + auto read_b = mem_trace_builder.read_and_load_from_memory( + clk, IntermRegister::IB, mem_idx_b, AvmMemoryTag::FF, AvmMemoryTag::FF); tag_match = tag_match && read_b.tag_match; ib = read_b.val; returnMem.push_back(ib); @@ -891,8 +920,8 @@ std::vector AvmTraceBuilder::return_op(uint8_t indirect, uint32_t ret_offset mem_idx_c = direct_ret_offset + pos + 2; // Reading and loading to Ic - auto read_c = - mem_trace_builder.read_and_load_from_memory(clk, IntermRegister::IC, mem_idx_c, AvmMemoryTag::FF); + auto read_c = mem_trace_builder.read_and_load_from_memory( + clk, IntermRegister::IC, mem_idx_c, AvmMemoryTag::FF, AvmMemoryTag::FF); tag_match = tag_match && read_c.tag_match; ic = read_c.val; returnMem.push_back(ic); @@ -903,7 +932,8 @@ std::vector AvmTraceBuilder::return_op(uint8_t indirect, uint32_t ret_offset .avm_main_pc = FF(pc), .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_halt = FF(1), - .avm_main_in_tag = FF(static_cast(AvmMemoryTag::FF)), + .avm_main_r_in_tag = FF(static_cast(AvmMemoryTag::FF)), + .avm_main_w_in_tag = FF(static_cast(AvmMemoryTag::FF)), .avm_main_tag_err = FF(static_cast(!tag_match)), .avm_main_ia = ia, .avm_main_ib = ib, @@ -994,14 +1024,15 @@ void AvmTraceBuilder::internal_call(uint32_t jmp_dest) internal_call_stack.push(stored_pc); // Add the return location to the memory trace - mem_trace_builder.write_into_memory(clk, IntermRegister::IB, internal_return_ptr, FF(stored_pc), AvmMemoryTag::U32); + mem_trace_builder.write_into_memory( + clk, IntermRegister::IB, internal_return_ptr, FF(stored_pc), AvmMemoryTag::U0, AvmMemoryTag::U32); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = FF(pc), .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_internal_call = FF(1), - .avm_main_in_tag = FF(static_cast(AvmMemoryTag::U32)), + .avm_main_w_in_tag = FF(static_cast(AvmMemoryTag::U32)), .avm_main_ia = FF(jmp_dest), .avm_main_ib = FF(stored_pc), .avm_main_mem_op_b = FF(1), @@ -1032,14 +1063,14 @@ void AvmTraceBuilder::internal_return() // Internal return pointer is decremented // We want to load the value pointed by the internal pointer auto read_a = mem_trace_builder.read_and_load_from_memory( - clk, IntermRegister::IA, internal_return_ptr - 1, AvmMemoryTag::U32); + clk, IntermRegister::IA, internal_return_ptr - 1, AvmMemoryTag::U32, AvmMemoryTag::U0); main_trace.push_back(Row{ .avm_main_clk = clk, .avm_main_pc = pc, .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_sel_internal_return = FF(1), - .avm_main_in_tag = FF(static_cast(AvmMemoryTag::U32)), + .avm_main_r_in_tag = FF(static_cast(AvmMemoryTag::U32)), .avm_main_tag_err = FF(static_cast(!read_a.tag_match)), .avm_main_ia = read_a.val, .avm_main_mem_op_a = FF(1), @@ -1120,7 +1151,8 @@ std::vector AvmTraceBuilder::finalize() dest.avm_mem_m_addr = FF(src.m_addr); dest.avm_mem_m_val = src.m_val; dest.avm_mem_m_rw = FF(static_cast(src.m_rw)); - dest.avm_mem_m_in_tag = FF(static_cast(src.m_in_tag)); + dest.avm_mem_r_in_tag = FF(static_cast(src.r_in_tag)); + dest.avm_mem_w_in_tag = FF(static_cast(src.w_in_tag)); dest.avm_mem_m_tag = FF(static_cast(src.m_tag)); dest.avm_mem_m_tag_err = FF(static_cast(src.m_tag_err)); dest.avm_mem_m_one_min_inv = src.m_one_min_inv; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp index db1f2cee12f..f647cf2fc29 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -42,7 +42,8 @@ template struct AvmFullRow { FF avm_mem_m_lastAccess{}; FF avm_mem_m_last{}; FF avm_mem_m_rw{}; - FF avm_mem_m_in_tag{}; + FF avm_mem_r_in_tag{}; + FF avm_mem_w_in_tag{}; FF avm_mem_m_op_a{}; FF avm_mem_m_op_b{}; FF avm_mem_m_op_c{}; @@ -121,7 +122,8 @@ template struct AvmFullRow { FF avm_main_sel_op_xor{}; FF avm_main_alu_sel{}; FF avm_main_bin_sel{}; - FF avm_main_in_tag{}; + FF avm_main_r_in_tag{}; + FF avm_main_w_in_tag{}; FF avm_main_op_err{}; FF avm_main_tag_err{}; FF avm_main_inv{}; @@ -161,25 +163,25 @@ template struct AvmFullRow { FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; - FF avm_binary_acc_ic_shift{}; - FF avm_binary_op_id_shift{}; - FF avm_binary_acc_ia_shift{}; - FF avm_binary_mem_tag_ctr_shift{}; - FF avm_binary_acc_ib_shift{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u16_r6_shift{}; + FF avm_mem_m_rw_shift{}; + FF avm_mem_m_tag_shift{}; + FF avm_mem_m_val_shift{}; + FF avm_mem_m_addr_shift{}; + FF avm_main_pc_shift{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_alu_alu_u16_r2_shift{}; FF avm_alu_alu_u16_r0_shift{}; + FF avm_alu_alu_u16_r3_shift{}; FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r7_shift{}; FF avm_alu_alu_u16_r4_shift{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u16_r6_shift{}; FF avm_alu_alu_u16_r5_shift{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_pc_shift{}; - FF avm_mem_m_tag_shift{}; - FF avm_mem_m_val_shift{}; - FF avm_mem_m_addr_shift{}; - FF avm_mem_m_rw_shift{}; + FF avm_binary_mem_tag_ctr_shift{}; + FF avm_binary_acc_ia_shift{}; + FF avm_binary_op_id_shift{}; + FF avm_binary_acc_ib_shift{}; + FF avm_binary_acc_ic_shift{}; }; class AvmCircuitBuilder { @@ -192,8 +194,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 148; - static constexpr size_t num_polys = 129; + static constexpr size_t num_fixed_columns = 150; + static constexpr size_t num_polys = 131; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -219,7 +221,8 @@ class AvmCircuitBuilder { polys.avm_mem_m_lastAccess[i] = rows[i].avm_mem_m_lastAccess; polys.avm_mem_m_last[i] = rows[i].avm_mem_m_last; polys.avm_mem_m_rw[i] = rows[i].avm_mem_m_rw; - polys.avm_mem_m_in_tag[i] = rows[i].avm_mem_m_in_tag; + polys.avm_mem_r_in_tag[i] = rows[i].avm_mem_r_in_tag; + polys.avm_mem_w_in_tag[i] = rows[i].avm_mem_w_in_tag; polys.avm_mem_m_op_a[i] = rows[i].avm_mem_m_op_a; polys.avm_mem_m_op_b[i] = rows[i].avm_mem_m_op_b; polys.avm_mem_m_op_c[i] = rows[i].avm_mem_m_op_c; @@ -298,7 +301,8 @@ class AvmCircuitBuilder { polys.avm_main_sel_op_xor[i] = rows[i].avm_main_sel_op_xor; polys.avm_main_alu_sel[i] = rows[i].avm_main_alu_sel; polys.avm_main_bin_sel[i] = rows[i].avm_main_bin_sel; - polys.avm_main_in_tag[i] = rows[i].avm_main_in_tag; + polys.avm_main_r_in_tag[i] = rows[i].avm_main_r_in_tag; + polys.avm_main_w_in_tag[i] = rows[i].avm_main_w_in_tag; polys.avm_main_op_err[i] = rows[i].avm_main_op_err; polys.avm_main_tag_err[i] = rows[i].avm_main_tag_err; polys.avm_main_inv[i] = rows[i].avm_main_inv; @@ -340,25 +344,25 @@ class AvmCircuitBuilder { polys.incl_mem_tag_err_counts[i] = rows[i].incl_mem_tag_err_counts; } - polys.avm_binary_acc_ic_shift = Polynomial(polys.avm_binary_acc_ic.shifted()); - polys.avm_binary_op_id_shift = Polynomial(polys.avm_binary_op_id.shifted()); - polys.avm_binary_acc_ia_shift = Polynomial(polys.avm_binary_acc_ia.shifted()); - polys.avm_binary_mem_tag_ctr_shift = Polynomial(polys.avm_binary_mem_tag_ctr.shifted()); - polys.avm_binary_acc_ib_shift = Polynomial(polys.avm_binary_acc_ib.shifted()); - polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); - polys.avm_alu_alu_u16_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); + polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); + polys.avm_mem_m_tag_shift = Polynomial(polys.avm_mem_m_tag.shifted()); + polys.avm_mem_m_val_shift = Polynomial(polys.avm_mem_m_val.shifted()); + polys.avm_mem_m_addr_shift = Polynomial(polys.avm_mem_m_addr.shifted()); + polys.avm_main_pc_shift = Polynomial(polys.avm_main_pc.shifted()); + polys.avm_main_internal_return_ptr_shift = Polynomial(polys.avm_main_internal_return_ptr.shifted()); + polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.shifted()); + polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.shifted()); - polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); - polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); polys.avm_alu_alu_u16_r4_shift = Polynomial(polys.avm_alu_alu_u16_r4.shifted()); + polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); + polys.avm_alu_alu_u16_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); polys.avm_alu_alu_u16_r5_shift = Polynomial(polys.avm_alu_alu_u16_r5.shifted()); - polys.avm_main_internal_return_ptr_shift = Polynomial(polys.avm_main_internal_return_ptr.shifted()); - polys.avm_main_pc_shift = Polynomial(polys.avm_main_pc.shifted()); - polys.avm_mem_m_tag_shift = Polynomial(polys.avm_mem_m_tag.shifted()); - polys.avm_mem_m_val_shift = Polynomial(polys.avm_mem_m_val.shifted()); - polys.avm_mem_m_addr_shift = Polynomial(polys.avm_mem_m_addr.shifted()); - polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); + polys.avm_binary_mem_tag_ctr_shift = Polynomial(polys.avm_binary_mem_tag_ctr.shifted()); + polys.avm_binary_acc_ia_shift = Polynomial(polys.avm_binary_acc_ia.shifted()); + polys.avm_binary_op_id_shift = Polynomial(polys.avm_binary_op_id.shifted()); + polys.avm_binary_acc_ib_shift = Polynomial(polys.avm_binary_acc_ib.shifted()); + polys.avm_binary_acc_ic_shift = Polynomial(polys.avm_binary_acc_ic.shifted()); return polys; } @@ -430,20 +434,20 @@ class AvmCircuitBuilder { return true; }; - if (!evaluate_relation.template operator()>("avm_binary", - Avm_vm::get_relation_label_avm_binary)) { - return false; - } - if (!evaluate_relation.template operator()>("avm_alu", - Avm_vm::get_relation_label_avm_alu)) { + if (!evaluate_relation.template operator()>("avm_mem", + Avm_vm::get_relation_label_avm_mem)) { return false; } if (!evaluate_relation.template operator()>("avm_main", Avm_vm::get_relation_label_avm_main)) { return false; } - if (!evaluate_relation.template operator()>("avm_mem", - Avm_vm::get_relation_label_avm_mem)) { + if (!evaluate_relation.template operator()>("avm_alu", + Avm_vm::get_relation_label_avm_alu)) { + return false; + } + if (!evaluate_relation.template operator()>("avm_binary", + Avm_vm::get_relation_label_avm_binary)) { return false; } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 81f872a6b56..a9350ba2dd2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -46,16 +46,16 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 127; + static constexpr size_t NUM_WITNESS_ENTITIES = 129; 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 = 148; + static constexpr size_t NUM_ALL_ENTITIES = 150; - using Relations = std::tuple, - Avm_vm::avm_alu, + using Relations = std::tuple, Avm_vm::avm_main, - Avm_vm::avm_mem, + Avm_vm::avm_alu, + Avm_vm::avm_binary, perm_main_alu_relation, perm_main_bin_relation, perm_main_mem_a_relation, @@ -105,7 +105,8 @@ class AvmFlavor { avm_mem_m_lastAccess, avm_mem_m_last, avm_mem_m_rw, - avm_mem_m_in_tag, + avm_mem_r_in_tag, + avm_mem_w_in_tag, avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, @@ -184,7 +185,8 @@ class AvmFlavor { avm_main_sel_op_xor, avm_main_alu_sel, avm_main_bin_sel, - avm_main_in_tag, + avm_main_r_in_tag, + avm_main_w_in_tag, avm_main_op_err, avm_main_tag_err, avm_main_inv, @@ -235,7 +237,8 @@ class AvmFlavor { avm_mem_m_lastAccess, avm_mem_m_last, avm_mem_m_rw, - avm_mem_m_in_tag, + avm_mem_r_in_tag, + avm_mem_w_in_tag, avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, @@ -314,7 +317,8 @@ class AvmFlavor { avm_main_sel_op_xor, avm_main_alu_sel, avm_main_bin_sel, - avm_main_in_tag, + avm_main_r_in_tag, + avm_main_w_in_tag, avm_main_op_err, avm_main_tag_err, avm_main_inv, @@ -371,7 +375,8 @@ class AvmFlavor { avm_mem_m_lastAccess, avm_mem_m_last, avm_mem_m_rw, - avm_mem_m_in_tag, + avm_mem_r_in_tag, + avm_mem_w_in_tag, avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, @@ -450,7 +455,8 @@ class AvmFlavor { avm_main_sel_op_xor, avm_main_alu_sel, avm_main_bin_sel, - avm_main_in_tag, + avm_main_r_in_tag, + avm_main_w_in_tag, avm_main_op_err, avm_main_tag_err, avm_main_inv, @@ -490,25 +496,25 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_binary_acc_ic_shift, - avm_binary_op_id_shift, - avm_binary_acc_ia_shift, - avm_binary_mem_tag_ctr_shift, - avm_binary_acc_ib_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r6_shift, + avm_mem_m_rw_shift, + avm_mem_m_tag_shift, + avm_mem_m_val_shift, + avm_mem_m_addr_shift, + avm_main_pc_shift, + avm_main_internal_return_ptr_shift, + avm_alu_alu_u16_r2_shift, avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r3_shift, avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r5_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_mem_m_tag_shift, - avm_mem_m_val_shift, - avm_mem_m_addr_shift, - avm_mem_m_rw_shift) + avm_binary_mem_tag_ctr_shift, + avm_binary_acc_ia_shift, + avm_binary_op_id_shift, + avm_binary_acc_ib_shift, + avm_binary_acc_ic_shift) RefVector get_wires() { @@ -522,7 +528,8 @@ class AvmFlavor { avm_mem_m_lastAccess, avm_mem_m_last, avm_mem_m_rw, - avm_mem_m_in_tag, + avm_mem_r_in_tag, + avm_mem_w_in_tag, avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, @@ -601,7 +608,8 @@ class AvmFlavor { avm_main_sel_op_xor, avm_main_alu_sel, avm_main_bin_sel, - avm_main_in_tag, + avm_main_r_in_tag, + avm_main_w_in_tag, avm_main_op_err, avm_main_tag_err, avm_main_inv, @@ -641,25 +649,25 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, - avm_binary_acc_ic_shift, - avm_binary_op_id_shift, - avm_binary_acc_ia_shift, - avm_binary_mem_tag_ctr_shift, - avm_binary_acc_ib_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r6_shift, + avm_mem_m_rw_shift, + avm_mem_m_tag_shift, + avm_mem_m_val_shift, + avm_mem_m_addr_shift, + avm_main_pc_shift, + avm_main_internal_return_ptr_shift, + avm_alu_alu_u16_r2_shift, avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r3_shift, avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r5_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift, - avm_mem_m_tag_shift, - avm_mem_m_val_shift, - avm_mem_m_addr_shift, - avm_mem_m_rw_shift }; + avm_binary_mem_tag_ctr_shift, + avm_binary_acc_ia_shift, + avm_binary_op_id_shift, + avm_binary_acc_ib_shift, + avm_binary_acc_ic_shift }; }; RefVector get_unshifted() { @@ -673,7 +681,8 @@ class AvmFlavor { avm_mem_m_lastAccess, avm_mem_m_last, avm_mem_m_rw, - avm_mem_m_in_tag, + avm_mem_r_in_tag, + avm_mem_w_in_tag, avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, @@ -752,7 +761,8 @@ class AvmFlavor { avm_main_sel_op_xor, avm_main_alu_sel, avm_main_bin_sel, - avm_main_in_tag, + avm_main_r_in_tag, + avm_main_w_in_tag, avm_main_op_err, avm_main_tag_err, avm_main_inv, @@ -795,29 +805,23 @@ class AvmFlavor { }; RefVector get_to_be_shifted() { - return { avm_binary_acc_ic, avm_binary_op_id, - avm_binary_acc_ia, avm_binary_mem_tag_ctr, - avm_binary_acc_ib, avm_alu_alu_u16_r3, - avm_alu_alu_u16_r6, avm_alu_alu_u16_r0, - avm_alu_alu_u16_r1, avm_alu_alu_u16_r2, - avm_alu_alu_u16_r7, avm_alu_alu_u16_r4, - avm_alu_alu_u16_r5, avm_main_internal_return_ptr, - avm_main_pc, avm_mem_m_tag, - avm_mem_m_val, avm_mem_m_addr, - avm_mem_m_rw }; + return { avm_mem_m_rw, avm_mem_m_tag, avm_mem_m_val, + avm_mem_m_addr, avm_main_pc, avm_main_internal_return_ptr, + avm_alu_alu_u16_r2, avm_alu_alu_u16_r0, avm_alu_alu_u16_r3, + avm_alu_alu_u16_r1, avm_alu_alu_u16_r4, avm_alu_alu_u16_r7, + avm_alu_alu_u16_r6, avm_alu_alu_u16_r5, avm_binary_mem_tag_ctr, + avm_binary_acc_ia, avm_binary_op_id, avm_binary_acc_ib, + avm_binary_acc_ic }; }; RefVector get_shifted() { - return { avm_binary_acc_ic_shift, avm_binary_op_id_shift, - avm_binary_acc_ia_shift, avm_binary_mem_tag_ctr_shift, - avm_binary_acc_ib_shift, avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r4_shift, - avm_alu_alu_u16_r5_shift, avm_main_internal_return_ptr_shift, - avm_main_pc_shift, avm_mem_m_tag_shift, - avm_mem_m_val_shift, avm_mem_m_addr_shift, - avm_mem_m_rw_shift }; + return { avm_mem_m_rw_shift, avm_mem_m_tag_shift, avm_mem_m_val_shift, + avm_mem_m_addr_shift, avm_main_pc_shift, avm_main_internal_return_ptr_shift, + avm_alu_alu_u16_r2_shift, avm_alu_alu_u16_r0_shift, avm_alu_alu_u16_r3_shift, + avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r4_shift, avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r6_shift, avm_alu_alu_u16_r5_shift, avm_binary_mem_tag_ctr_shift, + avm_binary_acc_ia_shift, avm_binary_op_id_shift, avm_binary_acc_ib_shift, + avm_binary_acc_ic_shift }; }; }; @@ -830,16 +834,13 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_binary_acc_ic, avm_binary_op_id, - avm_binary_acc_ia, avm_binary_mem_tag_ctr, - avm_binary_acc_ib, avm_alu_alu_u16_r3, - avm_alu_alu_u16_r6, avm_alu_alu_u16_r0, - avm_alu_alu_u16_r1, avm_alu_alu_u16_r2, - avm_alu_alu_u16_r7, avm_alu_alu_u16_r4, - avm_alu_alu_u16_r5, avm_main_internal_return_ptr, - avm_main_pc, avm_mem_m_tag, - avm_mem_m_val, avm_mem_m_addr, - avm_mem_m_rw }; + return { avm_mem_m_rw, avm_mem_m_tag, avm_mem_m_val, + avm_mem_m_addr, avm_main_pc, avm_main_internal_return_ptr, + avm_alu_alu_u16_r2, avm_alu_alu_u16_r0, avm_alu_alu_u16_r3, + avm_alu_alu_u16_r1, avm_alu_alu_u16_r4, avm_alu_alu_u16_r7, + avm_alu_alu_u16_r6, avm_alu_alu_u16_r5, avm_binary_mem_tag_ctr, + avm_binary_acc_ia, avm_binary_op_id, avm_binary_acc_ib, + avm_binary_acc_ic }; }; // The plookup wires that store plookup read data. @@ -926,7 +927,8 @@ class AvmFlavor { Base::avm_mem_m_lastAccess = "AVM_MEM_M_LASTACCESS"; Base::avm_mem_m_last = "AVM_MEM_M_LAST"; Base::avm_mem_m_rw = "AVM_MEM_M_RW"; - Base::avm_mem_m_in_tag = "AVM_MEM_M_IN_TAG"; + Base::avm_mem_r_in_tag = "AVM_MEM_R_IN_TAG"; + Base::avm_mem_w_in_tag = "AVM_MEM_W_IN_TAG"; Base::avm_mem_m_op_a = "AVM_MEM_M_OP_A"; Base::avm_mem_m_op_b = "AVM_MEM_M_OP_B"; Base::avm_mem_m_op_c = "AVM_MEM_M_OP_C"; @@ -1005,7 +1007,8 @@ class AvmFlavor { Base::avm_main_sel_op_xor = "AVM_MAIN_SEL_OP_XOR"; Base::avm_main_alu_sel = "AVM_MAIN_ALU_SEL"; Base::avm_main_bin_sel = "AVM_MAIN_BIN_SEL"; - Base::avm_main_in_tag = "AVM_MAIN_IN_TAG"; + Base::avm_main_r_in_tag = "AVM_MAIN_R_IN_TAG"; + Base::avm_main_w_in_tag = "AVM_MAIN_W_IN_TAG"; Base::avm_main_op_err = "AVM_MAIN_OP_ERR"; Base::avm_main_tag_err = "AVM_MAIN_TAG_ERR"; Base::avm_main_inv = "AVM_MAIN_INV"; @@ -1072,7 +1075,8 @@ class AvmFlavor { Commitment avm_mem_m_lastAccess; Commitment avm_mem_m_last; Commitment avm_mem_m_rw; - Commitment avm_mem_m_in_tag; + Commitment avm_mem_r_in_tag; + Commitment avm_mem_w_in_tag; Commitment avm_mem_m_op_a; Commitment avm_mem_m_op_b; Commitment avm_mem_m_op_c; @@ -1151,7 +1155,8 @@ class AvmFlavor { Commitment avm_main_sel_op_xor; Commitment avm_main_alu_sel; Commitment avm_main_bin_sel; - Commitment avm_main_in_tag; + Commitment avm_main_r_in_tag; + Commitment avm_main_w_in_tag; Commitment avm_main_op_err; Commitment avm_main_tag_err; Commitment avm_main_inv; @@ -1218,7 +1223,8 @@ class AvmFlavor { avm_mem_m_lastAccess = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_m_last = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_m_rw = deserialize_from_buffer(Transcript::proof_data, num_frs_read); - avm_mem_m_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_r_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_w_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_m_op_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_m_op_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_m_op_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1298,7 +1304,8 @@ class AvmFlavor { avm_main_sel_op_xor = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_alu_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_bin_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); - avm_main_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_r_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_w_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_op_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_inv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1369,7 +1376,8 @@ class AvmFlavor { serialize_to_buffer(avm_mem_m_lastAccess, Transcript::proof_data); serialize_to_buffer(avm_mem_m_last, Transcript::proof_data); serialize_to_buffer(avm_mem_m_rw, Transcript::proof_data); - serialize_to_buffer(avm_mem_m_in_tag, Transcript::proof_data); + serialize_to_buffer(avm_mem_r_in_tag, Transcript::proof_data); + serialize_to_buffer(avm_mem_w_in_tag, Transcript::proof_data); serialize_to_buffer(avm_mem_m_op_a, Transcript::proof_data); serialize_to_buffer(avm_mem_m_op_b, Transcript::proof_data); serialize_to_buffer(avm_mem_m_op_c, Transcript::proof_data); @@ -1448,7 +1456,8 @@ class AvmFlavor { serialize_to_buffer(avm_main_sel_op_xor, Transcript::proof_data); serialize_to_buffer(avm_main_alu_sel, Transcript::proof_data); serialize_to_buffer(avm_main_bin_sel, Transcript::proof_data); - serialize_to_buffer(avm_main_in_tag, Transcript::proof_data); + serialize_to_buffer(avm_main_r_in_tag, Transcript::proof_data); + serialize_to_buffer(avm_main_w_in_tag, Transcript::proof_data); serialize_to_buffer(avm_main_op_err, Transcript::proof_data); serialize_to_buffer(avm_main_tag_err, Transcript::proof_data); serialize_to_buffer(avm_main_inv, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 0f651bc29b7..f141e354472 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -61,8 +61,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_mem_m_lastAccess); commitments.avm_mem_m_last = transcript->template receive_from_prover(commitment_labels.avm_mem_m_last); commitments.avm_mem_m_rw = transcript->template receive_from_prover(commitment_labels.avm_mem_m_rw); - commitments.avm_mem_m_in_tag = - transcript->template receive_from_prover(commitment_labels.avm_mem_m_in_tag); + commitments.avm_mem_r_in_tag = + transcript->template receive_from_prover(commitment_labels.avm_mem_r_in_tag); + commitments.avm_mem_w_in_tag = + transcript->template receive_from_prover(commitment_labels.avm_mem_w_in_tag); commitments.avm_mem_m_op_a = transcript->template receive_from_prover(commitment_labels.avm_mem_m_op_a); commitments.avm_mem_m_op_b = transcript->template receive_from_prover(commitment_labels.avm_mem_m_op_b); commitments.avm_mem_m_op_c = transcript->template receive_from_prover(commitment_labels.avm_mem_m_op_c); @@ -211,8 +213,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_main_alu_sel); commitments.avm_main_bin_sel = transcript->template receive_from_prover(commitment_labels.avm_main_bin_sel); - commitments.avm_main_in_tag = - transcript->template receive_from_prover(commitment_labels.avm_main_in_tag); + commitments.avm_main_r_in_tag = + transcript->template receive_from_prover(commitment_labels.avm_main_r_in_tag); + commitments.avm_main_w_in_tag = + transcript->template receive_from_prover(commitment_labels.avm_main_w_in_tag); commitments.avm_main_op_err = transcript->template receive_from_prover(commitment_labels.avm_main_op_err); commitments.avm_main_tag_err = diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp index 3e4992b8c9b..7e5dbf7a26c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp @@ -1,5 +1,7 @@ #include "avm_common.test.hpp" #include "barretenberg/numeric/uint128/uint128.hpp" +#include "barretenberg/vm/avm_trace/avm_common.hpp" +#include namespace tests_avm { using namespace bb::avm_trace; @@ -32,8 +34,8 @@ void common_validate_arithmetic_op(Row const& main_row, EXPECT_EQ(main_row.avm_main_mem_op_b, FF(1)); EXPECT_EQ(main_row.avm_main_rwb, FF(0)); - // Check the instruction tag - EXPECT_EQ(main_row.avm_main_in_tag, FF(static_cast(tag))); + // Check the read instruction tag + EXPECT_EQ(main_row.avm_main_r_in_tag, FF(static_cast(tag))); // Check that intermediate registers are correctly copied in Alu trace EXPECT_EQ(alu_row.avm_alu_alu_ia, a); @@ -66,6 +68,7 @@ Row common_validate_add(std::vector const& trace, EXPECT_TRUE(alu_row != trace.end()); common_validate_arithmetic_op(*row, *alu_row, a, b, c, addr_a, addr_b, addr_c, tag); + EXPECT_EQ(row->avm_main_w_in_tag, FF(static_cast(tag))); // Check that addition selector is set. EXPECT_EQ(row->avm_main_sel_op_add, FF(1)); @@ -95,6 +98,7 @@ Row common_validate_sub(std::vector const& trace, EXPECT_TRUE(alu_row != trace.end()); common_validate_arithmetic_op(*row, *alu_row, a, b, c, addr_a, addr_b, addr_c, tag); + EXPECT_EQ(row->avm_main_w_in_tag, FF(static_cast(tag))); // Check that subtraction selector is set. EXPECT_EQ(row->avm_main_sel_op_sub, FF(1)); @@ -124,6 +128,7 @@ size_t common_validate_mul(std::vector const& trace, EXPECT_TRUE(alu_row != trace.end()); common_validate_arithmetic_op(*row, *alu_row, a, b, c, addr_a, addr_b, addr_c, tag); + EXPECT_EQ(row->avm_main_w_in_tag, FF(static_cast(tag))); // Check that multiplication selector is set. EXPECT_EQ(row->avm_main_sel_op_mul, FF(1)); @@ -131,6 +136,7 @@ size_t common_validate_mul(std::vector const& trace, return static_cast(alu_row - trace.begin()); } + size_t common_validate_eq(std::vector const& trace, FF const& a, FF const& b, @@ -152,6 +158,7 @@ size_t common_validate_eq(std::vector const& trace, EXPECT_TRUE(alu_row != trace.end()); common_validate_arithmetic_op(*row, *alu_row, a, b, c, addr_a, addr_b, addr_c, tag); + EXPECT_EQ(row->avm_main_w_in_tag, FF(static_cast(AvmMemoryTag::U8))); // Check that equality selector is set. EXPECT_EQ(row->avm_main_sel_op_eq, FF(1)); @@ -160,6 +167,22 @@ size_t common_validate_eq(std::vector const& trace, return static_cast(alu_row - trace.begin()); } +// Generate a trace with an EQ opcode operation. +std::vector gen_trace_eq(uint128_t const& a, + uint128_t const& b, + uint32_t const& addr_a, + uint32_t const& addr_b, + uint32_t const& addr_c, + avm_trace::AvmMemoryTag tag) +{ + auto trace_builder = avm_trace::AvmTraceBuilder(); + trace_builder.set(a, addr_a, tag); + trace_builder.set(b, addr_b, tag); + trace_builder.op_eq(0, addr_a, addr_b, addr_c, tag); + trace_builder.return_op(0, 0, 0); + return trace_builder.finalize(); +} + // This function generates a mutated trace of an addition where a and b are the passed inputs. // a and b are stored in memory indices 0 and 1. c_mutated is the wrong result of the addition // and the memory and alu trace are created consistently with the wrong value c_mutated. @@ -675,11 +698,7 @@ TEST_F(AvmArithmeticTestsU8, multiplicationOverflow) // Test of equality on u8 elements TEST_F(AvmArithmeticTestsU8, equality) { - trace_builder.set(128, 0, AvmMemoryTag::U8); - trace_builder.set(128, 1, AvmMemoryTag::U8); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U8); // Memory layout: [128,128,1,0,..,0] - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(128, 128, 0, 1, 2, AvmMemoryTag::U8); auto alu_row_index = common_validate_eq(trace, FF(128), FF(128), FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::U8); auto alu_row = trace.at(alu_row_index); @@ -692,13 +711,9 @@ TEST_F(AvmArithmeticTestsU8, equality) // Test correct non-equality of U8 elements TEST_F(AvmArithmeticTestsU8, nonEquality) { - trace_builder.set(84, 0, AvmMemoryTag::U8); - trace_builder.set(200, 1, AvmMemoryTag::U8); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U8); // Memory layout: [84,200,0,0,..,0] - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(84, 200, 12, 15, 28, AvmMemoryTag::U8); - auto alu_row_index = common_validate_eq(trace, 84, 200, FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::U8); + auto alu_row_index = common_validate_eq(trace, 84, 200, FF(0), FF(12), FF(15), FF(28), AvmMemoryTag::U8); auto alu_row = trace.at(alu_row_index); EXPECT_EQ(alu_row.avm_alu_alu_u8_tag, FF(1)); @@ -861,11 +876,7 @@ TEST_F(AvmArithmeticTestsU16, multiplicationOverflow) // Test of equality on U16 elements TEST_F(AvmArithmeticTestsU16, equality) { - trace_builder.set(35823, 0, AvmMemoryTag::U16); - trace_builder.set(35823, 1, AvmMemoryTag::U16); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U16); - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(35823, 35823, 0, 1, 2, AvmMemoryTag::U16); auto alu_row_index = common_validate_eq(trace, FF(35823), FF(35823), FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::U16); auto alu_row = trace.at(alu_row_index); @@ -878,11 +889,7 @@ TEST_F(AvmArithmeticTestsU16, equality) // Test correct non-equality of U16 elements TEST_F(AvmArithmeticTestsU16, nonEquality) { - trace_builder.set(35'823, 0, AvmMemoryTag::U16); - trace_builder.set(50'123, 1, AvmMemoryTag::U16); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U16); - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(35823, 50123, 0, 1, 2, AvmMemoryTag::U16); auto alu_row_index = common_validate_eq(trace, 35'823, 50'123, FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::U16); auto alu_row = trace.at(alu_row_index); @@ -1060,11 +1067,7 @@ TEST_F(AvmArithmeticTestsU32, multiplicationOverflow) // Test of equality on U32 elements TEST_F(AvmArithmeticTestsU32, equality) { - trace_builder.set(0xb435e9c1, 0, AvmMemoryTag::U32); - trace_builder.set(0xb435e9c1, 1, AvmMemoryTag::U32); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U32); - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(0xb435e9c1, 0xb435e9c1, 0, 1, 2, AvmMemoryTag::U32); auto alu_row_index = common_validate_eq(trace, 0xb435e9c1, 0xb435e9c1, FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::U32); @@ -1078,11 +1081,7 @@ TEST_F(AvmArithmeticTestsU32, equality) // Test correct non-equality of U32 elements TEST_F(AvmArithmeticTestsU32, nonEquality) { - trace_builder.set(0xb435e9c1, 0, AvmMemoryTag::U32); - trace_builder.set(0xb435e9c0, 1, AvmMemoryTag::U32); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U32); - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(0xb435e9c1, 0xb435e9c0, 0, 1, 2, AvmMemoryTag::U32); auto alu_row_index = common_validate_eq(trace, 0xb435e9c1, 0xb435e9c0, FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::U32); @@ -1285,11 +1284,7 @@ TEST_F(AvmArithmeticTestsU64, multiplicationOverflow) TEST_F(AvmArithmeticTestsU64, equality) { - trace_builder.set(0xffffffffffffffe0LLU, 0, AvmMemoryTag::U64); - trace_builder.set(0xffffffffffffffe0LLU, 1, AvmMemoryTag::U64); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U64); - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(0xffffffffffffffe0LLU, 0xffffffffffffffe0LLU, 0, 1, 2, AvmMemoryTag::U64); auto alu_row_index = common_validate_eq( trace, 0xffffffffffffffe0LLU, 0xffffffffffffffe0LLU, FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::U64); @@ -1303,11 +1298,7 @@ TEST_F(AvmArithmeticTestsU64, equality) // Test correct non-equality of U64 elements TEST_F(AvmArithmeticTestsU64, nonEquality) { - trace_builder.set(0xffffffffffffffe0LLU, 0, AvmMemoryTag::U64); - trace_builder.set(0xffffffffffaeffe0LLU, 1, AvmMemoryTag::U64); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U64); - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(0xffffffffffffffe0LLU, 0xffffffffffaeffe0LLU, 0, 1, 2, AvmMemoryTag::U64); auto alu_row_index = common_validate_eq( trace, 0xffffffffffffffe0LLU, 0xffffffffffaeffe0LLU, FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::U64); @@ -1580,11 +1571,7 @@ TEST_F(AvmArithmeticTestsU128, multiplicationOverflow) TEST_F(AvmArithmeticTestsU128, equality) { uint128_t const elem = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; - trace_builder.set(elem, 0, AvmMemoryTag::U128); - trace_builder.set(elem, 1, AvmMemoryTag::U128); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U128); - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(elem, elem, 0, 1, 2, AvmMemoryTag::U128); auto alu_row_index = common_validate_eq(trace, FF(uint256_t::from_uint128(elem)), @@ -1606,11 +1593,7 @@ TEST_F(AvmArithmeticTestsU128, nonEquality) { uint128_t const a = (uint128_t{ 0x5555222233334444LLU } << 64) + uint128_t{ 0x88889999AAAABBBBLLU }; uint128_t const b = a - (0xdeadbeefLLU << 32); - trace_builder.set(a, 0, AvmMemoryTag::U128); - trace_builder.set(b, 1, AvmMemoryTag::U128); - trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::U128); - trace_builder.return_op(0, 0, 0); - auto trace = trace_builder.finalize(); + auto trace = gen_trace_eq(a, b, 0, 1, 2, AvmMemoryTag::U128); auto alu_row_index = common_validate_eq(trace, FF(uint256_t::from_uint128(a)), @@ -1830,6 +1813,23 @@ TEST_F(AvmArithmeticNegativeTestsFF, nonBooleanEq) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for field elements where the tag for c is not U8. +TEST_F(AvmArithmeticNegativeTestsFF, eqOutputWrongTag) +{ + FF elem = FF::modulus - FF(15); + trace_builder.calldata_copy(0, 0, 2, 0, std::vector{ elem, elem }); + trace_builder.op_eq(0, 0, 1, 2, AvmMemoryTag::FF); // Memory Layout [elem, elem, 1, 0..] + trace_builder.return_op(0, 0, 0); + auto trace = trace_builder.finalize(); + + // Find the first row enabling the eq selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_eq == FF(1); }); + ASSERT_TRUE(row != trace.end()); + + row->avm_main_w_in_tag = FF(4); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "EQ_OUTPUT_U8"); +} + // Tests a situation for field elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsFF, invalidInverseDifference) { @@ -1864,7 +1864,7 @@ TEST_F(AvmArithmeticNegativeTestsU8, multiplication) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_MUL_COMMON_2"); } -// Tests a situation for field elements where a != b but c == 1; +// Tests a situation for U8 elements where a != b but c == 1; TEST_F(AvmArithmeticNegativeTestsU8, invalidEquality) { std::vector trace = gen_mutated_trace_eq(FF(10), FF(255), FF(1), FF(0), AvmMemoryTag::U8); @@ -1885,6 +1885,19 @@ TEST_F(AvmArithmeticNegativeTestsU8, nonBooleanEq) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U8 elements where the tag for c is not U8. +TEST_F(AvmArithmeticNegativeTestsU8, eqOutputWrongTag) +{ + auto trace = gen_trace_eq(2, 3, 23, 24, 25, AvmMemoryTag::U8); + + // Find the first row enabling the eq selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_eq == FF(1); }); + ASSERT_TRUE(row != trace.end()); + + row->avm_main_w_in_tag = FF(3); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "EQ_OUTPUT_U8"); +} + // Tests a situation for U8 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU8, invalidInverseDifference) { @@ -1939,6 +1952,19 @@ TEST_F(AvmArithmeticNegativeTestsU16, nonBooleanEq) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U16 elements where the tag for c is not U8. +TEST_F(AvmArithmeticNegativeTestsU16, eqOutputWrongTag) +{ + auto trace = gen_trace_eq(1515, 1515, 23, 24, 25, AvmMemoryTag::U16); + + // Find the first row enabling the eq selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_eq == FF(1); }); + ASSERT_TRUE(row != trace.end()); + + row->avm_main_w_in_tag = FF(5); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "EQ_OUTPUT_U8"); +} + // Tests a situation for U16 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU16, invalidInverseDifference) { @@ -1993,6 +2019,19 @@ TEST_F(AvmArithmeticNegativeTestsU32, nonBooleanEq) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U32 elements where the tag for c is not U8. +TEST_F(AvmArithmeticNegativeTestsU32, eqOutputWrongTag) +{ + auto trace = gen_trace_eq(15, 15, 23, 24, 25, AvmMemoryTag::U32); + + // Find the first row enabling the eq selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_eq == FF(1); }); + ASSERT_TRUE(row != trace.end()); + + row->avm_main_w_in_tag = FF(6); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "EQ_OUTPUT_U8"); +} + // Tests a situation for U32 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU32, invalidInverseDifference) { @@ -2054,6 +2093,19 @@ TEST_F(AvmArithmeticNegativeTestsU64, nonBooleanEq) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U64 elements where the tag for c is not U8. +TEST_F(AvmArithmeticNegativeTestsU64, eqOutputWrongTag) +{ + auto trace = gen_trace_eq(198732, 15, 23, 24, 25, AvmMemoryTag::U64); + + // Find the first row enabling the eq selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_eq == FF(1); }); + ASSERT_TRUE(row != trace.end()); + + row->avm_main_w_in_tag = FF(2); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "EQ_OUTPUT_U8"); +} + // Tests a situation for U64 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU64, invalidInverseDifference) { @@ -2140,6 +2192,19 @@ TEST_F(AvmArithmeticNegativeTestsU128, nonBooleanEq) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "ALU_RES_IS_BOOL"); } +// Tests a situation for U128 elements where the tag for c is not U8. +TEST_F(AvmArithmeticNegativeTestsU128, eqOutputWrongTag) +{ + auto trace = gen_trace_eq(1587, 1587, 23, 24, 25, AvmMemoryTag::U128); + + // Find the first row enabling the eq selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_eq == FF(1); }); + ASSERT_TRUE(row != trace.end()); + + row->avm_main_w_in_tag = FF(4); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "EQ_OUTPUT_U8"); +} + // Tests a situation for U128 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; TEST_F(AvmArithmeticNegativeTestsU128, invalidInverseDifference) { diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp index 3399e5736d3..b73ebc729cd 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_bitwise.test.cpp @@ -46,8 +46,9 @@ void common_validate_op_not(std::vector const& trace, EXPECT_EQ(row->avm_main_mem_op_a, FF(1)); EXPECT_EQ(row->avm_main_rwa, FF(0)); - // Check the instruction tag - EXPECT_EQ(row->avm_main_in_tag, FF(static_cast(tag))); + // Check the instruction tags + EXPECT_EQ(row->avm_main_r_in_tag, FF(static_cast(tag))); + EXPECT_EQ(row->avm_main_w_in_tag, FF(static_cast(tag))); // Check that intermediate registers are correctly copied in Alu trace EXPECT_EQ(alu_row->avm_alu_alu_ia, a); @@ -130,8 +131,9 @@ void common_validate_bit_op(std::vector const& trace, EXPECT_EQ(row->avm_main_mem_op_b, FF(1)); EXPECT_EQ(row->avm_main_rwb, FF(0)); - // Check the instruction tag - EXPECT_EQ(row->avm_main_in_tag, FF(static_cast(tag))); + // Check the instruction tags + EXPECT_EQ(row->avm_main_r_in_tag, FF(static_cast(tag))); + EXPECT_EQ(row->avm_main_w_in_tag, FF(static_cast(tag))); // Check that start row is the same as what is copied into the main trace EXPECT_EQ(bin_row_start->avm_binary_acc_ia, a); @@ -167,6 +169,7 @@ enum BIT_FAILURES { ByteLengthError, IncorrectBinSelector, }; + std::vector gen_mutated_trace_bit(std::vector trace, std::function&& select_row, FF const& c_mutated, @@ -542,10 +545,12 @@ TEST_F(AvmBitwiseNegativeTestsFF, UndefinedOverFF) // we will need to look at a new way of doing this test. for (size_t i = 1; i < 4; i++) { trace.at(i).avm_mem_m_tag = FF(6); - trace.at(i).avm_mem_m_in_tag = FF(6); + trace.at(i).avm_mem_r_in_tag = FF(6); + trace.at(i).avm_mem_w_in_tag = FF(6); trace.at(i).avm_alu_alu_ff_tag = FF::one(); trace.at(i).avm_alu_alu_u8_tag = FF::zero(); - trace.at(i).avm_main_in_tag = FF(6); + trace.at(i).avm_main_r_in_tag = FF(6); + trace.at(i).avm_main_w_in_tag = FF(6); trace.at(i).avm_alu_alu_in_tag = FF(6); } diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp index ea1199a1b2c..0dcaae7b8a7 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp @@ -287,11 +287,12 @@ TEST_F(AvmPermMainMemNegativeTests, wrongInTagIaInMem) { executeSub(21, 3); auto wrong_in_tag = static_cast(AvmMemoryTag::U32); - trace.at(mem_idx_a).avm_mem_m_in_tag = wrong_in_tag; // Correct value: AvmMemoryTag::U8 + trace.at(mem_idx_a).avm_mem_r_in_tag = wrong_in_tag; // Correct value: AvmMemoryTag::U8 trace.at(mem_idx_a).avm_mem_m_tag = wrong_in_tag; // We need to adjust the write operation beforehand (set opcode). - trace.at(mem_idx_a - 1).avm_mem_m_in_tag = wrong_in_tag; + trace.at(mem_idx_a - 1).avm_mem_r_in_tag = wrong_in_tag; + trace.at(mem_idx_a - 1).avm_mem_w_in_tag = wrong_in_tag; trace.at(mem_idx_a - 1).avm_mem_m_tag = wrong_in_tag; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "PERM_MAIN_MEM_A"); @@ -301,11 +302,12 @@ TEST_F(AvmPermMainMemNegativeTests, wrongInTagIbInMem) { executeSub(21, 3); auto wrong_in_tag = static_cast(AvmMemoryTag::U16); - trace.at(mem_idx_b).avm_mem_m_in_tag = wrong_in_tag; // Correct value: AvmMemoryTag::U8 + trace.at(mem_idx_b).avm_mem_r_in_tag = wrong_in_tag; // Correct value: AvmMemoryTag::U8 trace.at(mem_idx_b).avm_mem_m_tag = wrong_in_tag; // We need to adjust the write operation beforehand (set opcode). - trace.at(mem_idx_b - 1).avm_mem_m_in_tag = wrong_in_tag; + trace.at(mem_idx_b - 1).avm_mem_r_in_tag = wrong_in_tag; + trace.at(mem_idx_b - 1).avm_mem_w_in_tag = wrong_in_tag; trace.at(mem_idx_b - 1).avm_mem_m_tag = wrong_in_tag; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "PERM_MAIN_MEM_B"); @@ -315,7 +317,7 @@ TEST_F(AvmPermMainMemNegativeTests, wrongInTagIcInMem) { executeSub(21, 3); auto wrong_in_tag = static_cast(AvmMemoryTag::U128); - trace.at(mem_idx_c).avm_mem_m_in_tag = wrong_in_tag; // Correct value: AvmMemoryTag::U8 + trace.at(mem_idx_c).avm_mem_w_in_tag = wrong_in_tag; // Correct value: AvmMemoryTag::U8 trace.at(mem_idx_c).avm_mem_m_tag = wrong_in_tag; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "PERM_MAIN_MEM_C"); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp index 861403b4b09..5f3d420450a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp @@ -102,13 +102,14 @@ class AvmMemOpcodeTests : public ::testing::Test { AllOf(Field(&Row::avm_main_ia, val_ff), Field(&Row::avm_main_ib, 0), Field(&Row::avm_main_ic, val_ff), - Field(&Row::avm_main_in_tag, static_cast(tag)))); + Field(&Row::avm_main_r_in_tag, static_cast(tag)), + Field(&Row::avm_main_w_in_tag, static_cast(tag)))); auto const& mem_a_row = trace.at(mem_a_idx); EXPECT_THAT(mem_a_row, AllOf(Field(&Row::avm_mem_m_tag_err, 0), - Field(&Row::avm_mem_m_in_tag, static_cast(tag)), + Field(&Row::avm_mem_r_in_tag, static_cast(tag)), Field(&Row::avm_mem_m_tag, static_cast(tag)), Field(&Row::avm_mem_m_sel_mov, 1), Field(&Row::avm_mem_m_addr, indirect ? dir_src_offset : src_offset), @@ -120,7 +121,7 @@ class AvmMemOpcodeTests : public ::testing::Test { EXPECT_THAT(mem_c_row, AllOf(Field(&Row::avm_mem_m_tag_err, 0), - Field(&Row::avm_mem_m_in_tag, static_cast(tag)), + Field(&Row::avm_mem_w_in_tag, static_cast(tag)), Field(&Row::avm_mem_m_tag, static_cast(tag)), Field(&Row::avm_mem_m_addr, indirect ? dir_dst_offset : dst_offset), Field(&Row::avm_mem_m_val, val_ff), @@ -130,7 +131,7 @@ class AvmMemOpcodeTests : public ::testing::Test { auto const& mem_ind_a_row = trace.at(mem_ind_a_idx); EXPECT_THAT(mem_ind_a_row, AllOf(Field(&Row::avm_mem_m_tag_err, 0), - Field(&Row::avm_mem_m_in_tag, static_cast(AvmMemoryTag::U32)), + Field(&Row::avm_mem_r_in_tag, static_cast(AvmMemoryTag::U32)), Field(&Row::avm_mem_m_tag, static_cast(AvmMemoryTag::U32)), Field(&Row::avm_mem_m_addr, src_offset), Field(&Row::avm_mem_m_val, dir_src_offset), @@ -139,7 +140,7 @@ class AvmMemOpcodeTests : public ::testing::Test { auto const& mem_ind_c_row = trace.at(mem_ind_c_idx); EXPECT_THAT(mem_ind_c_row, AllOf(Field(&Row::avm_mem_m_tag_err, 0), - Field(&Row::avm_mem_m_in_tag, static_cast(AvmMemoryTag::U32)), + Field(&Row::avm_mem_r_in_tag, static_cast(AvmMemoryTag::U32)), Field(&Row::avm_mem_m_tag, static_cast(AvmMemoryTag::U32)), Field(&Row::avm_mem_m_addr, dst_offset), Field(&Row::avm_mem_m_val, dir_dst_offset), @@ -191,7 +192,7 @@ TEST_F(AvmMemOpcodeTests, indirectMovInvalidAddressTag) EXPECT_THAT(trace.at(mem_ind_c_idx), AllOf(Field(&Row::avm_mem_m_tag_err, 1), Field(&Row::avm_mem_m_tag, static_cast(AvmMemoryTag::U128)), - Field(&Row::avm_mem_m_in_tag, static_cast(AvmMemoryTag::U32)), + Field(&Row::avm_mem_r_in_tag, static_cast(AvmMemoryTag::U32)), Field(&Row::avm_mem_m_ind_op_c, 1))); validate_trace_proof(std::move(trace)); @@ -230,9 +231,9 @@ TEST_F(AvmMemOpcodeNegativeTests, indMovWrongOutputValue) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "MOV_SAME_VALUE"); } -// We want to test that the output tag cannot be changed. -// In this test, we modify the m_in_tag for load operation to Ia. -// Then, we propagate the error tag and the copy of m_in_tag to the +// We want to test that the output tag for MOV cannot be altered. +// In this test, we modify the r_in_tag for load operation to Ia. +// Then, we propagate the error tag and the copy of r_in_tag to the // main trace and the memory entry related to store operation from Ic. TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagLoadIa) { @@ -243,12 +244,15 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagLoadIa) buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); computeIndices(false); - trace.at(mem_a_idx).avm_mem_m_in_tag = tag_u64; + auto trace_tmp = trace; + + trace.at(mem_a_idx).avm_mem_r_in_tag = tag_u64; trace.at(mem_a_idx).avm_mem_m_tag_err = 1; trace.at(mem_a_idx).avm_mem_m_one_min_inv = one_min_inverse_diff; trace.at(mem_c_idx).avm_mem_m_tag = tag_u64; - trace.at(mem_c_idx).avm_mem_m_in_tag = tag_u64; - trace.at(main_idx).avm_main_in_tag = tag_u64; + trace.at(mem_c_idx).avm_mem_w_in_tag = tag_u64; + trace.at(main_idx).avm_main_r_in_tag = tag_u64; + trace.at(main_idx).avm_main_w_in_tag = tag_u64; trace.at(main_idx).avm_main_tag_err = 1; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "MOV_SAME_TAG"); @@ -265,33 +269,50 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagDisabledSelector) buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); computeIndices(false); - trace.at(mem_a_idx).avm_mem_m_in_tag = tag_u64; + trace.at(mem_a_idx).avm_mem_r_in_tag = tag_u64; + trace.at(mem_a_idx).avm_mem_w_in_tag = tag_u64; trace.at(mem_a_idx).avm_mem_m_tag_err = 1; trace.at(mem_a_idx).avm_mem_m_one_min_inv = one_min_inverse_diff; trace.at(mem_a_idx).avm_mem_m_sel_mov = 0; trace.at(mem_c_idx).avm_mem_m_tag = tag_u64; - trace.at(mem_c_idx).avm_mem_m_in_tag = tag_u64; - trace.at(main_idx).avm_main_in_tag = tag_u64; + trace.at(mem_c_idx).avm_mem_r_in_tag = tag_u64; + trace.at(mem_c_idx).avm_mem_w_in_tag = tag_u64; + trace.at(main_idx).avm_main_r_in_tag = tag_u64; + trace.at(main_idx).avm_main_w_in_tag = tag_u64; trace.at(main_idx).avm_main_tag_err = 1; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "PERM_MAIN_MEM_A"); } -// The manipulation of the tag occurs in the main trace and then we -// propagate this change to the store memory operation of Ic. -TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagMainTrace) +// Same goal as above but we alter the w_in_tag in the main trace +// and propagate this to the store operation. +TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagInMainTrace) { FF const tag_u64 = FF(static_cast(AvmMemoryTag::U64)); buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); computeIndices(false); - trace.at(main_idx).avm_main_in_tag = tag_u64; + trace.at(mem_c_idx).avm_mem_m_tag = tag_u64; + trace.at(mem_c_idx).avm_mem_w_in_tag = tag_u64; + trace.at(main_idx).avm_main_w_in_tag = tag_u64; + trace.at(main_idx).avm_main_tag_err = 1; + + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "MOV_MAIN_SAME_TAG"); +} + +// The manipulation of the tag occurs in the store operation. +TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagMainTraceRead) +{ + FF const tag_u64 = FF(static_cast(AvmMemoryTag::U64)); + + buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); + computeIndices(false); trace.at(mem_c_idx).avm_mem_m_tag = tag_u64; - trace.at(mem_c_idx).avm_mem_m_in_tag = tag_u64; + trace.at(mem_c_idx).avm_mem_w_in_tag = tag_u64; - EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "PERM_MAIN_MEM_A"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "PERM_MAIN_MEM_C"); } } // namespace tests_avm diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp index 3fdea73260e..7a4fa2bc921 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp @@ -55,7 +55,7 @@ TEST_F(AvmMemoryTests, mismatchedTagAddOperation) EXPECT_TRUE(row != trace.end()); EXPECT_EQ(row->avm_mem_m_tag_err, FF(1)); // Error is raised - EXPECT_EQ(row->avm_mem_m_in_tag, FF(static_cast(AvmMemoryTag::U8))); + EXPECT_EQ(row->avm_mem_r_in_tag, FF(static_cast(AvmMemoryTag::U8))); EXPECT_EQ(row->avm_mem_m_tag, FF(static_cast(AvmMemoryTag::FF))); // Find the memory trace position corresponding to the add sub-operation of register ib. @@ -66,7 +66,7 @@ TEST_F(AvmMemoryTests, mismatchedTagAddOperation) EXPECT_TRUE(row != trace.end()); EXPECT_EQ(row->avm_mem_m_tag_err, FF(1)); // Error is raised - EXPECT_EQ(row->avm_mem_m_in_tag, FF(static_cast(AvmMemoryTag::U8))); + EXPECT_EQ(row->avm_mem_r_in_tag, FF(static_cast(AvmMemoryTag::U8))); EXPECT_EQ(row->avm_mem_m_tag, FF(static_cast(AvmMemoryTag::FF))); validate_trace_proof(std::move(trace)); @@ -98,7 +98,7 @@ TEST_F(AvmMemoryTests, mismatchedTagEqOperation) EXPECT_TRUE(row != trace.end()); EXPECT_EQ(row->avm_mem_m_tag_err, FF(0)); // Error is NOT raised - EXPECT_EQ(row->avm_mem_m_in_tag, FF(static_cast(AvmMemoryTag::U32))); + EXPECT_EQ(row->avm_mem_r_in_tag, FF(static_cast(AvmMemoryTag::U32))); EXPECT_EQ(row->avm_mem_m_tag, FF(static_cast(AvmMemoryTag::U32))); // Find the memory trace position corresponding to the load sub-operation of register ib. @@ -109,7 +109,7 @@ TEST_F(AvmMemoryTests, mismatchedTagEqOperation) EXPECT_TRUE(row != trace.end()); EXPECT_EQ(row->avm_mem_m_tag_err, FF(1)); // Error is raised - EXPECT_EQ(row->avm_mem_m_in_tag, FF(static_cast(AvmMemoryTag::U32))); + EXPECT_EQ(row->avm_mem_r_in_tag, FF(static_cast(AvmMemoryTag::U32))); EXPECT_EQ(row->avm_mem_m_tag, FF(static_cast(AvmMemoryTag::U16))); validate_trace_proof(std::move(trace)); @@ -278,4 +278,32 @@ TEST_F(AvmMemoryTests, consistentTagNoErrorViolation) EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "MEM_IN_TAG_CONSISTENCY_1"); } + +// Testing violation that a write operation must not set a VM error. +TEST_F(AvmMemoryTests, noErrorTagWriteViolation) +{ + trace_builder.calldata_copy(0, 0, 2, 0, std::vector{ 84, 7 }); + + trace_builder.op_div(0, 0, 1, 4, AvmMemoryTag::FF); + trace_builder.halt(); + auto trace = trace_builder.finalize(); + + // Find the first row enabling the division selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_div == FF(1); }); + + ASSERT_TRUE(row != trace.end()); + + auto clk = row->avm_main_clk; + + // Find the memory trace position corresponding to the div sub-operation of register ic. + row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { + return r.avm_mem_m_clk == clk && r.avm_mem_m_sub_clk == AvmMemTraceBuilder::SUB_CLK_STORE_C; + }); + + ASSERT_TRUE(row != trace.end()); + row->avm_mem_m_tag_err = FF(1); + + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "NO_TAG_ERR_WRITE"); +} + } // namespace tests_avm