diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index ba2ce3d94d7b..02b102fa470b 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -61,7 +61,7 @@ namespace avm_main(256); pol commit ib; pol commit ic; - // Memory operation per intermediate register + // Memory operation selector per intermediate register pol commit mem_op_a; pol commit mem_op_b; pol commit mem_op_c; @@ -71,6 +71,17 @@ namespace avm_main(256); pol commit rwb; pol commit rwc; + // Indirect register values + pol commit ind_a; + pol commit ind_b; + pol commit ind_c; + + // Indirect memory operation selector per indirect register + pol commit ind_op_a; + pol commit ind_op_b; + pol commit ind_op_c; + + // Memory index involved into a memory operation per pertaining intermediate register // We should range constrain it to 32 bits ultimately. For first version of the AVM, // we will assume that these columns are of the right type. @@ -103,6 +114,7 @@ namespace avm_main(256); op_err * (1 - op_err) = 0; tag_err * (1 - tag_err) = 0; // Potential optimization (boolean constraint derivation from equivalence check to avm_mem)? + // Might be removed if derived from opcode based on a lookup of constants mem_op_a * (1 - mem_op_a) = 0; mem_op_b * (1 - mem_op_b) = 0; mem_op_c * (1 - mem_op_c) = 0; @@ -111,7 +123,15 @@ namespace avm_main(256); rwb * (1 - rwb) = 0; rwc * (1 - rwc) = 0; - // TODO: Constrain rwa, rwb, rwc to u32 type and 0 <= in_tag <= 6 + // Might be removed if derived from opcode based on a lookup of constants + ind_op_a * (1 - ind_op_a) = 0; + ind_op_b * (1 - ind_op_b) = 0; + ind_op_c * (1 - ind_op_c) = 0; + + // 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 // Relation for division over the finite field // If tag_err == 1 in a division, then ib == 0 and op_err == 1. @@ -232,4 +252,19 @@ namespace avm_main(256); #[PERM_MAIN_MEM_C] mem_op_c {clk, mem_idx_c, ic, rwc, 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}; \ No newline at end of file + 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}; + + #[PERM_MAIN_MEM_IND_A] + ind_op_a {clk, ind_a, mem_idx_a} + is + avm_mem.m_ind_op_a {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val}; + + #[PERM_MAIN_MEM_IND_B] + ind_op_b {clk, ind_b, mem_idx_b} + is + avm_mem.m_ind_op_b {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val}; + + #[PERM_MAIN_MEM_IND_C] + ind_op_c {clk, ind_c, mem_idx_c} + is + avm_mem.m_ind_op_c {avm_mem.m_clk, avm_mem.m_addr, avm_mem.m_val}; \ No newline at end of file diff --git a/barretenberg/cpp/pil/avm/avm_mem.pil b/barretenberg/cpp/pil/avm/avm_mem.pil index df862019cb60..2f2af7297751 100644 --- a/barretenberg/cpp/pil/avm/avm_mem.pil +++ b/barretenberg/cpp/pil/avm/avm_mem.pil @@ -20,6 +20,11 @@ namespace avm_mem(256); pol commit m_op_b; pol commit m_op_c; + // Indicator of the indirect register pertaining to the memory operation (foreign key to avm_main.ind_op_XXX) + pol commit m_ind_op_a; + pol commit m_ind_op_b; + pol commit m_ind_op_c; + // Selector for MOV opcode (copied from main trace for loading operation on intermediated register ia) // Boolean constraint is performed in main trace. pol commit m_sel_mov; @@ -38,16 +43,21 @@ namespace avm_mem(256); m_op_a * (1 - m_op_a) = 0; m_op_b * (1 - m_op_b) = 0; m_op_c * (1 - m_op_c) = 0; + m_ind_op_a * (1 - m_ind_op_a) = 0; + m_ind_op_b * (1 - m_ind_op_b) = 0; + 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) - // sub_clk derivation - m_sub_clk = 3 * m_rw + m_op_b + 2 * m_op_c; - // Maximum one memory operation enabled per row - pol M_OP_SUM = m_op_a + m_op_b + m_op_c; - M_OP_SUM * (M_OP_SUM - 1) = 0; + pol MEM_SEL = m_op_a + m_op_b + m_op_c + m_ind_op_a + m_ind_op_b + m_ind_op_c; + MEM_SEL * (MEM_SEL - 1) = 0; + + // sub_clk derivation + pol IND_OP = m_ind_op_a + m_ind_op_b + m_ind_op_c; + m_sub_clk = MEM_SEL * (m_ind_op_b + m_op_b + 2 * (m_ind_op_c + m_op_c) + 3 * (1 - IND_OP + m_rw)); + // We need the MEM_SEL factor as the right factor is not zero when all columns are zero. // Remark: m_lastAccess == 1 on first row and therefore any relation with the // multiplicative term (1 - m_lastAccess) implicitly includes (1 - avm_main.first) @@ -117,6 +127,17 @@ namespace avm_mem(256); // 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 + //====== 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; + + // 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 // the load operation pertaining to Ia. diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp index ea107e4c0e4f..4f1a8e30c685 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/avm_flavor.hpp @@ -20,6 +20,9 @@ #include "barretenberg/relations/generated/avm/perm_main_mem_a.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_b.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_c.hpp" +#include "barretenberg/relations/generated/avm/perm_main_mem_ind_a.hpp" +#include "barretenberg/relations/generated/avm/perm_main_mem_ind_b.hpp" +#include "barretenberg/relations/generated/avm/perm_main_mem_ind_c.hpp" #include "barretenberg/transcript/transcript.hpp" namespace bb { @@ -41,19 +44,22 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 85; + static constexpr size_t NUM_WITNESS_ENTITIES = 97; 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 = 101; + static constexpr size_t NUM_ALL_ENTITIES = 113; - using Relations = std::tuple, + using Relations = std::tuple, Avm_vm::avm_mem, - Avm_vm::avm_main, + Avm_vm::avm_alu, perm_main_alu_relation, perm_main_mem_a_relation, perm_main_mem_b_relation, - perm_main_mem_c_relation>; + perm_main_mem_c_relation, + perm_main_mem_ind_a_relation, + perm_main_mem_ind_b_relation, + perm_main_mem_ind_c_relation>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -99,6 +105,9 @@ class AvmFlavor { avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, + avm_mem_m_ind_op_a, + avm_mem_m_ind_op_b, + avm_mem_m_ind_op_c, avm_mem_m_sel_mov, avm_mem_m_tag_err, avm_mem_m_one_min_inv, @@ -160,6 +169,12 @@ class AvmFlavor { avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_ind_a, + avm_main_ind_b, + avm_main_ind_c, + avm_main_ind_op_a, + avm_main_ind_op_b, + avm_main_ind_op_c, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, @@ -168,6 +183,9 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_ind_a, + perm_main_mem_ind_b, + perm_main_mem_ind_c, incl_main_tag_err, incl_mem_tag_err, incl_main_tag_err_counts, @@ -187,6 +205,9 @@ class AvmFlavor { avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, + avm_mem_m_ind_op_a, + avm_mem_m_ind_op_b, + avm_mem_m_ind_op_c, avm_mem_m_sel_mov, avm_mem_m_tag_err, avm_mem_m_one_min_inv, @@ -248,6 +269,12 @@ class AvmFlavor { avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_ind_a, + avm_main_ind_b, + avm_main_ind_c, + avm_main_ind_op_a, + avm_main_ind_op_b, + avm_main_ind_op_c, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, @@ -256,6 +283,9 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_ind_a, + perm_main_mem_ind_b, + perm_main_mem_ind_c, incl_main_tag_err, incl_mem_tag_err, incl_main_tag_err_counts, @@ -281,6 +311,9 @@ class AvmFlavor { avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, + avm_mem_m_ind_op_a, + avm_mem_m_ind_op_b, + avm_mem_m_ind_op_c, avm_mem_m_sel_mov, avm_mem_m_tag_err, avm_mem_m_one_min_inv, @@ -342,6 +375,12 @@ class AvmFlavor { avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_ind_a, + avm_main_ind_b, + avm_main_ind_c, + avm_main_ind_op_a, + avm_main_ind_op_b, + avm_main_ind_op_c, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, @@ -350,24 +389,27 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_ind_a, + perm_main_mem_ind_b, + perm_main_mem_ind_c, incl_main_tag_err, incl_mem_tag_err, incl_main_tag_err_counts, incl_mem_tag_err_counts, + avm_main_internal_return_ptr_shift, + avm_main_pc_shift, + avm_mem_m_addr_shift, + avm_mem_m_val_shift, + avm_mem_m_tag_shift, + avm_mem_m_rw_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r5_shift, avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r4_shift, - avm_mem_m_tag_shift, - avm_mem_m_addr_shift, - avm_mem_m_val_shift, - avm_mem_m_rw_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift) + avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r3_shift) RefVector get_wires() { @@ -385,6 +427,9 @@ class AvmFlavor { avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, + avm_mem_m_ind_op_a, + avm_mem_m_ind_op_b, + avm_mem_m_ind_op_c, avm_mem_m_sel_mov, avm_mem_m_tag_err, avm_mem_m_one_min_inv, @@ -446,6 +491,12 @@ class AvmFlavor { avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_ind_a, + avm_main_ind_b, + avm_main_ind_c, + avm_main_ind_op_a, + avm_main_ind_op_b, + avm_main_ind_op_c, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, @@ -454,24 +505,27 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_ind_a, + perm_main_mem_ind_b, + perm_main_mem_ind_c, incl_main_tag_err, incl_mem_tag_err, incl_main_tag_err_counts, incl_mem_tag_err_counts, + avm_main_internal_return_ptr_shift, + avm_main_pc_shift, + avm_mem_m_addr_shift, + avm_mem_m_val_shift, + avm_mem_m_tag_shift, + avm_mem_m_rw_shift, + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r5_shift, avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r7_shift, avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r1_shift, avm_alu_alu_u16_r4_shift, - avm_mem_m_tag_shift, - avm_mem_m_addr_shift, - avm_mem_m_val_shift, - avm_mem_m_rw_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift }; + avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r3_shift }; }; RefVector get_unshifted() { @@ -489,6 +543,9 @@ class AvmFlavor { avm_mem_m_op_a, avm_mem_m_op_b, avm_mem_m_op_c, + avm_mem_m_ind_op_a, + avm_mem_m_ind_op_b, + avm_mem_m_ind_op_c, avm_mem_m_sel_mov, avm_mem_m_tag_err, avm_mem_m_one_min_inv, @@ -550,6 +607,12 @@ class AvmFlavor { avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_ind_a, + avm_main_ind_b, + avm_main_ind_c, + avm_main_ind_op_a, + avm_main_ind_op_b, + avm_main_ind_op_c, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, @@ -558,6 +621,9 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_ind_a, + perm_main_mem_ind_b, + perm_main_mem_ind_c, incl_main_tag_err, incl_mem_tag_err, incl_main_tag_err_counts, @@ -565,37 +631,37 @@ class AvmFlavor { }; RefVector get_to_be_shifted() { - return { avm_alu_alu_u16_r5, - avm_alu_alu_u16_r6, - avm_alu_alu_u16_r3, - avm_alu_alu_u16_r7, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r2, - avm_alu_alu_u16_r1, - avm_alu_alu_u16_r4, - avm_mem_m_tag, + return { avm_main_internal_return_ptr, + avm_main_pc, avm_mem_m_addr, avm_mem_m_val, + avm_mem_m_tag, avm_mem_m_rw, - avm_main_internal_return_ptr, - avm_main_pc }; + avm_alu_alu_u16_r7, + avm_alu_alu_u16_r1, + avm_alu_alu_u16_r5, + avm_alu_alu_u16_r6, + avm_alu_alu_u16_r0, + avm_alu_alu_u16_r4, + avm_alu_alu_u16_r2, + avm_alu_alu_u16_r3 }; }; RefVector get_shifted() { - return { avm_alu_alu_u16_r5_shift, - avm_alu_alu_u16_r6_shift, - avm_alu_alu_u16_r3_shift, - avm_alu_alu_u16_r7_shift, - avm_alu_alu_u16_r0_shift, - avm_alu_alu_u16_r2_shift, - avm_alu_alu_u16_r1_shift, - avm_alu_alu_u16_r4_shift, - avm_mem_m_tag_shift, + return { avm_main_internal_return_ptr_shift, + avm_main_pc_shift, avm_mem_m_addr_shift, avm_mem_m_val_shift, + avm_mem_m_tag_shift, avm_mem_m_rw_shift, - avm_main_internal_return_ptr_shift, - avm_main_pc_shift }; + avm_alu_alu_u16_r7_shift, + avm_alu_alu_u16_r1_shift, + avm_alu_alu_u16_r5_shift, + avm_alu_alu_u16_r6_shift, + avm_alu_alu_u16_r0_shift, + avm_alu_alu_u16_r4_shift, + avm_alu_alu_u16_r2_shift, + avm_alu_alu_u16_r3_shift }; }; }; @@ -608,20 +674,20 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_alu_alu_u16_r5, - avm_alu_alu_u16_r6, - avm_alu_alu_u16_r3, - avm_alu_alu_u16_r7, - avm_alu_alu_u16_r0, - avm_alu_alu_u16_r2, - avm_alu_alu_u16_r1, - avm_alu_alu_u16_r4, - avm_mem_m_tag, + return { avm_main_internal_return_ptr, + avm_main_pc, avm_mem_m_addr, avm_mem_m_val, + avm_mem_m_tag, avm_mem_m_rw, - avm_main_internal_return_ptr, - avm_main_pc }; + avm_alu_alu_u16_r7, + avm_alu_alu_u16_r1, + avm_alu_alu_u16_r5, + avm_alu_alu_u16_r6, + avm_alu_alu_u16_r0, + avm_alu_alu_u16_r4, + avm_alu_alu_u16_r2, + avm_alu_alu_u16_r3 }; }; // The plookup wires that store plookup read data. @@ -712,6 +778,9 @@ class AvmFlavor { 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"; + Base::avm_mem_m_ind_op_a = "AVM_MEM_M_IND_OP_A"; + Base::avm_mem_m_ind_op_b = "AVM_MEM_M_IND_OP_B"; + Base::avm_mem_m_ind_op_c = "AVM_MEM_M_IND_OP_C"; Base::avm_mem_m_sel_mov = "AVM_MEM_M_SEL_MOV"; Base::avm_mem_m_tag_err = "AVM_MEM_M_TAG_ERR"; Base::avm_mem_m_one_min_inv = "AVM_MEM_M_ONE_MIN_INV"; @@ -773,6 +842,12 @@ class AvmFlavor { Base::avm_main_rwa = "AVM_MAIN_RWA"; Base::avm_main_rwb = "AVM_MAIN_RWB"; Base::avm_main_rwc = "AVM_MAIN_RWC"; + Base::avm_main_ind_a = "AVM_MAIN_IND_A"; + Base::avm_main_ind_b = "AVM_MAIN_IND_B"; + Base::avm_main_ind_c = "AVM_MAIN_IND_C"; + Base::avm_main_ind_op_a = "AVM_MAIN_IND_OP_A"; + Base::avm_main_ind_op_b = "AVM_MAIN_IND_OP_B"; + Base::avm_main_ind_op_c = "AVM_MAIN_IND_OP_C"; Base::avm_main_mem_idx_a = "AVM_MAIN_MEM_IDX_A"; Base::avm_main_mem_idx_b = "AVM_MAIN_MEM_IDX_B"; Base::avm_main_mem_idx_c = "AVM_MAIN_MEM_IDX_C"; @@ -781,6 +856,9 @@ class AvmFlavor { Base::perm_main_mem_a = "PERM_MAIN_MEM_A"; Base::perm_main_mem_b = "PERM_MAIN_MEM_B"; Base::perm_main_mem_c = "PERM_MAIN_MEM_C"; + Base::perm_main_mem_ind_a = "PERM_MAIN_MEM_IND_A"; + Base::perm_main_mem_ind_b = "PERM_MAIN_MEM_IND_B"; + Base::perm_main_mem_ind_c = "PERM_MAIN_MEM_IND_C"; Base::incl_main_tag_err = "INCL_MAIN_TAG_ERR"; Base::incl_mem_tag_err = "INCL_MEM_TAG_ERR"; Base::incl_main_tag_err_counts = "INCL_MAIN_TAG_ERR_COUNTS"; @@ -816,6 +894,9 @@ class AvmFlavor { Commitment avm_mem_m_op_a; Commitment avm_mem_m_op_b; Commitment avm_mem_m_op_c; + Commitment avm_mem_m_ind_op_a; + Commitment avm_mem_m_ind_op_b; + Commitment avm_mem_m_ind_op_c; Commitment avm_mem_m_sel_mov; Commitment avm_mem_m_tag_err; Commitment avm_mem_m_one_min_inv; @@ -877,6 +958,12 @@ class AvmFlavor { Commitment avm_main_rwa; Commitment avm_main_rwb; Commitment avm_main_rwc; + Commitment avm_main_ind_a; + Commitment avm_main_ind_b; + Commitment avm_main_ind_c; + Commitment avm_main_ind_op_a; + Commitment avm_main_ind_op_b; + Commitment avm_main_ind_op_c; Commitment avm_main_mem_idx_a; Commitment avm_main_mem_idx_b; Commitment avm_main_mem_idx_c; @@ -885,6 +972,9 @@ class AvmFlavor { Commitment perm_main_mem_a; Commitment perm_main_mem_b; Commitment perm_main_mem_c; + Commitment perm_main_mem_ind_a; + Commitment perm_main_mem_ind_b; + Commitment perm_main_mem_ind_c; Commitment incl_main_tag_err; Commitment incl_mem_tag_err; Commitment incl_main_tag_err_counts; @@ -920,6 +1010,9 @@ class AvmFlavor { 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); + avm_mem_m_ind_op_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_m_ind_op_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_m_ind_op_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_m_sel_mov = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_m_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_m_one_min_inv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -981,6 +1074,12 @@ class AvmFlavor { avm_main_rwa = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_rwb = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_rwc = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_ind_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_ind_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_ind_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_ind_op_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_ind_op_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_ind_op_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_mem_idx_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_mem_idx_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_mem_idx_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -989,6 +1088,9 @@ class AvmFlavor { perm_main_mem_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_mem_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + perm_main_mem_ind_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + perm_main_mem_ind_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + perm_main_mem_ind_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_main_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_mem_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_main_tag_err_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1028,6 +1130,9 @@ class AvmFlavor { 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); + serialize_to_buffer(avm_mem_m_ind_op_a, Transcript::proof_data); + serialize_to_buffer(avm_mem_m_ind_op_b, Transcript::proof_data); + serialize_to_buffer(avm_mem_m_ind_op_c, Transcript::proof_data); serialize_to_buffer(avm_mem_m_sel_mov, Transcript::proof_data); serialize_to_buffer(avm_mem_m_tag_err, Transcript::proof_data); serialize_to_buffer(avm_mem_m_one_min_inv, Transcript::proof_data); @@ -1089,6 +1194,12 @@ class AvmFlavor { serialize_to_buffer(avm_main_rwa, Transcript::proof_data); serialize_to_buffer(avm_main_rwb, Transcript::proof_data); serialize_to_buffer(avm_main_rwc, Transcript::proof_data); + serialize_to_buffer(avm_main_ind_a, Transcript::proof_data); + serialize_to_buffer(avm_main_ind_b, Transcript::proof_data); + serialize_to_buffer(avm_main_ind_c, Transcript::proof_data); + serialize_to_buffer(avm_main_ind_op_a, Transcript::proof_data); + serialize_to_buffer(avm_main_ind_op_b, Transcript::proof_data); + serialize_to_buffer(avm_main_ind_op_c, Transcript::proof_data); serialize_to_buffer(avm_main_mem_idx_a, Transcript::proof_data); serialize_to_buffer(avm_main_mem_idx_b, Transcript::proof_data); serialize_to_buffer(avm_main_mem_idx_c, Transcript::proof_data); @@ -1097,6 +1208,9 @@ class AvmFlavor { serialize_to_buffer(perm_main_mem_a, Transcript::proof_data); serialize_to_buffer(perm_main_mem_b, Transcript::proof_data); serialize_to_buffer(perm_main_mem_c, Transcript::proof_data); + serialize_to_buffer(perm_main_mem_ind_a, Transcript::proof_data); + serialize_to_buffer(perm_main_mem_ind_b, Transcript::proof_data); + serialize_to_buffer(perm_main_mem_ind_c, Transcript::proof_data); serialize_to_buffer(incl_main_tag_err, Transcript::proof_data); serialize_to_buffer(incl_mem_tag_err, Transcript::proof_data); serialize_to_buffer(incl_main_tag_err_counts, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/avm_circuit_builder.hpp index 0b9db3b8be7a..72277958eb8a 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/avm_circuit_builder.hpp @@ -21,6 +21,9 @@ #include "barretenberg/relations/generated/avm/perm_main_mem_a.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_b.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_c.hpp" +#include "barretenberg/relations/generated/avm/perm_main_mem_ind_a.hpp" +#include "barretenberg/relations/generated/avm/perm_main_mem_ind_b.hpp" +#include "barretenberg/relations/generated/avm/perm_main_mem_ind_c.hpp" namespace bb { @@ -39,6 +42,9 @@ template struct AvmFullRow { FF avm_mem_m_op_a{}; FF avm_mem_m_op_b{}; FF avm_mem_m_op_c{}; + FF avm_mem_m_ind_op_a{}; + FF avm_mem_m_ind_op_b{}; + FF avm_mem_m_ind_op_c{}; FF avm_mem_m_sel_mov{}; FF avm_mem_m_tag_err{}; FF avm_mem_m_one_min_inv{}; @@ -100,6 +106,12 @@ template struct AvmFullRow { FF avm_main_rwa{}; FF avm_main_rwb{}; FF avm_main_rwc{}; + FF avm_main_ind_a{}; + FF avm_main_ind_b{}; + FF avm_main_ind_c{}; + FF avm_main_ind_op_a{}; + FF avm_main_ind_op_b{}; + FF avm_main_ind_op_c{}; FF avm_main_mem_idx_a{}; FF avm_main_mem_idx_b{}; FF avm_main_mem_idx_c{}; @@ -108,24 +120,27 @@ template struct AvmFullRow { FF perm_main_mem_a{}; FF perm_main_mem_b{}; FF perm_main_mem_c{}; + FF perm_main_mem_ind_a{}; + FF perm_main_mem_ind_b{}; + FF perm_main_mem_ind_c{}; FF incl_main_tag_err{}; FF incl_mem_tag_err{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_pc_shift{}; + FF avm_mem_m_addr_shift{}; + FF avm_mem_m_val_shift{}; + FF avm_mem_m_tag_shift{}; + FF avm_mem_m_rw_shift{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u16_r1_shift{}; FF avm_alu_alu_u16_r5_shift{}; FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u16_r7_shift{}; FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_u16_r2_shift{}; - FF avm_alu_alu_u16_r1_shift{}; FF avm_alu_alu_u16_r4_shift{}; - FF avm_mem_m_tag_shift{}; - FF avm_mem_m_addr_shift{}; - FF avm_mem_m_val_shift{}; - FF avm_mem_m_rw_shift{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_pc_shift{}; + FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_u16_r3_shift{}; }; class AvmCircuitBuilder { @@ -138,8 +153,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 101; - static constexpr size_t num_polys = 87; + static constexpr size_t num_fixed_columns = 113; + static constexpr size_t num_polys = 99; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -169,6 +184,9 @@ class AvmCircuitBuilder { 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; + polys.avm_mem_m_ind_op_a[i] = rows[i].avm_mem_m_ind_op_a; + polys.avm_mem_m_ind_op_b[i] = rows[i].avm_mem_m_ind_op_b; + polys.avm_mem_m_ind_op_c[i] = rows[i].avm_mem_m_ind_op_c; polys.avm_mem_m_sel_mov[i] = rows[i].avm_mem_m_sel_mov; polys.avm_mem_m_tag_err[i] = rows[i].avm_mem_m_tag_err; polys.avm_mem_m_one_min_inv[i] = rows[i].avm_mem_m_one_min_inv; @@ -230,6 +248,12 @@ class AvmCircuitBuilder { polys.avm_main_rwa[i] = rows[i].avm_main_rwa; polys.avm_main_rwb[i] = rows[i].avm_main_rwb; polys.avm_main_rwc[i] = rows[i].avm_main_rwc; + polys.avm_main_ind_a[i] = rows[i].avm_main_ind_a; + polys.avm_main_ind_b[i] = rows[i].avm_main_ind_b; + polys.avm_main_ind_c[i] = rows[i].avm_main_ind_c; + polys.avm_main_ind_op_a[i] = rows[i].avm_main_ind_op_a; + polys.avm_main_ind_op_b[i] = rows[i].avm_main_ind_op_b; + polys.avm_main_ind_op_c[i] = rows[i].avm_main_ind_op_c; polys.avm_main_mem_idx_a[i] = rows[i].avm_main_mem_idx_a; polys.avm_main_mem_idx_b[i] = rows[i].avm_main_mem_idx_b; polys.avm_main_mem_idx_c[i] = rows[i].avm_main_mem_idx_c; @@ -238,26 +262,29 @@ class AvmCircuitBuilder { polys.perm_main_mem_a[i] = rows[i].perm_main_mem_a; polys.perm_main_mem_b[i] = rows[i].perm_main_mem_b; polys.perm_main_mem_c[i] = rows[i].perm_main_mem_c; + polys.perm_main_mem_ind_a[i] = rows[i].perm_main_mem_ind_a; + polys.perm_main_mem_ind_b[i] = rows[i].perm_main_mem_ind_b; + polys.perm_main_mem_ind_c[i] = rows[i].perm_main_mem_ind_c; polys.incl_main_tag_err[i] = rows[i].incl_main_tag_err; polys.incl_mem_tag_err[i] = rows[i].incl_mem_tag_err; polys.incl_main_tag_err_counts[i] = rows[i].incl_main_tag_err_counts; polys.incl_mem_tag_err_counts[i] = rows[i].incl_mem_tag_err_counts; } + 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_addr_shift = Polynomial(polys.avm_mem_m_addr.shifted()); + polys.avm_mem_m_val_shift = Polynomial(polys.avm_mem_m_val.shifted()); + polys.avm_mem_m_tag_shift = Polynomial(polys.avm_mem_m_tag.shifted()); + polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.shifted()); + polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); + polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.shifted()); polys.avm_alu_alu_u16_r5_shift = Polynomial(polys.avm_alu_alu_u16_r5.shifted()); polys.avm_alu_alu_u16_r6_shift = Polynomial(polys.avm_alu_alu_u16_r6.shifted()); - polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); - polys.avm_alu_alu_u16_r7_shift = Polynomial(polys.avm_alu_alu_u16_r7.shifted()); polys.avm_alu_alu_u16_r0_shift = Polynomial(polys.avm_alu_alu_u16_r0.shifted()); - polys.avm_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); - polys.avm_alu_alu_u16_r1_shift = Polynomial(polys.avm_alu_alu_u16_r1.shifted()); polys.avm_alu_alu_u16_r4_shift = Polynomial(polys.avm_alu_alu_u16_r4.shifted()); - polys.avm_mem_m_tag_shift = Polynomial(polys.avm_mem_m_tag.shifted()); - polys.avm_mem_m_addr_shift = Polynomial(polys.avm_mem_m_addr.shifted()); - polys.avm_mem_m_val_shift = Polynomial(polys.avm_mem_m_val.shifted()); - polys.avm_mem_m_rw_shift = Polynomial(polys.avm_mem_m_rw.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_alu_alu_u16_r2_shift = Polynomial(polys.avm_alu_alu_u16_r2.shifted()); + polys.avm_alu_alu_u16_r3_shift = Polynomial(polys.avm_alu_alu_u16_r3.shifted()); return polys; } @@ -329,16 +356,16 @@ class AvmCircuitBuilder { return true; }; - if (!evaluate_relation.template operator()>("avm_alu", - Avm_vm::get_relation_label_avm_alu)) { + 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)) { return false; } - if (!evaluate_relation.template operator()>("avm_main", - Avm_vm::get_relation_label_avm_main)) { + if (!evaluate_relation.template operator()>("avm_alu", + Avm_vm::get_relation_label_avm_alu)) { return false; } @@ -354,6 +381,15 @@ class AvmCircuitBuilder { if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_C")) { return false; } + if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_IND_A")) { + return false; + } + if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_IND_B")) { + return false; + } + if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_IND_C")) { + return false; + } if (!evaluate_logderivative.template operator()>("INCL_MAIN_TAG_ERR")) { return false; } 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 98388dfb3116..fc1970fc8fc0 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,75 +7,75 @@ namespace bb::Avm_vm { template struct Avm_aluRow { - FF avm_alu_alu_op_add{}; - FF avm_alu_alu_u16_r5{}; - FF avm_alu_alu_u16_r2{}; - FF avm_alu_alu_cf{}; + FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_u8_tag{}; + FF avm_alu_alu_u128_tag{}; + FF avm_alu_alu_ib{}; + FF avm_alu_alu_u16_r4{}; + FF avm_alu_alu_u16_r0{}; + FF avm_alu_alu_u16_r1_shift{}; FF avm_alu_alu_op_mul{}; + FF avm_alu_alu_u16_tag{}; + FF avm_alu_alu_u16_r2{}; + FF avm_alu_alu_u16_r1{}; + FF avm_alu_alu_u16_r3{}; + FF avm_alu_alu_in_tag{}; FF avm_alu_alu_u8_r1{}; - FF avm_alu_alu_op_not{}; - FF avm_alu_alu_op_sub{}; - FF avm_alu_alu_u16_r5_shift{}; - FF avm_alu_alu_u16_r6{}; FF avm_alu_alu_u16_r7{}; - FF avm_alu_alu_u64_r0{}; + FF avm_alu_alu_u16_r6{}; + FF avm_alu_alu_op_eq{}; + FF avm_alu_alu_u64_tag{}; FF avm_alu_alu_ia{}; - FF avm_alu_alu_u16_r6_shift{}; - FF avm_alu_alu_in_tag{}; - FF avm_alu_alu_sel{}; - FF avm_alu_alu_u16_r3_shift{}; - FF avm_alu_alu_u16_r7_shift{}; + FF avm_alu_alu_ic{}; + FF avm_alu_alu_u16_r5_shift{}; FF avm_alu_alu_op_eq_diff_inv{}; - FF avm_alu_alu_u64_tag{}; - FF avm_alu_alu_u16_r0_shift{}; - FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_op_add{}; + FF avm_alu_alu_ff_tag{}; + FF avm_alu_alu_u16_r5{}; FF avm_alu_alu_u32_tag{}; - FF avm_alu_alu_u16_r1_shift{}; - FF avm_alu_alu_op_eq{}; - FF avm_alu_alu_u16_r1{}; + FF avm_alu_alu_u16_r6_shift{}; + FF avm_alu_alu_op_sub{}; + FF avm_alu_alu_u16_r0_shift{}; FF avm_alu_alu_u16_r4_shift{}; - FF avm_alu_alu_ff_tag{}; - FF avm_alu_alu_u16_r0{}; - FF avm_alu_alu_ib{}; - FF avm_alu_alu_u16_tag{}; - FF avm_alu_alu_u16_r3{}; - FF avm_alu_alu_u128_tag{}; FF avm_alu_alu_u8_r0{}; - FF avm_alu_alu_ic{}; - FF avm_alu_alu_u8_tag{}; - FF avm_alu_alu_u16_r4{}; + FF avm_alu_alu_op_not{}; + FF avm_alu_alu_u16_r2_shift{}; + FF avm_alu_alu_u16_r3_shift{}; + FF avm_alu_alu_u64_r0{}; + FF avm_alu_alu_sel{}; + FF avm_alu_alu_cf{}; }; inline std::string get_relation_label_avm_alu(int index) { switch (index) { - case 18: - return "ALU_OP_NOT"; + case 19: + return "ALU_RES_IS_BOOL"; - case 16: - return "ALU_MULTIPLICATION_OUT_U128"; + case 20: + return "ALU_OP_EQ"; + + case 13: + return "ALU_MUL_COMMON_2"; + + case 11: + return "ALU_MULTIPLICATION_FF"; case 10: return "ALU_ADD_SUB_2"; - case 9: - return "ALU_ADD_SUB_1"; + case 16: + return "ALU_MULTIPLICATION_OUT_U128"; - case 11: - return "ALU_MULTIPLICATION_FF"; + case 18: + return "ALU_OP_NOT"; - case 13: - return "ALU_MUL_COMMON_2"; + case 9: + return "ALU_ADD_SUB_1"; case 17: return "ALU_FF_NOT_XOR"; - case 20: - return "ALU_OP_EQ"; - - case 19: - return "ALU_RES_IS_BOOL"; - case 12: return "ALU_MUL_COMMON_1"; } 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 fd48e15c47c6..713d12a89646 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -7,68 +7,71 @@ namespace bb::Avm_vm { template struct Avm_mainRow { - FF avm_main_tag_err{}; - FF avm_main_rwb{}; - FF avm_main_mem_op_b{}; - FF avm_main_ic{}; - FF avm_main_sel_internal_return{}; - FF avm_main_internal_return_ptr{}; - FF avm_main_alu_sel{}; - FF avm_main_sel_halt{}; - FF avm_main_internal_return_ptr_shift{}; - FF avm_main_mem_idx_a{}; + FF avm_main_ind_op_b{}; FF avm_main_mem_idx_b{}; - FF avm_main_rwa{}; - FF avm_main_mem_op_a{}; - FF avm_main_sel_mov{}; - FF avm_main_mem_op_c{}; + FF avm_main_mem_idx_a{}; + FF avm_main_internal_return_ptr{}; FF avm_main_sel_op_not{}; - FF avm_main_sel_internal_call{}; - FF avm_main_pc_shift{}; - FF avm_main_inv{}; - FF avm_main_sel_op_add{}; - FF avm_main_rwc{}; - FF avm_main_sel_op_eq{}; - FF avm_main_ia{}; FF avm_main_sel_op_mul{}; - FF avm_main_op_err{}; + FF avm_main_sel_op_add{}; + FF avm_main_sel_internal_call{}; + FF avm_main_mem_op_c{}; + FF avm_main_internal_return_ptr_shift{}; + FF avm_main_mem_op_b{}; + FF avm_main_sel_halt{}; FF avm_main_first{}; + FF avm_main_rwa{}; + FF avm_main_ia{}; FF avm_main_ib{}; + FF avm_main_sel_jump{}; FF avm_main_sel_op_sub{}; - FF avm_main_sel_op_div{}; + FF avm_main_alu_sel{}; + FF avm_main_inv{}; + FF avm_main_pc_shift{}; + FF avm_main_ic{}; + FF avm_main_sel_internal_return{}; + FF avm_main_ind_op_c{}; + FF avm_main_tag_err{}; + FF avm_main_op_err{}; + FF avm_main_ind_op_a{}; FF avm_main_pc{}; - FF avm_main_sel_jump{}; + FF avm_main_sel_mov{}; + FF avm_main_rwb{}; + FF avm_main_mem_op_a{}; + FF avm_main_rwc{}; + FF avm_main_sel_op_eq{}; + FF avm_main_sel_op_div{}; }; inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 21: - return "SUBOP_DIVISION_ZERO_ERR2"; + case 27: + return "RETURN_POINTER_INCREMENT"; - case 19: - return "SUBOP_DIVISION_FF"; + case 23: + return "SUBOP_DIVISION_ZERO_ERR1"; - case 35: + case 38: return "PC_INCREMENT"; - case 20: - return "SUBOP_DIVISION_ZERO_ERR1"; + case 24: + return "SUBOP_DIVISION_ZERO_ERR2"; - case 30: - return "RETURN_POINTER_DECREMENT"; + case 40: + return "MOV_SAME_VALUE"; - case 36: - return "INTERNAL_RETURN_POINTER_CONSISTENCY"; + case 33: + return "RETURN_POINTER_DECREMENT"; case 22: - return "SUBOP_ERROR_RELEVANT_OP"; + return "SUBOP_DIVISION_FF"; - case 37: - return "MOV_SAME_VALUE"; + case 39: + return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 24: - return "RETURN_POINTER_INCREMENT"; + case 25: + return "SUBOP_ERROR_RELEVANT_OP"; } return std::to_string(index); } @@ -77,9 +80,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, 5, - 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, + 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, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, }; template @@ -245,8 +248,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(19); - 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_ind_op_a * (-avm_main_ind_op_a + FF(1))); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -254,7 +256,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); + auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -262,7 +264,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); + auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -270,7 +272,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); + 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<22>(evals) += tmp; } @@ -278,7 +281,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -286,8 +289,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(24); - 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_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -295,7 +297,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); + auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -303,7 +305,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -311,7 +313,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); + 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<27>(evals) += tmp; } @@ -319,7 +322,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(28); - auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); + auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -327,7 +330,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(29); - auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); + auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -335,8 +338,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(30); - 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_pc + FF(1)) - avm_main_ib)); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -344,7 +346,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(31); - 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_call * (avm_main_rwb - FF(1))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -352,7 +354,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(32); - auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -360,7 +362,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(33); - auto tmp = (avm_main_sel_internal_return * avm_main_rwa); + 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<33>(evals) += tmp; } @@ -368,7 +371,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(34); - auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -376,43 +379,67 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(35); + auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); + tmp *= scaling_factor; + std::get<35>(evals) += tmp; + } + // Contribution 36 + { + Avm_DECLARE_VIEWS(36); + + auto tmp = (avm_main_sel_internal_return * avm_main_rwa); + tmp *= scaling_factor; + std::get<36>(evals) += tmp; + } + // Contribution 37 + { + Avm_DECLARE_VIEWS(37); + + auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + tmp *= scaling_factor; + std::get<37>(evals) += tmp; + } + // Contribution 38 + { + Avm_DECLARE_VIEWS(38); + 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) + avm_main_sel_op_not) + avm_main_sel_op_eq)) * (avm_main_pc_shift - (avm_main_pc + FF(1)))); tmp *= scaling_factor; - std::get<35>(evals) += tmp; + std::get<38>(evals) += tmp; } - // Contribution 36 + // Contribution 39 { - Avm_DECLARE_VIEWS(36); + Avm_DECLARE_VIEWS(39); 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<36>(evals) += tmp; + std::get<39>(evals) += tmp; } - // Contribution 37 + // Contribution 40 { - Avm_DECLARE_VIEWS(37); + Avm_DECLARE_VIEWS(40); auto tmp = (avm_main_sel_mov * (avm_main_ia - avm_main_ic)); tmp *= scaling_factor; - std::get<37>(evals) += tmp; + std::get<40>(evals) += tmp; } - // Contribution 38 + // Contribution 41 { - Avm_DECLARE_VIEWS(38); + Avm_DECLARE_VIEWS(41); 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<38>(evals) += tmp; + std::get<41>(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 caacb2ec45d0..7863ebbbc7b5 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -7,49 +7,52 @@ namespace bb::Avm_vm { template struct Avm_memRow { - FF avm_mem_m_op_a{}; - FF avm_mem_m_tag_err{}; - FF avm_mem_m_last{}; - FF avm_mem_m_addr{}; - FF avm_mem_m_val{}; - FF avm_mem_m_in_tag{}; - FF avm_mem_m_tag_shift{}; - FF avm_mem_m_sub_clk{}; - FF avm_mem_m_addr_shift{}; + FF avm_mem_m_one_min_inv{}; FF avm_mem_m_sel_mov{}; - FF avm_mem_m_rw{}; + FF avm_mem_m_ind_op_c{}; + FF avm_mem_m_ind_op_b{}; FF avm_mem_m_op_b{}; - FF avm_mem_m_val_shift{}; - FF avm_mem_m_tag{}; + FF avm_mem_m_sub_clk{}; + FF avm_mem_m_addr{}; FF avm_mem_m_op_c{}; + FF avm_mem_m_last{}; + FF avm_mem_m_addr_shift{}; + FF avm_mem_m_val_shift{}; + FF avm_mem_m_op_a{}; + FF avm_mem_m_tag_shift{}; FF avm_mem_m_rw_shift{}; - FF avm_mem_m_one_min_inv{}; + FF avm_mem_m_ind_op_a{}; + FF avm_mem_m_tag_err{}; + FF avm_mem_m_val{}; FF avm_mem_m_lastAccess{}; + FF avm_mem_m_tag{}; + FF avm_mem_m_rw{}; + FF avm_mem_m_in_tag{}; }; inline std::string get_relation_label_avm_mem(int index) { switch (index) { - case 10: - return "MEM_READ_WRITE_VAL_CONSISTENCY"; - - case 11: - return "MEM_READ_WRITE_TAG_CONSISTENCY"; - - case 9: + case 12: return "MEM_LAST_ACCESS_DELIMITER"; - case 13: + case 16: return "MEM_IN_TAG_CONSISTENCY_1"; - case 12: + case 17: + return "MEM_IN_TAG_CONSISTENCY_2"; + + case 24: + return "MOV_SAME_TAG"; + + case 15: return "MEM_ZERO_INIT"; case 14: - return "MEM_IN_TAG_CONSISTENCY_2"; + return "MEM_READ_WRITE_TAG_CONSISTENCY"; - case 15: - return "MOV_SAME_TAG"; + case 13: + return "MEM_READ_WRITE_VAL_CONSISTENCY"; } return std::to_string(index); } @@ -58,8 +61,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, 4, 4, 4, 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, 3, 3, 3, 3, 3, 3, 3, 3, 3, }; template @@ -129,7 +132,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(7); - auto tmp = (avm_mem_m_sub_clk - (((avm_mem_m_rw * FF(3)) + avm_mem_m_op_b) + (avm_mem_m_op_c * FF(2)))); + auto tmp = (avm_mem_m_ind_op_a * (-avm_mem_m_ind_op_a + FF(1))); tmp *= scaling_factor; std::get<7>(evals) += tmp; } @@ -137,8 +140,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(8); - auto tmp = (((avm_mem_m_op_a + avm_mem_m_op_b) + avm_mem_m_op_c) * - (((avm_mem_m_op_a + avm_mem_m_op_b) + avm_mem_m_op_c) - FF(1))); + auto tmp = (avm_mem_m_ind_op_b * (-avm_mem_m_ind_op_b + FF(1))); tmp *= scaling_factor; std::get<8>(evals) += tmp; } @@ -146,7 +148,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(9); - auto tmp = ((-avm_mem_m_lastAccess + FF(1)) * (avm_mem_m_addr_shift - avm_mem_m_addr)); + auto tmp = (avm_mem_m_ind_op_c * (-avm_mem_m_ind_op_c + FF(1))); tmp *= scaling_factor; std::get<9>(evals) += tmp; } @@ -154,8 +156,12 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(10); - auto tmp = (((-avm_mem_m_lastAccess + FF(1)) * (-avm_mem_m_rw_shift + FF(1))) * - (avm_mem_m_val_shift - avm_mem_m_val)); + auto tmp = + ((((((avm_mem_m_op_a + avm_mem_m_op_b) + avm_mem_m_op_c) + avm_mem_m_ind_op_a) + avm_mem_m_ind_op_b) + + avm_mem_m_ind_op_c) * + ((((((avm_mem_m_op_a + avm_mem_m_op_b) + avm_mem_m_op_c) + avm_mem_m_ind_op_a) + avm_mem_m_ind_op_b) + + avm_mem_m_ind_op_c) - + FF(1))); tmp *= scaling_factor; std::get<10>(evals) += tmp; } @@ -163,8 +169,13 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(11); - auto tmp = (((-avm_mem_m_lastAccess + FF(1)) * (-avm_mem_m_rw_shift + FF(1))) * - (avm_mem_m_tag_shift - avm_mem_m_tag)); + auto tmp = + (avm_mem_m_sub_clk - + ((((((avm_mem_m_op_a + avm_mem_m_op_b) + avm_mem_m_op_c) + avm_mem_m_ind_op_a) + avm_mem_m_ind_op_b) + + avm_mem_m_ind_op_c) * + (((avm_mem_m_ind_op_b + avm_mem_m_op_b) + ((avm_mem_m_ind_op_c + avm_mem_m_op_c) * FF(2))) + + (((-((avm_mem_m_ind_op_a + avm_mem_m_ind_op_b) + avm_mem_m_ind_op_c) + FF(1)) + avm_mem_m_rw) * + FF(3))))); tmp *= scaling_factor; std::get<11>(evals) += tmp; } @@ -172,7 +183,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(12); - auto tmp = ((avm_mem_m_lastAccess * (-avm_mem_m_rw_shift + FF(1))) * avm_mem_m_val_shift); + auto tmp = ((-avm_mem_m_lastAccess + FF(1)) * (avm_mem_m_addr_shift - avm_mem_m_addr)); tmp *= scaling_factor; std::get<12>(evals) += tmp; } @@ -180,7 +191,8 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(13); - 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_lastAccess + FF(1)) * (-avm_mem_m_rw_shift + FF(1))) * + (avm_mem_m_val_shift - avm_mem_m_val)); tmp *= scaling_factor; std::get<13>(evals) += tmp; } @@ -188,7 +200,8 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(14); - auto tmp = ((-avm_mem_m_tag_err + FF(1)) * avm_mem_m_one_min_inv); + auto tmp = (((-avm_mem_m_lastAccess + FF(1)) * (-avm_mem_m_rw_shift + FF(1))) * + (avm_mem_m_tag_shift - avm_mem_m_tag)); tmp *= scaling_factor; std::get<14>(evals) += tmp; } @@ -196,10 +209,82 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(15); - auto tmp = (avm_mem_m_sel_mov * avm_mem_m_tag_err); + auto tmp = ((avm_mem_m_lastAccess * (-avm_mem_m_rw_shift + FF(1))) * avm_mem_m_val_shift); tmp *= scaling_factor; std::get<15>(evals) += tmp; } + // Contribution 16 + { + 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); + tmp *= scaling_factor; + std::get<16>(evals) += tmp; + } + // Contribution 17 + { + Avm_DECLARE_VIEWS(17); + + auto tmp = ((-avm_mem_m_tag_err + FF(1)) * avm_mem_m_one_min_inv); + tmp *= scaling_factor; + std::get<17>(evals) += tmp; + } + // Contribution 18 + { + Avm_DECLARE_VIEWS(18); + + auto tmp = (avm_mem_m_ind_op_a * (avm_mem_m_in_tag - FF(3))); + tmp *= scaling_factor; + std::get<18>(evals) += tmp; + } + // Contribution 19 + { + Avm_DECLARE_VIEWS(19); + + auto tmp = (avm_mem_m_ind_op_b * (avm_mem_m_in_tag - FF(3))); + tmp *= scaling_factor; + std::get<19>(evals) += tmp; + } + // Contribution 20 + { + Avm_DECLARE_VIEWS(20); + + auto tmp = (avm_mem_m_ind_op_c * (avm_mem_m_in_tag - FF(3))); + tmp *= scaling_factor; + std::get<20>(evals) += tmp; + } + // Contribution 21 + { + Avm_DECLARE_VIEWS(21); + + auto tmp = (avm_mem_m_ind_op_a * avm_mem_m_rw); + tmp *= scaling_factor; + std::get<21>(evals) += tmp; + } + // Contribution 22 + { + Avm_DECLARE_VIEWS(22); + + auto tmp = (avm_mem_m_ind_op_b * avm_mem_m_rw); + tmp *= scaling_factor; + std::get<22>(evals) += tmp; + } + // Contribution 23 + { + Avm_DECLARE_VIEWS(23); + + auto tmp = (avm_mem_m_ind_op_c * avm_mem_m_rw); + tmp *= scaling_factor; + std::get<23>(evals) += tmp; + } + // Contribution 24 + { + Avm_DECLARE_VIEWS(24); + + auto tmp = (avm_mem_m_sel_mov * avm_mem_m_tag_err); + tmp *= scaling_factor; + std::get<24>(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 9d9ee4459e58..3b840e95441d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -16,6 +16,9 @@ [[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); \ + [[maybe_unused]] auto avm_mem_m_ind_op_a = View(new_term.avm_mem_m_ind_op_a); \ + [[maybe_unused]] auto avm_mem_m_ind_op_b = View(new_term.avm_mem_m_ind_op_b); \ + [[maybe_unused]] auto avm_mem_m_ind_op_c = View(new_term.avm_mem_m_ind_op_c); \ [[maybe_unused]] auto avm_mem_m_sel_mov = View(new_term.avm_mem_m_sel_mov); \ [[maybe_unused]] auto avm_mem_m_tag_err = View(new_term.avm_mem_m_tag_err); \ [[maybe_unused]] auto avm_mem_m_one_min_inv = View(new_term.avm_mem_m_one_min_inv); \ @@ -77,6 +80,12 @@ [[maybe_unused]] auto avm_main_rwa = View(new_term.avm_main_rwa); \ [[maybe_unused]] auto avm_main_rwb = View(new_term.avm_main_rwb); \ [[maybe_unused]] auto avm_main_rwc = View(new_term.avm_main_rwc); \ + [[maybe_unused]] auto avm_main_ind_a = View(new_term.avm_main_ind_a); \ + [[maybe_unused]] auto avm_main_ind_b = View(new_term.avm_main_ind_b); \ + [[maybe_unused]] auto avm_main_ind_c = View(new_term.avm_main_ind_c); \ + [[maybe_unused]] auto avm_main_ind_op_a = View(new_term.avm_main_ind_op_a); \ + [[maybe_unused]] auto avm_main_ind_op_b = View(new_term.avm_main_ind_op_b); \ + [[maybe_unused]] auto avm_main_ind_op_c = View(new_term.avm_main_ind_op_c); \ [[maybe_unused]] auto avm_main_mem_idx_a = View(new_term.avm_main_mem_idx_a); \ [[maybe_unused]] auto avm_main_mem_idx_b = View(new_term.avm_main_mem_idx_b); \ [[maybe_unused]] auto avm_main_mem_idx_c = View(new_term.avm_main_mem_idx_c); \ @@ -85,21 +94,24 @@ [[maybe_unused]] auto perm_main_mem_a = View(new_term.perm_main_mem_a); \ [[maybe_unused]] auto perm_main_mem_b = View(new_term.perm_main_mem_b); \ [[maybe_unused]] auto perm_main_mem_c = View(new_term.perm_main_mem_c); \ + [[maybe_unused]] auto perm_main_mem_ind_a = View(new_term.perm_main_mem_ind_a); \ + [[maybe_unused]] auto perm_main_mem_ind_b = View(new_term.perm_main_mem_ind_b); \ + [[maybe_unused]] auto perm_main_mem_ind_c = View(new_term.perm_main_mem_ind_c); \ [[maybe_unused]] auto incl_main_tag_err = View(new_term.incl_main_tag_err); \ [[maybe_unused]] auto incl_mem_tag_err = View(new_term.incl_mem_tag_err); \ [[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_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_addr_shift = View(new_term.avm_mem_m_addr_shift); \ + [[maybe_unused]] auto avm_mem_m_val_shift = View(new_term.avm_mem_m_val_shift); \ + [[maybe_unused]] auto avm_mem_m_tag_shift = View(new_term.avm_mem_m_tag_shift); \ + [[maybe_unused]] auto avm_mem_m_rw_shift = View(new_term.avm_mem_m_rw_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_r1_shift = View(new_term.avm_alu_alu_u16_r1_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r5_shift = View(new_term.avm_alu_alu_u16_r5_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_r3_shift = View(new_term.avm_alu_alu_u16_r3_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_r0_shift = View(new_term.avm_alu_alu_u16_r0_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_r1_shift = View(new_term.avm_alu_alu_u16_r1_shift); \ [[maybe_unused]] auto avm_alu_alu_u16_r4_shift = View(new_term.avm_alu_alu_u16_r4_shift); \ - [[maybe_unused]] auto avm_mem_m_tag_shift = View(new_term.avm_mem_m_tag_shift); \ - [[maybe_unused]] auto avm_mem_m_addr_shift = View(new_term.avm_mem_m_addr_shift); \ - [[maybe_unused]] auto avm_mem_m_val_shift = View(new_term.avm_mem_m_val_shift); \ - [[maybe_unused]] auto avm_mem_m_rw_shift = View(new_term.avm_mem_m_rw_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_alu_alu_u16_r2_shift = View(new_term.avm_alu_alu_u16_r2_shift); \ + [[maybe_unused]] auto avm_alu_alu_u16_r3_shift = View(new_term.avm_alu_alu_u16_r3_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_a.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_a.hpp new file mode 100644 index 000000000000..71f8af97195a --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_a.hpp @@ -0,0 +1,98 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class perm_main_mem_ind_a_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 3; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the + * value needs to be set to zero. + * + * @details If this is true then permutation takes place in this row + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.avm_main_ind_op_a == 1 || in.avm_mem_m_ind_op_a == 1); + } + + /** + * @brief Get all the entities for the permutation when we don't need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_mem_ind_a, + in.avm_main_ind_op_a, + in.avm_main_ind_op_a, + in.avm_mem_m_ind_op_a, + in.avm_main_clk, + in.avm_main_ind_a, + in.avm_main_mem_idx_a, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val); + } + + /** + * @brief Get all the entities for the permutation when need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_mem_ind_a, + in.avm_main_ind_op_a, + in.avm_main_ind_op_a, + in.avm_mem_m_ind_op_a, + in.avm_main_clk, + in.avm_main_ind_a, + in.avm_main_mem_idx_a, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val); + } +}; + +template +using perm_main_mem_ind_a_relation = GenericPermutationRelation; +template using perm_main_mem_ind_a = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_b.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_b.hpp new file mode 100644 index 000000000000..755defdf4b94 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_b.hpp @@ -0,0 +1,98 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class perm_main_mem_ind_b_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 3; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the + * value needs to be set to zero. + * + * @details If this is true then permutation takes place in this row + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.avm_main_ind_op_b == 1 || in.avm_mem_m_ind_op_b == 1); + } + + /** + * @brief Get all the entities for the permutation when we don't need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_mem_ind_b, + in.avm_main_ind_op_b, + in.avm_main_ind_op_b, + in.avm_mem_m_ind_op_b, + in.avm_main_clk, + in.avm_main_ind_b, + in.avm_main_mem_idx_b, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val); + } + + /** + * @brief Get all the entities for the permutation when need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_mem_ind_b, + in.avm_main_ind_op_b, + in.avm_main_ind_op_b, + in.avm_mem_m_ind_op_b, + in.avm_main_clk, + in.avm_main_ind_b, + in.avm_main_mem_idx_b, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val); + } +}; + +template +using perm_main_mem_ind_b_relation = GenericPermutationRelation; +template using perm_main_mem_ind_b = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_c.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_c.hpp new file mode 100644 index 000000000000..73f9fe5638ad --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_c.hpp @@ -0,0 +1,98 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class perm_main_mem_ind_c_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 3; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the + * value needs to be set to zero. + * + * @details If this is true then permutation takes place in this row + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.avm_main_ind_op_c == 1 || in.avm_mem_m_ind_op_c == 1); + } + + /** + * @brief Get all the entities for the permutation when we don't need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_mem_ind_c, + in.avm_main_ind_op_c, + in.avm_main_ind_op_c, + in.avm_mem_m_ind_op_c, + in.avm_main_clk, + in.avm_main_ind_c, + in.avm_main_mem_idx_c, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val); + } + + /** + * @brief Get all the entities for the permutation when need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_mem_ind_c, + in.avm_main_ind_op_c, + in.avm_main_ind_op_c, + in.avm_mem_m_ind_op_c, + in.avm_main_clk, + in.avm_main_ind_c, + in.avm_main_mem_idx_c, + in.avm_mem_m_clk, + in.avm_mem_m_addr, + in.avm_mem_m_val); + } +}; + +template +using perm_main_mem_ind_c_relation = GenericPermutationRelation; +template using perm_main_mem_ind_c = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp index b163d40c6e0c..51c35cfa290d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp @@ -13,6 +13,7 @@ using Row = bb::AvmFullRow; // Number of rows static const size_t AVM_TRACE_SIZE = 256; enum class IntermRegister : uint32_t { IA = 0, IB = 1, IC = 2 }; +enum class IndirectRegister : uint32_t { IND_A = 0, IND_B = 1, IND_C = 2 }; // Keep following enum in sync with MAX_NEM_TAG below enum class AvmMemoryTag : uint32_t { U0 = 0, U8 = 1, U16 = 2, U32 = 3, U64 = 4, U128 = 5, FF = 6 }; 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 96ac76fc5e52..a27536a08f82 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -179,7 +179,9 @@ std::vector Execution::gen_trace(std::vector const& instructio break; } case OpCode::MOV: - trace_builder.op_mov(std::get(inst.operands.at(1)), std::get(inst.operands.at(2))); + trace_builder.op_mov(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2))); break; // Control Flow - Contract Calls case OpCode::RETURN: 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 22de65efaef2..eeb56e30c76e 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 @@ -1,5 +1,7 @@ #include "avm_mem_trace.hpp" #include "barretenberg/vm/avm_trace/avm_common.hpp" +#include "barretenberg/vm/avm_trace/avm_trace.hpp" +#include namespace bb::avm_trace { @@ -108,11 +110,10 @@ void AvmMemTraceBuilder::load_mismatch_tag_in_mem_trace(uint32_t const m_clk, } /** - * @brief Add a memory trace entry corresponding to a memory load into the intermediate - * passed register. + * @brief Add a memory trace entry corresponding to a memory load. * * @param clk The main clock - * @param interm_reg The intermediate register + * @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 @@ -120,22 +121,9 @@ void AvmMemTraceBuilder::load_mismatch_tag_in_mem_trace(uint32_t const m_clk, * @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_in_mem_trace( - uint32_t clk, IntermRegister interm_reg, uint32_t addr, FF const& val, AvmMemoryTag m_in_tag) +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 sub_clk = 0; - switch (interm_reg) { - case IntermRegister::IA: - sub_clk = SUB_CLK_LOAD_A; - break; - case IntermRegister::IB: - sub_clk = SUB_CLK_LOAD_B; - break; - case IntermRegister::IC: - sub_clk = SUB_CLK_LOAD_C; - break; - } - 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); @@ -225,8 +213,47 @@ AvmMemTraceBuilder::MemRead AvmMemTraceBuilder::read_and_load_from_memory(uint32 uint32_t const addr, AvmMemoryTag const m_in_tag) { + uint32_t sub_clk = 0; + switch (interm_reg) { + case IntermRegister::IA: + sub_clk = SUB_CLK_LOAD_A; + break; + case IntermRegister::IB: + sub_clk = SUB_CLK_LOAD_B; + break; + case IntermRegister::IC: + sub_clk = SUB_CLK_LOAD_C; + break; + } + + FF val = memory.at(addr); + bool tagMatch = load_from_mem_trace(clk, sub_clk, addr, val, m_in_tag); + + return MemRead{ + .tag_match = tagMatch, + .val = val, + }; +} + +AvmMemTraceBuilder::MemRead AvmMemTraceBuilder::indirect_read_and_load_from_memory(uint32_t clk, + IndirectRegister ind_reg, + uint32_t addr) +{ + uint32_t sub_clk = 0; + switch (ind_reg) { + case IndirectRegister::IND_A: + sub_clk = SUB_CLK_IND_LOAD_A; + break; + case IndirectRegister::IND_B: + sub_clk = SUB_CLK_IND_LOAD_B; + break; + case IndirectRegister::IND_C: + sub_clk = SUB_CLK_IND_LOAD_C; + break; + } + FF val = memory.at(addr); - bool tagMatch = load_in_mem_trace(clk, interm_reg, addr, val, m_in_tag); + bool tagMatch = load_from_mem_trace(clk, sub_clk, addr, val, AvmMemoryTag::U32); return MemRead{ .tag_match = tagMatch, 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 e7246f14d034..d31d22ab7eb5 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 @@ -9,12 +9,15 @@ class AvmMemTraceBuilder { public: static const size_t MEM_SIZE = 1024; - static const uint32_t SUB_CLK_LOAD_A = 0; - static const uint32_t SUB_CLK_LOAD_B = 1; - static const uint32_t SUB_CLK_LOAD_C = 2; - static const uint32_t SUB_CLK_STORE_A = 3; - static const uint32_t SUB_CLK_STORE_B = 4; - static const uint32_t SUB_CLK_STORE_C = 5; + static const uint32_t SUB_CLK_IND_LOAD_A = 0; + static const uint32_t SUB_CLK_IND_LOAD_B = 1; + static const uint32_t SUB_CLK_IND_LOAD_C = 2; + static const uint32_t SUB_CLK_LOAD_A = 3; + static const uint32_t SUB_CLK_LOAD_B = 4; + static const uint32_t SUB_CLK_LOAD_C = 5; + static const uint32_t SUB_CLK_STORE_A = 6; + static const uint32_t SUB_CLK_STORE_B = 7; + static const uint32_t SUB_CLK_STORE_C = 8; // Keeps track of the number of times a mem tag err should appear in the trace // clk -> count @@ -75,6 +78,7 @@ class AvmMemTraceBuilder { 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 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); @@ -93,8 +97,7 @@ class AvmMemTraceBuilder { AvmMemoryTag m_in_tag, AvmMemoryTag m_tag); - bool load_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 m_in_tag); void store_in_mem_trace( uint32_t clk, IntermRegister interm_reg, uint32_t addr, FF const& val, AvmMemoryTag m_in_tag); }; 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 c02f8b8f3c67..805cae56f9e5 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -9,6 +9,8 @@ #include #include "avm_trace.hpp" +#include "barretenberg/vm/avm_trace/avm_common.hpp" +#include "barretenberg/vm/avm_trace/avm_mem_trace.hpp" namespace bb::avm_trace { @@ -365,32 +367,58 @@ void AvmTraceBuilder::set(uint128_t val, uint32_t dst_offset, AvmMemoryTag in_ta * @brief Copy value and tag from a memory cell at position src_offset to the * memory cell at position dst_offset * + * @param indirect A byte encoding information about indirect/direct memory access. * @param src_offset Offset of source memory cell * @param dst_offset Offset of destination memory cell */ -void AvmTraceBuilder::op_mov(uint32_t const src_offset, uint32_t const dst_offset) +void AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset) { auto const clk = static_cast(main_trace.size()); + bool tag_match = true; + uint32_t direct_src_offset = src_offset; + uint32_t direct_dst_offset = dst_offset; + + bool indirect_src_flag = static_cast(indirect & 0x01); + bool indirect_dst_flag = static_cast((indirect & 0x02) >> 1); + + if (indirect_src_flag) { + auto read_ind_a = + mem_trace_builder.indirect_read_and_load_from_memory(clk, IndirectRegister::IND_A, src_offset); + tag_match = read_ind_a.tag_match; + direct_src_offset = uint32_t(read_ind_a.val); + } + + if (indirect_dst_flag) { + auto read_ind_c = + mem_trace_builder.indirect_read_and_load_from_memory(clk, IndirectRegister::IND_C, dst_offset); + tag_match = tag_match && read_ind_c.tag_match; + direct_dst_offset = uint32_t(read_ind_c.val); + } // Reading from memory and loading into ia without tag check. - auto const [val, tag] = mem_trace_builder.read_and_load_mov_opcode(clk, src_offset); + auto const [val, tag] = mem_trace_builder.read_and_load_mov_opcode(clk, direct_src_offset); - // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, dst_offset, val, tag); + // Write into memory from intermediate register ic. + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, direct_dst_offset, val, 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_mov = FF(1), - .avm_main_in_tag = FF(static_cast(tag)), + .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_tag_err = static_cast(!tag_match), .avm_main_ia = val, .avm_main_ic = val, - .avm_main_mem_op_a = FF(1), - .avm_main_mem_op_c = FF(1), - .avm_main_rwc = FF(1), - .avm_main_mem_idx_a = FF(src_offset), - .avm_main_mem_idx_c = FF(dst_offset), + .avm_main_mem_op_a = 1, + .avm_main_mem_op_c = 1, + .avm_main_rwc = 1, + .avm_main_ind_a = indirect_src_flag ? src_offset : 0, + .avm_main_ind_c = indirect_dst_flag ? dst_offset : 0, + .avm_main_ind_op_a = static_cast(indirect_src_flag), + .avm_main_ind_op_c = static_cast(indirect_dst_flag), + .avm_main_mem_idx_a = direct_src_offset, + .avm_main_mem_idx_c = direct_dst_offset, }); } @@ -787,15 +815,30 @@ std::vector AvmTraceBuilder::finalize() dest.incl_mem_tag_err_counts = FF(static_cast(src.m_tag_err_count_relevant)); - if (src.m_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_A || - src.m_sub_clk == AvmMemTraceBuilder::SUB_CLK_STORE_A) { - dest.avm_mem_m_op_a = FF(1); - } else if (src.m_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_B || - src.m_sub_clk == AvmMemTraceBuilder::SUB_CLK_STORE_B) { - dest.avm_mem_m_op_b = FF(1); - } else if (src.m_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_C || - src.m_sub_clk == AvmMemTraceBuilder::SUB_CLK_STORE_C) { - dest.avm_mem_m_op_c = FF(1); + switch (src.m_sub_clk) { + case AvmMemTraceBuilder::SUB_CLK_LOAD_A: + case AvmMemTraceBuilder::SUB_CLK_STORE_A: + dest.avm_mem_m_op_a = 1; + break; + case AvmMemTraceBuilder::SUB_CLK_LOAD_B: + case AvmMemTraceBuilder::SUB_CLK_STORE_B: + dest.avm_mem_m_op_b = 1; + break; + case AvmMemTraceBuilder::SUB_CLK_LOAD_C: + case AvmMemTraceBuilder::SUB_CLK_STORE_C: + dest.avm_mem_m_op_c = 1; + break; + case AvmMemTraceBuilder::SUB_CLK_IND_LOAD_A: + dest.avm_mem_m_ind_op_a = 1; + break; + case AvmMemTraceBuilder::SUB_CLK_IND_LOAD_B: + dest.avm_mem_m_ind_op_b = 1; + break; + case AvmMemTraceBuilder::SUB_CLK_IND_LOAD_C: + dest.avm_mem_m_ind_op_c = 1; + break; + default: + break; } if (i + 1 < mem_trace_size) { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp index 8731f4515fdf..e0bdb4e9ed1f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -50,7 +50,7 @@ class AvmTraceBuilder { void set(uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag); // Move (copy) the value and tag of a memory cell to another one. - void op_mov(uint32_t src_offset, uint32_t dst_offset); + void op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset); // Jump to a given program counter. void jump(uint32_t jmp_dest); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 9f863e2dcef5..87e34d8179d2 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -66,6 +66,12 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) 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); + commitments.avm_mem_m_ind_op_a = + transcript->template receive_from_prover(commitment_labels.avm_mem_m_ind_op_a); + commitments.avm_mem_m_ind_op_b = + transcript->template receive_from_prover(commitment_labels.avm_mem_m_ind_op_b); + commitments.avm_mem_m_ind_op_c = + transcript->template receive_from_prover(commitment_labels.avm_mem_m_ind_op_c); commitments.avm_mem_m_sel_mov = transcript->template receive_from_prover(commitment_labels.avm_mem_m_sel_mov); commitments.avm_mem_m_tag_err = @@ -176,6 +182,15 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) commitments.avm_main_rwa = transcript->template receive_from_prover(commitment_labels.avm_main_rwa); commitments.avm_main_rwb = transcript->template receive_from_prover(commitment_labels.avm_main_rwb); commitments.avm_main_rwc = transcript->template receive_from_prover(commitment_labels.avm_main_rwc); + commitments.avm_main_ind_a = transcript->template receive_from_prover(commitment_labels.avm_main_ind_a); + commitments.avm_main_ind_b = transcript->template receive_from_prover(commitment_labels.avm_main_ind_b); + commitments.avm_main_ind_c = transcript->template receive_from_prover(commitment_labels.avm_main_ind_c); + commitments.avm_main_ind_op_a = + transcript->template receive_from_prover(commitment_labels.avm_main_ind_op_a); + commitments.avm_main_ind_op_b = + transcript->template receive_from_prover(commitment_labels.avm_main_ind_op_b); + commitments.avm_main_ind_op_c = + transcript->template receive_from_prover(commitment_labels.avm_main_ind_op_c); commitments.avm_main_mem_idx_a = transcript->template receive_from_prover(commitment_labels.avm_main_mem_idx_a); commitments.avm_main_mem_idx_b = @@ -190,6 +205,12 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.perm_main_mem_b); commitments.perm_main_mem_c = transcript->template receive_from_prover(commitment_labels.perm_main_mem_c); + commitments.perm_main_mem_ind_a = + transcript->template receive_from_prover(commitment_labels.perm_main_mem_ind_a); + commitments.perm_main_mem_ind_b = + transcript->template receive_from_prover(commitment_labels.perm_main_mem_ind_b); + commitments.perm_main_mem_ind_c = + transcript->template receive_from_prover(commitment_labels.perm_main_mem_ind_c); commitments.incl_main_tag_err = transcript->template receive_from_prover(commitment_labels.incl_main_tag_err); commitments.incl_mem_tag_err = diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp index b018610c5efd..0feab83b36e9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_execution.test.cpp @@ -503,6 +503,54 @@ TEST_F(AvmExecutionTests, movOpcode) gen_proof_and_validate(bytecode, std::move(trace), {}); } +// Positive test with indirect MOV. +TEST_F(AvmExecutionTests, indMovOpcode) +{ + std::string bytecode_hex = to_hex(OpCode::SET) + // opcode SET + "00" // Indirect flag + "03" // U32 + "0000000A" // val 10 + "00000001" // dst_offset 1 + + to_hex(OpCode::SET) + // opcode SET + "00" // Indirect flag + "03" // U32 + "0000000B" // val 11 + "00000002" // dst_offset 2 + + to_hex(OpCode::SET) + // opcode SET + "00" // Indirect flag + "01" // U8 + "FF" // val 255 + "0000000A" // dst_offset 10 + + to_hex(OpCode::MOV) + // opcode MOV + "01" // Indirect flag + "00000001" // src_offset 1 --> direct offset 10 + "00000002" // dst_offset 2 --> direct offset 11 + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000000" // ret offset 0 + "00000000"; // ret size 0 + + auto bytecode = hex_to_bytes(bytecode_hex); + auto instructions = Deserialization::parse(bytecode); + + ASSERT_THAT(instructions, SizeIs(5)); + + // MOV + EXPECT_THAT(instructions.at(3), + AllOf(Field(&Instruction::op_code, OpCode::MOV), + Field(&Instruction::operands, + ElementsAre(VariantWith(1), VariantWith(1), VariantWith(2))))); + + auto trace = Execution::gen_trace(instructions); + + // Find the first row enabling the MOV selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_mov == 1; }); + EXPECT_EQ(row->avm_main_ia, 255); + EXPECT_EQ(row->avm_main_ic, 255); + + gen_proof_and_validate(bytecode, std::move(trace), {}); +} + // Negative test detecting an invalid opcode byte. TEST_F(AvmExecutionTests, invalidOpcode) { 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 04b43ea9a5ab..63dd61810ac6 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 @@ -1,11 +1,15 @@ #include "avm_common.test.hpp" #include "barretenberg/vm/avm_trace/avm_common.hpp" +#include "barretenberg/vm/avm_trace/avm_mem_trace.hpp" #include "barretenberg/vm/tests/helpers.test.hpp" #include #include +#include +#include namespace tests_avm { using namespace bb::avm_trace; +using namespace testing; class AvmMemOpcodeTests : public ::testing::Test { public: @@ -16,16 +20,34 @@ class AvmMemOpcodeTests : public ::testing::Test { size_t main_idx; size_t mem_a_idx; size_t mem_c_idx; + size_t mem_ind_a_idx; + size_t mem_ind_c_idx; // TODO(640): The Standard Honk on Grumpkin test suite fails unless the SRS is initialised for every test. void SetUp() override { srs::init_crs_factory("../srs_db/ignition"); }; - void buildTrace(uint128_t const val, uint32_t const src_offset, uint32_t const dst_offset, AvmMemoryTag const tag) + void buildTrace(bool indirect, + uint128_t const& val, + uint32_t src_offset, + uint32_t dst_offset, + AvmMemoryTag tag, + uint32_t dir_src_offset = 0, + uint32_t dir_dst_offset = 0) { - trace_builder.set(val, src_offset, tag); - trace_builder.op_mov(src_offset, dst_offset); + if (indirect) { + trace_builder.set(dir_src_offset, src_offset, AvmMemoryTag::U32); + trace_builder.set(dir_dst_offset, dst_offset, AvmMemoryTag::U32); + trace_builder.set(val, dir_src_offset, tag); + } else { + trace_builder.set(val, src_offset, tag); + } + + trace_builder.op_mov(indirect ? 3 : 0, src_offset, dst_offset); trace_builder.return_op(0, 0); trace = trace_builder.finalize(); + } + void computeIndices(bool indirect) + { // Find the first row enabling the MOV selector auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_mov == FF(1); }); ASSERT_TRUE(row != trace.end()); @@ -33,52 +55,96 @@ class AvmMemOpcodeTests : public ::testing::Test { auto clk = row->avm_main_clk; + auto gen_matcher = [clk](uint32_t sub_clk) { + return [clk, sub_clk](Row r) { return r.avm_mem_m_clk == clk && r.avm_mem_m_sub_clk == sub_clk; }; + }; + // Find the memory trace position corresponding to the load sub-operation of register ia. - 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_LOAD_A; - }); + row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(AvmMemTraceBuilder::SUB_CLK_LOAD_A)); ASSERT_TRUE(row != trace.end()); mem_a_idx = static_cast(row - trace.begin()); // Find the memory trace position corresponding to the write 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; - }); + row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(AvmMemTraceBuilder::SUB_CLK_STORE_C)); ASSERT_TRUE(row != trace.end()); mem_c_idx = static_cast(row - trace.begin()); + + // Find the memory trace position of the indirect loads. + if (indirect) { + row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(AvmMemTraceBuilder::SUB_CLK_IND_LOAD_A)); + ASSERT_TRUE(row != trace.end()); + mem_ind_a_idx = static_cast(row - trace.begin()); + + row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(AvmMemTraceBuilder::SUB_CLK_IND_LOAD_C)); + ASSERT_TRUE(row != trace.end()); + mem_ind_c_idx = static_cast(row - trace.begin()); + } } - void validate_trace(uint128_t const val, - uint32_t const src_offset, - uint32_t const dst_offset, - AvmMemoryTag const tag) + void validate_trace(bool indirect, + uint128_t const& val, + uint32_t src_offset, + uint32_t dst_offset, + AvmMemoryTag tag, + uint32_t dir_src_offset = 0, + uint32_t dir_dst_offset = 0) { + computeIndices(indirect); FF const val_ff = uint256_t::from_uint128(val); auto const& main_row = trace.at(main_idx); - EXPECT_EQ(main_row.avm_main_ia, val_ff); - EXPECT_EQ(main_row.avm_main_ib, FF(0)); - EXPECT_EQ(main_row.avm_main_ic, val_ff); - EXPECT_EQ(main_row.avm_main_in_tag, FF(static_cast(tag))); + if (indirect) { + EXPECT_THAT(main_row, + AllOf(Field(&Row::avm_main_mem_idx_a, dir_src_offset), + Field(&Row::avm_main_mem_idx_c, dir_dst_offset))); + } + EXPECT_THAT(main_row, + 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)))); auto const& mem_a_row = trace.at(mem_a_idx); - EXPECT_EQ(mem_a_row.avm_mem_m_tag_err, FF(0)); - EXPECT_EQ(mem_a_row.avm_mem_m_in_tag, FF(static_cast(tag))); - EXPECT_EQ(mem_a_row.avm_mem_m_tag, FF(static_cast(tag))); - EXPECT_EQ(mem_a_row.avm_mem_m_sel_mov, FF(1)); - EXPECT_EQ(mem_a_row.avm_mem_m_addr, FF(src_offset)); - EXPECT_EQ(mem_a_row.avm_mem_m_val, val_ff); - EXPECT_EQ(mem_a_row.avm_mem_m_op_a, FF(1)); + 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_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), + Field(&Row::avm_mem_m_val, val_ff), + Field(&Row::avm_mem_m_rw, 0), + Field(&Row::avm_mem_m_op_a, 1))); auto const& mem_c_row = trace.at(mem_c_idx); - EXPECT_EQ(mem_c_row.avm_mem_m_tag_err, FF(0)); - EXPECT_EQ(mem_c_row.avm_mem_m_in_tag, FF(static_cast(tag))); - EXPECT_EQ(mem_c_row.avm_mem_m_tag, FF(static_cast(tag))); - EXPECT_EQ(mem_c_row.avm_mem_m_addr, FF(dst_offset)); - EXPECT_EQ(mem_c_row.avm_mem_m_val, val_ff); - EXPECT_EQ(mem_c_row.avm_mem_m_op_c, FF(1)); + 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_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), + Field(&Row::avm_mem_m_op_c, 1))); + + if (indirect) { + 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_m_tag, static_cast(AvmMemoryTag::U32)), + Field(&Row::avm_mem_m_addr, src_offset), + Field(&Row::avm_mem_m_val, dir_src_offset), + Field(&Row::avm_mem_m_ind_op_a, 1))); + + 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_m_tag, static_cast(AvmMemoryTag::U32)), + Field(&Row::avm_mem_m_addr, dst_offset), + Field(&Row::avm_mem_m_val, dir_dst_offset), + Field(&Row::avm_mem_m_ind_op_c, 1))); + } validate_trace_proof(std::move(trace)); } @@ -88,51 +154,94 @@ class AvmMemOpcodeNegativeTests : public AvmMemOpcodeTests {}; /****************************************************************************** * - * MEMORY OPCODE TESTS + * MEMORY OPCODE POSITIVE TESTS * ******************************************************************************/ TEST_F(AvmMemOpcodeTests, basicMov) { - buildTrace(42, 9, 13, AvmMemoryTag::U64); - validate_trace(42, 9, 13, AvmMemoryTag::U64); + buildTrace(false, 42, 9, 13, AvmMemoryTag::U64); + validate_trace(false, 42, 9, 13, AvmMemoryTag::U64); } TEST_F(AvmMemOpcodeTests, sameAddressMov) { + buildTrace(false, 11, 356, 356, AvmMemoryTag::U16); + validate_trace(false, 11, 356, 356, AvmMemoryTag::U16); +} - buildTrace(11, 356, 356, AvmMemoryTag::U16); +TEST_F(AvmMemOpcodeTests, indirectMov) +{ + buildTrace(true, 23, 0, 1, AvmMemoryTag::U8, 2, 3); + validate_trace(true, 23, 0, 1, AvmMemoryTag::U8, 2, 3); +} - validate_trace(11, 356, 356, AvmMemoryTag::U16); +TEST_F(AvmMemOpcodeTests, indirectMovInvalidAddressTag) +{ + trace_builder.set(15, 100, AvmMemoryTag::U32); + trace_builder.set(16, 101, AvmMemoryTag::U128); // This will make the indirect load failing. + trace_builder.set(5, 15, AvmMemoryTag::FF); + trace_builder.op_mov(3, 100, 101); + trace_builder.return_op(0, 0); + trace = trace_builder.finalize(); + + computeIndices(true); + + EXPECT_EQ(trace.at(main_idx).avm_main_tag_err, 1); + 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_m_ind_op_c, 1))); + + validate_trace_proof(std::move(trace)); } -TEST_F(AvmMemOpcodeNegativeTests, wrongOutputErrorTag) +/****************************************************************************** + * + * MEMORY OPCODE NEGATIVE TESTS + * + ******************************************************************************/ + +TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputErrorTag) { - buildTrace(234, 0, 1, AvmMemoryTag::U8); + buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); + computeIndices(false); trace.at(main_idx).avm_main_tag_err = 1; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "INCL_MEM_TAG_ERR"); } -TEST_F(AvmMemOpcodeNegativeTests, wrongOutputValue) +TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputValue) { - buildTrace(234, 0, 1, AvmMemoryTag::U8); + buildTrace(false, 234, 0, 1, AvmMemoryTag::U8); + computeIndices(false); trace.at(main_idx).avm_main_ic = 233; EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), "MOV_SAME_VALUE"); } +TEST_F(AvmMemOpcodeNegativeTests, indMovWrongOutputValue) +{ + buildTrace(true, 8732, 23, 24, AvmMemoryTag::U16, 432, 876); + computeIndices(true); + trace.at(main_idx).avm_main_ic = 8733; + + 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 -// main trace and the memory entry related to stor operation from Ic. -TEST_F(AvmMemOpcodeNegativeTests, wrongOutputTagLoadIa) +// main trace and the memory entry related to store operation from Ic. +TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagLoadIa) { FF const tag_u64 = FF(static_cast(AvmMemoryTag::U64)); FF const tag_u8 = FF(static_cast(AvmMemoryTag::U8)); FF const one_min_inverse_diff = FF(1) - (tag_u64 - tag_u8).invert(); - buildTrace(234, 0, 1, AvmMemoryTag::U8); + 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_m_tag_err = 1; @@ -147,13 +256,14 @@ TEST_F(AvmMemOpcodeNegativeTests, wrongOutputTagLoadIa) // Same as above but one tries to disable the selector of MOV opcode in // the load operation. -TEST_F(AvmMemOpcodeNegativeTests, wrongOutputTagDisabledSelector) +TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagDisabledSelector) { FF const tag_u64 = FF(static_cast(AvmMemoryTag::U64)); FF const tag_u8 = FF(static_cast(AvmMemoryTag::U8)); FF const one_min_inverse_diff = FF(1) - (tag_u64 - tag_u8).invert(); - buildTrace(234, 0, 1, AvmMemoryTag::U8); + 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_m_tag_err = 1; @@ -169,11 +279,13 @@ TEST_F(AvmMemOpcodeNegativeTests, wrongOutputTagDisabledSelector) // 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, wrongOutputTagMainTrace) +TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagMainTrace) { FF const tag_u64 = FF(static_cast(AvmMemoryTag::U64)); - buildTrace(234, 0, 1, AvmMemoryTag::U8); + 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;