From 19dbe46bce95221bf2e68c9361618998a6bdc64f Mon Sep 17 00:00:00 2001 From: Jean M <132435771+jeanmon@users.noreply.github.com> Date: Thu, 11 Apr 2024 11:23:43 +0200 Subject: [PATCH] feat(avm): CMOV opcode (#5575) Resolves #5557 --- barretenberg/cpp/pil/avm/avm_main.pil | 73 +++- barretenberg/cpp/pil/avm/avm_mem.pil | 39 +- .../relations/generated/avm/avm_main.hpp | 237 +++++++---- .../relations/generated/avm/avm_mem.hpp | 155 ++++++-- .../relations/generated/avm/declare_views.hpp | 19 +- .../generated/avm/perm_main_mem_a.hpp | 14 +- .../generated/avm/perm_main_mem_b.hpp | 14 +- .../generated/avm/perm_main_mem_d.hpp | 114 ++++++ .../generated/avm/perm_main_mem_ind_d.hpp | 98 +++++ .../barretenberg/vm/avm_trace/avm_common.hpp | 4 +- .../vm/avm_trace/avm_deserialization.cpp | 2 + .../vm/avm_trace/avm_execution.cpp | 7 + .../vm/avm_trace/avm_mem_trace.cpp | 74 +++- .../vm/avm_trace/avm_mem_trace.hpp | 23 +- .../barretenberg/vm/avm_trace/avm_trace.cpp | 185 +++++++-- .../barretenberg/vm/avm_trace/avm_trace.hpp | 8 +- .../vm/generated/avm_circuit_builder.hpp | 48 ++- .../barretenberg/vm/generated/avm_flavor.hpp | 185 ++++++++- .../barretenberg/vm/generated/avm_prover.cpp | 38 +- .../vm/generated/avm_verifier.cpp | 34 +- .../vm/tests/avm_execution.test.cpp | 56 +++ .../vm/tests/avm_mem_opcodes.test.cpp | 371 +++++++++++++++++- 22 files changed, 1563 insertions(+), 235 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_d.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_d.hpp diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index 92fa0f4fa83..d491662c0fb 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -30,6 +30,7 @@ namespace avm_main(256); //===== MEMORY OPCODES ========================================================== pol commit sel_mov; + pol commit sel_cmov; //===== TABLE SUBOP-TR ======================================================== // Boolean selectors for (sub-)operations. Only one operation is activated at @@ -75,32 +76,37 @@ namespace avm_main(256); // A helper witness being the inverse of some value // to show a non-zero equality pol commit inv; + pol commit id_zero; // Boolean telling whether id is zero (cmov opcode) // Intermediate register values pol commit ia; pol commit ib; pol commit ic; + pol commit id; // Memory operation selector per intermediate register pol commit mem_op_a; pol commit mem_op_b; pol commit mem_op_c; + pol commit mem_op_d; // Read-write flag per intermediate register: Read = 0, Write = 1 pol commit rwa; pol commit rwb; pol commit rwc; + pol commit rwd; // Indirect register values pol commit ind_a; pol commit ind_b; pol commit ind_c; + pol commit ind_d; // Indirect memory operation selector per indirect register pol commit ind_op_a; pol commit ind_op_b; pol commit ind_op_c; - + pol commit ind_op_d; // 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, @@ -108,7 +114,7 @@ namespace avm_main(256); pol commit mem_idx_a; pol commit mem_idx_b; pol commit mem_idx_c; - + pol commit mem_idx_d; // Track the last line of the execution trace. It does NOT correspond to the last row of the whole table // of size N. As this depends on the supplied bytecode, this polynomial cannot be constant. @@ -135,27 +141,32 @@ namespace avm_main(256); // Might be removed if derived from opcode based on a lookup of constants sel_mov * ( 1 - sel_mov) = 0; + sel_cmov * ( 1 - sel_cmov) = 0; op_err * (1 - op_err) = 0; tag_err * (1 - tag_err) = 0; // Potential optimization (boolean constraint derivation from equivalence check to avm_mem)? + id_zero * (1 - id_zero) = 0; // 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; + mem_op_d * (1 - mem_op_d) = 0; rwa * (1 - rwa) = 0; rwb * (1 - rwb) = 0; rwc * (1 - rwc) = 0; + rwd * (1 - rwd) = 0; // 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; + ind_op_d * (1 - ind_op_d) = 0; // TODO - Constraints: - // - mem_idx_a, mem_idx_b, mem_idx_c to u32 type - // - ind_a, ind_b, ind_c to u32 type + // - mem_idx_a, mem_idx_b, mem_idx_c, mem_idx_d to u32 type + // - ind_a, ind_b, ind_c, ind_d to u32 type // - 0 <= r_in_tag, w_in_tag <= 6 // Maybe not needed as probably derived by the operation decomposition. //====== COMPARATOR OPCODES CONSTRAINTS ===================================== @@ -245,10 +256,36 @@ namespace avm_main(256); // TODO: we want to set an initial number for the reserved memory of the jump pointer //====== MEMORY OPCODES CONSTRAINTS ========================================= - #[MOV_SAME_VALUE] - sel_mov * (ia - ic) = 0; // Ensure that the correct value is moved/copied. + + // TODO: consolidate with zero division error handling + + // When sel_cmov == 1, we need id == 0 <==> id_zero == 0 + // This can be achieved with the 2 following relations. + // inv is an extra witness to show that we can invert id, i.e., inv = id^(-1) + // If id == 0, we have to set inv = 1 to satisfy the second relation, + // because id_zero == 1 from the first relation. + #[CMOV_CONDITION_RES_1] + sel_cmov * (id * inv - 1 + id_zero) = 0; + #[CMOV_CONDITION_RES_2] + sel_cmov * id_zero * (1 - inv) = 0; + + // Boolean selectors telling whether we move ia to ic or ib to ic. + // Boolean constraints and mutual exclusivity are derived from their + // respective definitions based on sel_mov, sel_cmov, and id_zero. + pol commit sel_mov_a; + pol commit sel_mov_b; + + // For MOV, we copy ia to ic. + // For CMOV, we copy ia to ic if id is NOT zero, otherwise we copy ib to ic. + sel_mov_a = sel_mov + sel_cmov * (1 - id_zero); + sel_mov_b = sel_cmov * id_zero; + + #[MOV_SAME_VALUE_A] + sel_mov_a * (ia - ic) = 0; // Ensure that the correct value is moved/copied. + #[MOV_SAME_VALUE_B] + sel_mov_b * (ib - ic) = 0; // Ensure that the correct value is moved/copied. #[MOV_MAIN_SAME_TAG] - sel_mov * (r_in_tag - w_in_tag) = 0; + (sel_mov + sel_cmov) * (r_in_tag - w_in_tag) = 0; //====== Inter-table Constraints ============================================ #[INCL_MAIN_TAG_ERR] @@ -288,20 +325,31 @@ namespace avm_main(256); avm_binary.start {avm_binary.clk, avm_binary.acc_ia, avm_binary.acc_ib, avm_binary.acc_ic, avm_binary.op_id, avm_binary.in_tag}; #[PERM_MAIN_MEM_A] - mem_op_a {clk, mem_idx_a, ia, rwa, r_in_tag, w_in_tag, sel_mov} + mem_op_a {clk, mem_idx_a, ia, rwa + , r_in_tag, w_in_tag, sel_mov_a, sel_cmov} is - avm_mem.op_a {avm_mem.clk, avm_mem.addr, avm_mem.val, avm_mem.rw, avm_mem.r_in_tag, avm_mem.w_in_tag, avm_mem.sel_mov}; + avm_mem.op_a {avm_mem.clk, avm_mem.addr, avm_mem.val, avm_mem.rw + , avm_mem.r_in_tag, avm_mem.w_in_tag, avm_mem.sel_mov_a, avm_mem.sel_cmov}; #[PERM_MAIN_MEM_B] - mem_op_b {clk, mem_idx_b, ib, rwb, r_in_tag, w_in_tag} + mem_op_b {clk, mem_idx_b, ib, rwb + , r_in_tag, w_in_tag, sel_mov_b, sel_cmov} is - avm_mem.op_b {avm_mem.clk, avm_mem.addr, avm_mem.val, avm_mem.rw, avm_mem.r_in_tag, avm_mem.w_in_tag}; + avm_mem.op_b {avm_mem.clk, avm_mem.addr, avm_mem.val, avm_mem.rw + , avm_mem.r_in_tag, avm_mem.w_in_tag, avm_mem.sel_mov_b, avm_mem.sel_cmov}; #[PERM_MAIN_MEM_C] mem_op_c {clk, mem_idx_c, ic, rwc, r_in_tag, w_in_tag} is avm_mem.op_c {avm_mem.clk, avm_mem.addr, avm_mem.val, avm_mem.rw, avm_mem.r_in_tag, avm_mem.w_in_tag}; + #[PERM_MAIN_MEM_D] + mem_op_d {clk, mem_idx_d, id, rwd + , r_in_tag, w_in_tag, sel_cmov} + is + avm_mem.op_d {avm_mem.clk, avm_mem.addr, avm_mem.val, avm_mem.rw + , avm_mem.r_in_tag, avm_mem.w_in_tag, avm_mem.sel_cmov}; + #[PERM_MAIN_MEM_IND_A] ind_op_a {clk, ind_a, mem_idx_a} is avm_mem.ind_op_a {avm_mem.clk, avm_mem.addr, avm_mem.val}; @@ -311,6 +359,9 @@ namespace avm_main(256); #[PERM_MAIN_MEM_IND_C] ind_op_c {clk, ind_c, mem_idx_c} is avm_mem.ind_op_c {avm_mem.clk, avm_mem.addr, avm_mem.val}; + #[PERM_MAIN_MEM_IND_D] + ind_op_d {clk, ind_d, mem_idx_d} is avm_mem.ind_op_d {avm_mem.clk, avm_mem.addr, avm_mem.val}; + //====== Inter-table Constraints (Range Checks) ============================================ // TODO: Investigate optimising these range checks. Handling non-FF elements should require less range checks. #[LOOKUP_U8_0] diff --git a/barretenberg/cpp/pil/avm/avm_mem.pil b/barretenberg/cpp/pil/avm/avm_mem.pil index 7be221ed2f5..34834214487 100644 --- a/barretenberg/cpp/pil/avm/avm_mem.pil +++ b/barretenberg/cpp/pil/avm/avm_mem.pil @@ -15,20 +15,26 @@ namespace avm_mem(256); pol commit r_in_tag; // Instruction memory tag ("foreign key" pointing to avm_main.r_in_tag) pol commit w_in_tag; // Instruction memory tag ("foreign key" pointing to avm_main.w_in_tag) + pol commit skip_check_tag; // A boolean value which relaxes the consistency check in memory + // trace between tag and r_in_tag. Required for CMOV opcode. // Indicator of the intermediate register pertaining to the memory operation (foreign key to avm_main.mem_op_XXX) pol commit op_a; pol commit op_b; pol commit op_c; + pol commit op_d; // Indicator of the indirect register pertaining to the memory operation (foreign key to avm_main.ind_op_XXX) pol commit ind_op_a; pol commit ind_op_b; pol commit ind_op_c; + pol commit ind_op_d; - // Selector for MOV opcode (copied from main trace for loading operation on intermediated register ia) + // Selectors related to MOV/CMOV opcodes (copied from main trace for loading operation on intermediated register ia/ib) // Boolean constraint is performed in main trace. - pol commit sel_mov; + pol commit sel_mov_a; + pol commit sel_mov_b; + pol commit sel_cmov; // Error columns pol commit tag_err; // Boolean (1 if r_in_tag != tag is detected) @@ -44,20 +50,22 @@ namespace avm_mem(256); op_a * (1 - op_a) = 0; op_b * (1 - op_b) = 0; op_c * (1 - op_c) = 0; + op_d * (1 - op_d) = 0; ind_op_a * (1 - ind_op_a) = 0; ind_op_b * (1 - ind_op_b) = 0; ind_op_c * (1 - ind_op_c) = 0; + ind_op_d * (1 - ind_op_d) = 0; // TODO: addr is u32 and 0 <= tag <= 6 // (r_in_tag, w_in_tag will be constrained through inclusion check to main trace) // Maximum one memory operation enabled per row - pol MEM_SEL = op_a + op_b + op_c + ind_op_a + ind_op_b + ind_op_c; + pol MEM_SEL = op_a + op_b + op_c + op_d + ind_op_a + ind_op_b + ind_op_c + ind_op_d; MEM_SEL * (MEM_SEL - 1) = 0; // sub_clk derivation - pol IND_OP = ind_op_a + ind_op_b + ind_op_c; - sub_clk = MEM_SEL * (ind_op_b + op_b + 2 * (ind_op_c + op_c) + 3 * (1 - IND_OP + rw)); + pol IND_OP = ind_op_a + ind_op_b + ind_op_c + ind_op_d; + sub_clk = MEM_SEL * (ind_op_b + op_b + 2 * (ind_op_c + op_c) + 3 * (ind_op_d + op_d) + 4 * (1 - IND_OP + rw)); // We need the MEM_SEL factor as the right factor is not zero when all columns are zero. // Remark: lastAccess == 1 on first row and therefore any relation with the @@ -106,6 +114,10 @@ namespace avm_mem(256); #[MEM_ZERO_INIT] lastAccess * (1 - rw') * val' = 0; + // Skip check tag + #[SKIP_CHECK_TAG] + skip_check_tag = sel_cmov * (op_d + op_a * (1-sel_mov_a) + op_b * (1-sel_mov_b)); + // Memory tag consistency check for load operations, i.e., rw == 0. // We want to prove that r_in_tag == tag <==> tag_err == 0 // We want to show that we can invert (r_in_tag - tag) when tag_err == 1, @@ -120,10 +132,13 @@ namespace avm_mem(256); // The new column one_min_inv is set to 1 - (r_in_tag - tag)^(-1) when tag_err == 1 // but must be set to 0 when tags are matching and tag_err = 0 #[MEM_IN_TAG_CONSISTENCY_1] - (1 - rw) * ((r_in_tag - tag) * (1 - one_min_inv) - tag_err) = 0; + (1 - skip_check_tag) * (1 - rw) * ((r_in_tag - tag) * (1 - one_min_inv) - tag_err) = 0; #[MEM_IN_TAG_CONSISTENCY_2] (1 - tag_err) * one_min_inv = 0; + #[NO_TAG_ERR_WRITE_OR_SKIP] + (skip_check_tag + rw) * tag_err = 0; + // Correctness of two above checks MEM_IN_TAG_CONSISTENCY_1/2 (assuming rw == 0): // r_in_tag == tag ==> tag_err == 0 (first relation) // tag_err == 0 ==> one_min_inv == 0 by second relation. First relation ==> r_in_tag - tag == 0 @@ -140,18 +155,20 @@ namespace avm_mem(256); ind_op_a * (r_in_tag - 3) = 0; ind_op_b * (r_in_tag - 3) = 0; ind_op_c * (r_in_tag - 3) = 0; + ind_op_d * (r_in_tag - 3) = 0; // Indirect operation is always a load ind_op_a * rw = 0; ind_op_b * rw = 0; ind_op_c * rw = 0; + ind_op_d * rw = 0; - //====== MOV Opcode Tag Constraint ===================================== + //====== MOV/CMOV Opcode Tag Constraint ===================================== // The following constraint ensures that the r_in_tag is set to tag for - // the load operation pertaining to Ia. - // The permutation check #[PERM_MAIN_MEM_A] guarantees that the r_in_tag - // value load operation for Ia is copied back in the main trace. + // the load operation pertaining to Ia resp. Ib. + // The permutation check #[PERM_MAIN_MEM_A/B] guarantees that the r_in_tag + // value load operation for Ia/Ib is copied back in the main trace. // Constraint #[MOV_MAIN_SAME_TAG] copies r_in_tag to w_in_tag in the main // trace. Then, #[PERM_MAIN_MEM_C] copies w_in_tag for store operation from Ic. #[MOV_SAME_TAG] - sel_mov * tag_err = 0; // Equivalent to sel_mov * (r_in_tag - tag) = 0 \ No newline at end of file + (sel_mov_a + sel_mov_b) * tag_err = 0; // Equivalent to (sel_mov_a + sel_mov_b) * (r_in_tag - tag) = 0 \ No newline at end of file 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 b3ae090ccdf..74e611ac699 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -14,9 +14,12 @@ template struct Avm_mainRow { FF avm_main_ia{}; FF avm_main_ib{}; FF avm_main_ic{}; + FF avm_main_id{}; + FF avm_main_id_zero{}; FF avm_main_ind_op_a{}; FF avm_main_ind_op_b{}; FF avm_main_ind_op_c{}; + FF avm_main_ind_op_d{}; FF avm_main_internal_return_ptr{}; FF avm_main_internal_return_ptr_shift{}; FF avm_main_inv{}; @@ -25,6 +28,7 @@ template struct Avm_mainRow { FF avm_main_mem_op_a{}; FF avm_main_mem_op_b{}; FF avm_main_mem_op_c{}; + FF avm_main_mem_op_d{}; FF avm_main_op_err{}; FF avm_main_pc{}; FF avm_main_pc_shift{}; @@ -32,11 +36,15 @@ template struct Avm_mainRow { FF avm_main_rwa{}; FF avm_main_rwb{}; FF avm_main_rwc{}; + FF avm_main_rwd{}; + FF avm_main_sel_cmov{}; FF avm_main_sel_halt{}; FF avm_main_sel_internal_call{}; FF avm_main_sel_internal_return{}; FF avm_main_sel_jump{}; FF avm_main_sel_mov{}; + FF avm_main_sel_mov_a{}; + FF avm_main_sel_mov_b{}; FF avm_main_sel_op_add{}; FF avm_main_sel_op_and{}; FF avm_main_sel_op_div{}; @@ -55,43 +63,52 @@ template struct Avm_mainRow { inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 27: + case 32: return "OUTPUT_U8"; - case 28: + case 33: return "SUBOP_DIVISION_FF"; - case 29: + case 34: return "SUBOP_DIVISION_ZERO_ERR1"; - case 30: + case 35: return "SUBOP_DIVISION_ZERO_ERR2"; - case 31: + case 36: return "SUBOP_ERROR_RELEVANT_OP"; - case 33: + case 38: return "RETURN_POINTER_INCREMENT"; - case 39: + case 44: return "RETURN_POINTER_DECREMENT"; - case 44: + case 49: return "PC_INCREMENT"; - case 45: + case 50: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 46: - return "MOV_SAME_VALUE"; + case 51: + return "CMOV_CONDITION_RES_1"; + + case 52: + return "CMOV_CONDITION_RES_2"; + + case 55: + return "MOV_SAME_VALUE_A"; - case 47: + case 56: + return "MOV_SAME_VALUE_B"; + + case 57: return "MOV_MAIN_SAME_TAG"; - case 49: + case 59: return "BIN_SEL_1"; - case 50: + case 60: return "BIN_SEL_2"; } return std::to_string(index); @@ -101,9 +118,9 @@ template class avm_mainImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 2, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 4, 4, 3, 3, 3, 3, 3, 3, 3, 2, }; template @@ -245,7 +262,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(16); - auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); + auto tmp = (avm_main_sel_cmov * (-avm_main_sel_cmov + FF(1))); tmp *= scaling_factor; std::get<16>(evals) += tmp; } @@ -253,7 +270,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(17); - auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); + auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); tmp *= scaling_factor; std::get<17>(evals) += tmp; } @@ -261,7 +278,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(18); - auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); + auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -269,7 +286,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(19); - auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); + auto tmp = (avm_main_id_zero * (-avm_main_id_zero + FF(1))); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -277,7 +294,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); + auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -285,7 +302,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); + auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -293,7 +310,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); + auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -301,7 +318,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); + auto tmp = (avm_main_mem_op_d * (-avm_main_mem_op_d + FF(1))); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -309,7 +326,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = (avm_main_ind_op_a * (-avm_main_ind_op_a + FF(1))); + auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -317,7 +334,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); + auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -325,7 +342,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); + auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -333,8 +350,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = - (((avm_main_sel_op_eq + avm_main_sel_op_lte) + avm_main_sel_op_lt) * (avm_main_w_in_tag - FF(1))); + auto tmp = (avm_main_rwd * (-avm_main_rwd + FF(1))); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -342,8 +358,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(28); - 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<28>(evals) += tmp; } @@ -351,7 +366,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(29); - 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<29>(evals) += tmp; } @@ -359,7 +374,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(30); - 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<30>(evals) += tmp; } @@ -367,7 +382,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(31); - auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); + auto tmp = (avm_main_ind_op_d * (-avm_main_ind_op_d + FF(1))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -375,7 +390,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(32); - auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); + auto tmp = + (((avm_main_sel_op_eq + avm_main_sel_op_lte) + avm_main_sel_op_lt) * (avm_main_w_in_tag - FF(1))); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -383,8 +399,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(33); - 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 + FF(1))) * ((avm_main_ic * avm_main_ib) - avm_main_ia)); tmp *= scaling_factor; std::get<33>(evals) += tmp; } @@ -392,7 +408,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(34); - auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); + auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -400,7 +416,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(35); - auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); + auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; std::get<35>(evals) += tmp; } @@ -408,7 +424,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(36); - auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); + auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); tmp *= scaling_factor; std::get<36>(evals) += tmp; } @@ -416,7 +432,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(37); - auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); + auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<37>(evals) += tmp; } @@ -424,7 +440,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(38); - auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); + 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<38>(evals) += tmp; } @@ -432,8 +449,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(39); - 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_internal_return_ptr - avm_main_mem_idx_b)); tmp *= scaling_factor; std::get<39>(evals) += tmp; } @@ -441,7 +457,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(40); - 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_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<40>(evals) += tmp; } @@ -449,7 +465,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(41); - auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); tmp *= scaling_factor; std::get<41>(evals) += tmp; } @@ -457,7 +473,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(42); - auto tmp = (avm_main_sel_internal_return * avm_main_rwa); + auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); tmp *= scaling_factor; std::get<42>(evals) += tmp; } @@ -465,7 +481,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(43); - auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<43>(evals) += tmp; } @@ -473,6 +489,47 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(44); + 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<44>(evals) += tmp; + } + // Contribution 45 + { + Avm_DECLARE_VIEWS(45); + + auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); + tmp *= scaling_factor; + std::get<45>(evals) += tmp; + } + // Contribution 46 + { + Avm_DECLARE_VIEWS(46); + + auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); + tmp *= scaling_factor; + std::get<46>(evals) += tmp; + } + // Contribution 47 + { + Avm_DECLARE_VIEWS(47); + + auto tmp = (avm_main_sel_internal_return * avm_main_rwa); + tmp *= scaling_factor; + std::get<47>(evals) += tmp; + } + // Contribution 48 + { + Avm_DECLARE_VIEWS(48); + + auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + tmp *= scaling_factor; + std::get<48>(evals) += tmp; + } + // Contribution 49 + { + Avm_DECLARE_VIEWS(49); + 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) + @@ -483,38 +540,78 @@ template class avm_mainImpl { avm_main_sel_op_xor)) * (avm_main_pc_shift - (avm_main_pc + FF(1)))); tmp *= scaling_factor; - std::get<44>(evals) += tmp; + std::get<49>(evals) += tmp; } - // Contribution 45 + // Contribution 50 { - Avm_DECLARE_VIEWS(45); + Avm_DECLARE_VIEWS(50); 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<45>(evals) += tmp; + std::get<50>(evals) += tmp; } - // Contribution 46 + // Contribution 51 { - Avm_DECLARE_VIEWS(46); + Avm_DECLARE_VIEWS(51); - auto tmp = (avm_main_sel_mov * (avm_main_ia - avm_main_ic)); + auto tmp = (avm_main_sel_cmov * (((avm_main_id * avm_main_inv) - FF(1)) + avm_main_id_zero)); tmp *= scaling_factor; - std::get<46>(evals) += tmp; + std::get<51>(evals) += tmp; } - // Contribution 47 + // Contribution 52 { - Avm_DECLARE_VIEWS(47); + Avm_DECLARE_VIEWS(52); - auto tmp = (avm_main_sel_mov * (avm_main_r_in_tag - avm_main_w_in_tag)); + auto tmp = ((avm_main_sel_cmov * avm_main_id_zero) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; - std::get<47>(evals) += tmp; + std::get<52>(evals) += tmp; } - // Contribution 48 + // Contribution 53 { - Avm_DECLARE_VIEWS(48); + Avm_DECLARE_VIEWS(53); + + auto tmp = (avm_main_sel_mov_a - (avm_main_sel_mov + (avm_main_sel_cmov * (-avm_main_id_zero + FF(1))))); + tmp *= scaling_factor; + std::get<53>(evals) += tmp; + } + // Contribution 54 + { + Avm_DECLARE_VIEWS(54); + + auto tmp = (avm_main_sel_mov_b - (avm_main_sel_cmov * avm_main_id_zero)); + tmp *= scaling_factor; + std::get<54>(evals) += tmp; + } + // Contribution 55 + { + Avm_DECLARE_VIEWS(55); + + auto tmp = (avm_main_sel_mov_a * (avm_main_ia - avm_main_ic)); + tmp *= scaling_factor; + std::get<55>(evals) += tmp; + } + // Contribution 56 + { + Avm_DECLARE_VIEWS(56); + + auto tmp = (avm_main_sel_mov_b * (avm_main_ib - avm_main_ic)); + tmp *= scaling_factor; + std::get<56>(evals) += tmp; + } + // Contribution 57 + { + Avm_DECLARE_VIEWS(57); + + auto tmp = ((avm_main_sel_mov + avm_main_sel_cmov) * (avm_main_r_in_tag - avm_main_w_in_tag)); + tmp *= scaling_factor; + std::get<57>(evals) += tmp; + } + // Contribution 58 + { + Avm_DECLARE_VIEWS(58); auto tmp = (avm_main_alu_sel - @@ -524,23 +621,23 @@ template class avm_mainImpl { avm_main_sel_op_lte) * (-avm_main_tag_err + FF(1)))); tmp *= scaling_factor; - std::get<48>(evals) += tmp; + std::get<58>(evals) += tmp; } - // Contribution 49 + // Contribution 59 { - Avm_DECLARE_VIEWS(49); + Avm_DECLARE_VIEWS(59); auto tmp = (avm_main_bin_op_id - (avm_main_sel_op_or + (avm_main_sel_op_xor * FF(2)))); tmp *= scaling_factor; - std::get<49>(evals) += tmp; + std::get<59>(evals) += tmp; } - // Contribution 50 + // Contribution 60 { - Avm_DECLARE_VIEWS(50); + Avm_DECLARE_VIEWS(60); auto tmp = (avm_main_bin_sel - ((avm_main_sel_op_and + avm_main_sel_op_or) + avm_main_sel_op_xor)); tmp *= scaling_factor; - std::get<50>(evals) += tmp; + std::get<60>(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 7ab7905c9b8..2de1a2fe5b0 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -12,16 +12,21 @@ template struct Avm_memRow { FF avm_mem_ind_op_a{}; FF avm_mem_ind_op_b{}; FF avm_mem_ind_op_c{}; + FF avm_mem_ind_op_d{}; FF avm_mem_last{}; FF avm_mem_lastAccess{}; FF avm_mem_one_min_inv{}; FF avm_mem_op_a{}; FF avm_mem_op_b{}; FF avm_mem_op_c{}; + FF avm_mem_op_d{}; FF avm_mem_r_in_tag{}; FF avm_mem_rw{}; FF avm_mem_rw_shift{}; - FF avm_mem_sel_mov{}; + FF avm_mem_sel_cmov{}; + FF avm_mem_sel_mov_a{}; + FF avm_mem_sel_mov_b{}; + FF avm_mem_skip_check_tag{}; FF avm_mem_sub_clk{}; FF avm_mem_tag{}; FF avm_mem_tag_err{}; @@ -34,28 +39,34 @@ template struct Avm_memRow { inline std::string get_relation_label_avm_mem(int index) { switch (index) { - case 12: + case 14: return "MEM_LAST_ACCESS_DELIMITER"; - case 13: + case 15: return "MEM_READ_WRITE_VAL_CONSISTENCY"; - case 14: + case 16: return "MEM_READ_WRITE_TAG_CONSISTENCY"; - case 15: + case 17: return "MEM_ZERO_INIT"; - case 16: + case 18: + return "SKIP_CHECK_TAG"; + + case 19: return "MEM_IN_TAG_CONSISTENCY_1"; - case 17: + case 20: return "MEM_IN_TAG_CONSISTENCY_2"; - case 19: + case 21: + return "NO_TAG_ERR_WRITE_OR_SKIP"; + + case 23: return "NO_TAG_ERR_WRITE"; - case 26: + case 32: return "MOV_SAME_TAG"; } return std::to_string(index); @@ -65,8 +76,8 @@ template class avm_memImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 4, 4, 4, 4, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }; template @@ -136,7 +147,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(7); - auto tmp = (avm_mem_ind_op_a * (-avm_mem_ind_op_a + FF(1))); + auto tmp = (avm_mem_op_d * (-avm_mem_op_d + FF(1))); tmp *= scaling_factor; std::get<7>(evals) += tmp; } @@ -144,7 +155,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(8); - auto tmp = (avm_mem_ind_op_b * (-avm_mem_ind_op_b + FF(1))); + auto tmp = (avm_mem_ind_op_a * (-avm_mem_ind_op_a + FF(1))); tmp *= scaling_factor; std::get<8>(evals) += tmp; } @@ -152,7 +163,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(9); - auto tmp = (avm_mem_ind_op_c * (-avm_mem_ind_op_c + FF(1))); + auto tmp = (avm_mem_ind_op_b * (-avm_mem_ind_op_b + FF(1))); tmp *= scaling_factor; std::get<9>(evals) += tmp; } @@ -160,11 +171,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(10); - auto tmp = ((((((avm_mem_op_a + avm_mem_op_b) + avm_mem_op_c) + avm_mem_ind_op_a) + avm_mem_ind_op_b) + - avm_mem_ind_op_c) * - ((((((avm_mem_op_a + avm_mem_op_b) + avm_mem_op_c) + avm_mem_ind_op_a) + avm_mem_ind_op_b) + - avm_mem_ind_op_c) - - FF(1))); + auto tmp = (avm_mem_ind_op_c * (-avm_mem_ind_op_c + FF(1))); tmp *= scaling_factor; std::get<10>(evals) += tmp; } @@ -172,12 +179,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(11); - auto tmp = - (avm_mem_sub_clk - - ((((((avm_mem_op_a + avm_mem_op_b) + avm_mem_op_c) + avm_mem_ind_op_a) + avm_mem_ind_op_b) + - avm_mem_ind_op_c) * - (((avm_mem_ind_op_b + avm_mem_op_b) + ((avm_mem_ind_op_c + avm_mem_op_c) * FF(2))) + - (((-((avm_mem_ind_op_a + avm_mem_ind_op_b) + avm_mem_ind_op_c) + FF(1)) + avm_mem_rw) * FF(3))))); + auto tmp = (avm_mem_ind_op_d * (-avm_mem_ind_op_d + FF(1))); tmp *= scaling_factor; std::get<11>(evals) += tmp; } @@ -185,7 +187,15 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(12); - auto tmp = ((-avm_mem_lastAccess + FF(1)) * (avm_mem_addr_shift - avm_mem_addr)); + auto tmp = ((((((((avm_mem_op_a + avm_mem_op_b) + avm_mem_op_c) + avm_mem_op_d) + avm_mem_ind_op_a) + + avm_mem_ind_op_b) + + avm_mem_ind_op_c) + + avm_mem_ind_op_d) * + ((((((((avm_mem_op_a + avm_mem_op_b) + avm_mem_op_c) + avm_mem_op_d) + avm_mem_ind_op_a) + + avm_mem_ind_op_b) + + avm_mem_ind_op_c) + + avm_mem_ind_op_d) - + FF(1))); tmp *= scaling_factor; std::get<12>(evals) += tmp; } @@ -193,8 +203,16 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(13); - auto tmp = - (((-avm_mem_lastAccess + FF(1)) * (-avm_mem_rw_shift + FF(1))) * (avm_mem_val_shift - avm_mem_val)); + auto tmp = (avm_mem_sub_clk - + ((((((((avm_mem_op_a + avm_mem_op_b) + avm_mem_op_c) + avm_mem_op_d) + avm_mem_ind_op_a) + + avm_mem_ind_op_b) + + avm_mem_ind_op_c) + + avm_mem_ind_op_d) * + ((((avm_mem_ind_op_b + avm_mem_op_b) + ((avm_mem_ind_op_c + avm_mem_op_c) * FF(2))) + + ((avm_mem_ind_op_d + avm_mem_op_d) * FF(3))) + + (((-(((avm_mem_ind_op_a + avm_mem_ind_op_b) + avm_mem_ind_op_c) + avm_mem_ind_op_d) + FF(1)) + + avm_mem_rw) * + FF(4))))); tmp *= scaling_factor; std::get<13>(evals) += tmp; } @@ -202,8 +220,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(14); - auto tmp = - (((-avm_mem_lastAccess + FF(1)) * (-avm_mem_rw_shift + FF(1))) * (avm_mem_tag_shift - avm_mem_tag)); + auto tmp = ((-avm_mem_lastAccess + FF(1)) * (avm_mem_addr_shift - avm_mem_addr)); tmp *= scaling_factor; std::get<14>(evals) += tmp; } @@ -211,7 +228,8 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(15); - auto tmp = ((avm_mem_lastAccess * (-avm_mem_rw_shift + FF(1))) * avm_mem_val_shift); + auto tmp = + (((-avm_mem_lastAccess + FF(1)) * (-avm_mem_rw_shift + FF(1))) * (avm_mem_val_shift - avm_mem_val)); tmp *= scaling_factor; std::get<15>(evals) += tmp; } @@ -219,8 +237,8 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(16); - auto tmp = ((-avm_mem_rw + FF(1)) * - (((avm_mem_r_in_tag - avm_mem_tag) * (-avm_mem_one_min_inv + FF(1))) - avm_mem_tag_err)); + auto tmp = + (((-avm_mem_lastAccess + FF(1)) * (-avm_mem_rw_shift + FF(1))) * (avm_mem_tag_shift - avm_mem_tag)); tmp *= scaling_factor; std::get<16>(evals) += tmp; } @@ -228,7 +246,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(17); - auto tmp = ((-avm_mem_tag_err + FF(1)) * avm_mem_one_min_inv); + auto tmp = ((avm_mem_lastAccess * (-avm_mem_rw_shift + FF(1))) * avm_mem_val_shift); tmp *= scaling_factor; std::get<17>(evals) += tmp; } @@ -236,7 +254,9 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(18); - auto tmp = (avm_mem_rw * (avm_mem_w_in_tag - avm_mem_tag)); + auto tmp = (avm_mem_skip_check_tag - + (avm_mem_sel_cmov * ((avm_mem_op_d + (avm_mem_op_a * (-avm_mem_sel_mov_a + FF(1)))) + + (avm_mem_op_b * (-avm_mem_sel_mov_b + FF(1)))))); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -244,7 +264,8 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(19); - auto tmp = (avm_mem_rw * avm_mem_tag_err); + auto tmp = (((-avm_mem_skip_check_tag + FF(1)) * (-avm_mem_rw + FF(1))) * + (((avm_mem_r_in_tag - avm_mem_tag) * (-avm_mem_one_min_inv + FF(1))) - avm_mem_tag_err)); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -252,7 +273,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = (avm_mem_ind_op_a * (avm_mem_r_in_tag - FF(3))); + auto tmp = ((-avm_mem_tag_err + FF(1)) * avm_mem_one_min_inv); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -260,7 +281,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = (avm_mem_ind_op_b * (avm_mem_r_in_tag - FF(3))); + auto tmp = ((avm_mem_skip_check_tag + avm_mem_rw) * avm_mem_tag_err); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -268,7 +289,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = (avm_mem_ind_op_c * (avm_mem_r_in_tag - FF(3))); + auto tmp = (avm_mem_rw * (avm_mem_w_in_tag - avm_mem_tag)); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -276,7 +297,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (avm_mem_ind_op_a * avm_mem_rw); + auto tmp = (avm_mem_rw * avm_mem_tag_err); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -284,7 +305,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = (avm_mem_ind_op_b * avm_mem_rw); + auto tmp = (avm_mem_ind_op_a * (avm_mem_r_in_tag - FF(3))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -292,7 +313,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (avm_mem_ind_op_c * avm_mem_rw); + auto tmp = (avm_mem_ind_op_b * (avm_mem_r_in_tag - FF(3))); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -300,10 +321,58 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = (avm_mem_sel_mov * avm_mem_tag_err); + auto tmp = (avm_mem_ind_op_c * (avm_mem_r_in_tag - FF(3))); tmp *= scaling_factor; std::get<26>(evals) += tmp; } + // Contribution 27 + { + Avm_DECLARE_VIEWS(27); + + auto tmp = (avm_mem_ind_op_d * (avm_mem_r_in_tag - FF(3))); + tmp *= scaling_factor; + std::get<27>(evals) += tmp; + } + // Contribution 28 + { + Avm_DECLARE_VIEWS(28); + + auto tmp = (avm_mem_ind_op_a * avm_mem_rw); + tmp *= scaling_factor; + std::get<28>(evals) += tmp; + } + // Contribution 29 + { + Avm_DECLARE_VIEWS(29); + + auto tmp = (avm_mem_ind_op_b * avm_mem_rw); + tmp *= scaling_factor; + std::get<29>(evals) += tmp; + } + // Contribution 30 + { + Avm_DECLARE_VIEWS(30); + + auto tmp = (avm_mem_ind_op_c * avm_mem_rw); + tmp *= scaling_factor; + std::get<30>(evals) += tmp; + } + // Contribution 31 + { + Avm_DECLARE_VIEWS(31); + + auto tmp = (avm_mem_ind_op_d * avm_mem_rw); + tmp *= scaling_factor; + std::get<31>(evals) += tmp; + } + // Contribution 32 + { + Avm_DECLARE_VIEWS(32); + + auto tmp = ((avm_mem_sel_mov_a + avm_mem_sel_mov_b) * avm_mem_tag_err); + tmp *= scaling_factor; + std::get<32>(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 8bebe5f792d..168d0b96d07 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -87,32 +87,42 @@ [[maybe_unused]] auto avm_main_ia = View(new_term.avm_main_ia); \ [[maybe_unused]] auto avm_main_ib = View(new_term.avm_main_ib); \ [[maybe_unused]] auto avm_main_ic = View(new_term.avm_main_ic); \ + [[maybe_unused]] auto avm_main_id = View(new_term.avm_main_id); \ + [[maybe_unused]] auto avm_main_id_zero = View(new_term.avm_main_id_zero); \ [[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_d = View(new_term.avm_main_ind_d); \ [[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_ind_op_d = View(new_term.avm_main_ind_op_d); \ [[maybe_unused]] auto avm_main_internal_return_ptr = View(new_term.avm_main_internal_return_ptr); \ [[maybe_unused]] auto avm_main_inv = View(new_term.avm_main_inv); \ [[maybe_unused]] auto avm_main_last = View(new_term.avm_main_last); \ [[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); \ + [[maybe_unused]] auto avm_main_mem_idx_d = View(new_term.avm_main_mem_idx_d); \ [[maybe_unused]] auto avm_main_mem_op_a = View(new_term.avm_main_mem_op_a); \ [[maybe_unused]] auto avm_main_mem_op_b = View(new_term.avm_main_mem_op_b); \ [[maybe_unused]] auto avm_main_mem_op_c = View(new_term.avm_main_mem_op_c); \ + [[maybe_unused]] auto avm_main_mem_op_d = View(new_term.avm_main_mem_op_d); \ [[maybe_unused]] auto avm_main_op_err = View(new_term.avm_main_op_err); \ [[maybe_unused]] auto avm_main_pc = View(new_term.avm_main_pc); \ [[maybe_unused]] auto avm_main_r_in_tag = View(new_term.avm_main_r_in_tag); \ [[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_rwd = View(new_term.avm_main_rwd); \ + [[maybe_unused]] auto avm_main_sel_cmov = View(new_term.avm_main_sel_cmov); \ [[maybe_unused]] auto avm_main_sel_halt = View(new_term.avm_main_sel_halt); \ [[maybe_unused]] auto avm_main_sel_internal_call = View(new_term.avm_main_sel_internal_call); \ [[maybe_unused]] auto avm_main_sel_internal_return = View(new_term.avm_main_sel_internal_return); \ [[maybe_unused]] auto avm_main_sel_jump = View(new_term.avm_main_sel_jump); \ [[maybe_unused]] auto avm_main_sel_mov = View(new_term.avm_main_sel_mov); \ + [[maybe_unused]] auto avm_main_sel_mov_a = View(new_term.avm_main_sel_mov_a); \ + [[maybe_unused]] auto avm_main_sel_mov_b = View(new_term.avm_main_sel_mov_b); \ [[maybe_unused]] auto avm_main_sel_op_add = View(new_term.avm_main_sel_op_add); \ [[maybe_unused]] auto avm_main_sel_op_and = View(new_term.avm_main_sel_op_and); \ [[maybe_unused]] auto avm_main_sel_op_div = View(new_term.avm_main_sel_op_div); \ @@ -133,15 +143,20 @@ [[maybe_unused]] auto avm_mem_ind_op_a = View(new_term.avm_mem_ind_op_a); \ [[maybe_unused]] auto avm_mem_ind_op_b = View(new_term.avm_mem_ind_op_b); \ [[maybe_unused]] auto avm_mem_ind_op_c = View(new_term.avm_mem_ind_op_c); \ + [[maybe_unused]] auto avm_mem_ind_op_d = View(new_term.avm_mem_ind_op_d); \ [[maybe_unused]] auto avm_mem_last = View(new_term.avm_mem_last); \ [[maybe_unused]] auto avm_mem_lastAccess = View(new_term.avm_mem_lastAccess); \ [[maybe_unused]] auto avm_mem_one_min_inv = View(new_term.avm_mem_one_min_inv); \ [[maybe_unused]] auto avm_mem_op_a = View(new_term.avm_mem_op_a); \ [[maybe_unused]] auto avm_mem_op_b = View(new_term.avm_mem_op_b); \ [[maybe_unused]] auto avm_mem_op_c = View(new_term.avm_mem_op_c); \ + [[maybe_unused]] auto avm_mem_op_d = View(new_term.avm_mem_op_d); \ [[maybe_unused]] auto avm_mem_r_in_tag = View(new_term.avm_mem_r_in_tag); \ [[maybe_unused]] auto avm_mem_rw = View(new_term.avm_mem_rw); \ - [[maybe_unused]] auto avm_mem_sel_mov = View(new_term.avm_mem_sel_mov); \ + [[maybe_unused]] auto avm_mem_sel_cmov = View(new_term.avm_mem_sel_cmov); \ + [[maybe_unused]] auto avm_mem_sel_mov_a = View(new_term.avm_mem_sel_mov_a); \ + [[maybe_unused]] auto avm_mem_sel_mov_b = View(new_term.avm_mem_sel_mov_b); \ + [[maybe_unused]] auto avm_mem_skip_check_tag = View(new_term.avm_mem_skip_check_tag); \ [[maybe_unused]] auto avm_mem_sub_clk = View(new_term.avm_mem_sub_clk); \ [[maybe_unused]] auto avm_mem_tag = View(new_term.avm_mem_tag); \ [[maybe_unused]] auto avm_mem_tag_err = View(new_term.avm_mem_tag_err); \ @@ -152,9 +167,11 @@ [[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_d = View(new_term.perm_main_mem_d); \ [[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 perm_main_mem_ind_d = View(new_term.perm_main_mem_ind_d); \ [[maybe_unused]] auto lookup_byte_lengths = View(new_term.lookup_byte_lengths); \ [[maybe_unused]] auto lookup_byte_operations = View(new_term.lookup_byte_operations); \ [[maybe_unused]] auto incl_main_tag_err = View(new_term.incl_main_tag_err); \ diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_a.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_a.hpp index 62e4f48c289..fb2a35e3ce0 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_a.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_a.hpp @@ -12,7 +12,7 @@ namespace bb { class perm_main_mem_a_permutation_settings { public: // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 7; + constexpr static size_t COLUMNS_PER_SET = 8; /** * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the @@ -56,14 +56,16 @@ class perm_main_mem_a_permutation_settings { in.avm_main_rwa, in.avm_main_r_in_tag, in.avm_main_w_in_tag, - in.avm_main_sel_mov, + in.avm_main_sel_mov_a, + in.avm_main_sel_cmov, in.avm_mem_clk, in.avm_mem_addr, in.avm_mem_val, in.avm_mem_rw, in.avm_mem_r_in_tag, in.avm_mem_w_in_tag, - in.avm_mem_sel_mov); + in.avm_mem_sel_mov_a, + in.avm_mem_sel_cmov); } /** @@ -96,14 +98,16 @@ class perm_main_mem_a_permutation_settings { in.avm_main_rwa, in.avm_main_r_in_tag, in.avm_main_w_in_tag, - in.avm_main_sel_mov, + in.avm_main_sel_mov_a, + in.avm_main_sel_cmov, in.avm_mem_clk, in.avm_mem_addr, in.avm_mem_val, in.avm_mem_rw, in.avm_mem_r_in_tag, in.avm_mem_w_in_tag, - in.avm_mem_sel_mov); + in.avm_mem_sel_mov_a, + in.avm_mem_sel_cmov); } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_b.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_b.hpp index 4da414817f1..0cedcf27b6c 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_b.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_b.hpp @@ -12,7 +12,7 @@ namespace bb { class perm_main_mem_b_permutation_settings { public: // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 6; + constexpr static size_t COLUMNS_PER_SET = 8; /** * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the @@ -56,12 +56,16 @@ class perm_main_mem_b_permutation_settings { in.avm_main_rwb, in.avm_main_r_in_tag, in.avm_main_w_in_tag, + in.avm_main_sel_mov_b, + in.avm_main_sel_cmov, in.avm_mem_clk, in.avm_mem_addr, in.avm_mem_val, in.avm_mem_rw, in.avm_mem_r_in_tag, - in.avm_mem_w_in_tag); + in.avm_mem_w_in_tag, + in.avm_mem_sel_mov_b, + in.avm_mem_sel_cmov); } /** @@ -94,12 +98,16 @@ class perm_main_mem_b_permutation_settings { in.avm_main_rwb, in.avm_main_r_in_tag, in.avm_main_w_in_tag, + in.avm_main_sel_mov_b, + in.avm_main_sel_cmov, in.avm_mem_clk, in.avm_mem_addr, in.avm_mem_val, in.avm_mem_rw, in.avm_mem_r_in_tag, - in.avm_mem_w_in_tag); + in.avm_mem_w_in_tag, + in.avm_mem_sel_mov_b, + in.avm_mem_sel_cmov); } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_d.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_d.hpp new file mode 100644 index 00000000000..389b6f2d880 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_d.hpp @@ -0,0 +1,114 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class perm_main_mem_d_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 7; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the + * 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_mem_op_d == 1 || in.avm_mem_op_d == 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_d, + in.avm_main_mem_op_d, + in.avm_main_mem_op_d, + in.avm_mem_op_d, + in.avm_main_clk, + in.avm_main_mem_idx_d, + in.avm_main_id, + in.avm_main_rwd, + in.avm_main_r_in_tag, + in.avm_main_w_in_tag, + in.avm_main_sel_cmov, + in.avm_mem_clk, + in.avm_mem_addr, + in.avm_mem_val, + in.avm_mem_rw, + in.avm_mem_r_in_tag, + in.avm_mem_w_in_tag, + in.avm_mem_sel_cmov); + } + + /** + * @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_d, + in.avm_main_mem_op_d, + in.avm_main_mem_op_d, + in.avm_mem_op_d, + in.avm_main_clk, + in.avm_main_mem_idx_d, + in.avm_main_id, + in.avm_main_rwd, + in.avm_main_r_in_tag, + in.avm_main_w_in_tag, + in.avm_main_sel_cmov, + in.avm_mem_clk, + in.avm_mem_addr, + in.avm_mem_val, + in.avm_mem_rw, + in.avm_mem_r_in_tag, + in.avm_mem_w_in_tag, + in.avm_mem_sel_cmov); + } +}; + +template +using perm_main_mem_d_relation = GenericPermutationRelation; +template using perm_main_mem_d = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_d.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_d.hpp new file mode 100644 index 00000000000..4b005cb3495 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_mem_ind_d.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_d_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_d == 1 || in.avm_mem_ind_op_d == 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_d, + in.avm_main_ind_op_d, + in.avm_main_ind_op_d, + in.avm_mem_ind_op_d, + in.avm_main_clk, + in.avm_main_ind_d, + in.avm_main_mem_idx_d, + in.avm_mem_clk, + in.avm_mem_addr, + in.avm_mem_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_d, + in.avm_main_ind_op_d, + in.avm_main_ind_op_d, + in.avm_mem_ind_op_d, + in.avm_main_clk, + in.avm_main_ind_d, + in.avm_main_mem_idx_d, + in.avm_mem_clk, + in.avm_mem_addr, + in.avm_mem_val); + } +}; + +template +using perm_main_mem_ind_d_relation = GenericPermutationRelation; +template using perm_main_mem_ind_d = 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 04ed5dc05d6..a0261419281 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_common.hpp @@ -13,8 +13,8 @@ using Row = bb::AvmFullRow; // Number of rows static const size_t AVM_TRACE_SIZE = 1 << 18; -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 }; +enum class IntermRegister : uint32_t { IA = 0, IB = 1, IC = 2, ID = 3 }; +enum class IndirectRegister : uint32_t { IND_A = 0, IND_B = 1, IND_C = 2, IND_D = 3 }; // 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_deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp index 03d4091ddef..2590e5e298a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp @@ -44,6 +44,8 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = // Machine State - Memory // OpCode::SET is handled differently { OpCode::MOV, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, + { OpCode::CMOV, + { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, // Control Flow - Contract Calls { OpCode::RETURN, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, }; 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 753ce9eca13..1e018d647d6 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -232,6 +232,13 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(1)), std::get(inst.operands.at(2))); break; + case OpCode::CMOV: + trace_builder.op_cmov(std::get(inst.operands.at(0)), + std::get(inst.operands.at(1)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4))); + break; // Control Flow - Contract Calls case OpCode::RETURN: trace_builder.return_op(std::get(inst.operands.at(0)), 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 bc073320d46..00b7b0bc1a6 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 @@ -170,6 +170,9 @@ void AvmMemTraceBuilder::store_in_mem_trace( case IntermRegister::IC: sub_clk = SUB_CLK_STORE_C; break; + case IntermRegister::ID: + sub_clk = SUB_CLK_STORE_D; + break; } insert_in_mem_trace(clk, sub_clk, addr, val, w_in_tag, r_in_tag, w_in_tag, true); @@ -190,20 +193,71 @@ void AvmMemTraceBuilder::store_in_mem_trace( */ AvmMemTraceBuilder::MemEntry AvmMemTraceBuilder::read_and_load_mov_opcode(uint32_t const clk, uint32_t const addr) { - MemEntry memEntry = memory.contains(addr) ? memory.at(addr) : MemEntry{}; + MemEntry mem_entry = memory.contains(addr) ? memory.at(addr) : MemEntry{}; mem_trace.emplace_back(MemoryTraceEntry{ .m_clk = clk, .m_sub_clk = SUB_CLK_LOAD_A, .m_addr = addr, - .m_val = memEntry.val, - .m_tag = memEntry.tag, - .r_in_tag = memEntry.tag, - .w_in_tag = memEntry.tag, - .m_sel_mov = true, + .m_val = mem_entry.val, + .m_tag = mem_entry.tag, + .r_in_tag = mem_entry.tag, + .w_in_tag = mem_entry.tag, + .m_sel_mov_a = true, + }); + + return mem_entry; +} + +std::array AvmMemTraceBuilder::read_and_load_cmov_opcode(uint32_t clk, + uint32_t a_addr, + uint32_t b_addr, + uint32_t cond_addr) +{ + MemEntry a_mem_entry = memory.contains(a_addr) ? memory.at(a_addr) : MemEntry{}; + MemEntry b_mem_entry = memory.contains(b_addr) ? memory.at(b_addr) : MemEntry{}; + MemEntry cond_mem_entry = memory.contains(cond_addr) ? memory.at(cond_addr) : MemEntry{}; + + bool mov_b = cond_mem_entry.val == 0; + + AvmMemoryTag r_w_in_tag = mov_b ? b_mem_entry.tag : a_mem_entry.tag; + + mem_trace.emplace_back(MemoryTraceEntry{ + .m_clk = clk, + .m_sub_clk = SUB_CLK_LOAD_A, + .m_addr = a_addr, + .m_val = a_mem_entry.val, + .m_tag = a_mem_entry.tag, + .r_in_tag = r_w_in_tag, + .w_in_tag = r_w_in_tag, + .m_sel_mov_a = !mov_b, + .m_sel_cmov = true, + }); + + mem_trace.emplace_back(MemoryTraceEntry{ + .m_clk = clk, + .m_sub_clk = SUB_CLK_LOAD_B, + .m_addr = b_addr, + .m_val = b_mem_entry.val, + .m_tag = b_mem_entry.tag, + .r_in_tag = r_w_in_tag, + .w_in_tag = r_w_in_tag, + .m_sel_mov_b = mov_b, + .m_sel_cmov = true, }); - return memEntry; + mem_trace.emplace_back(MemoryTraceEntry{ + .m_clk = clk, + .m_sub_clk = SUB_CLK_LOAD_D, + .m_addr = cond_addr, + .m_val = cond_mem_entry.val, + .m_tag = cond_mem_entry.tag, + .r_in_tag = r_w_in_tag, + .w_in_tag = r_w_in_tag, + .m_sel_cmov = true, + }); + + return { a_mem_entry, b_mem_entry, cond_mem_entry }; } /** @@ -237,6 +291,9 @@ AvmMemTraceBuilder::MemRead AvmMemTraceBuilder::read_and_load_from_memory(uint32 case IntermRegister::IC: sub_clk = SUB_CLK_LOAD_C; break; + case IntermRegister::ID: + sub_clk = SUB_CLK_LOAD_D; + break; } FF val = memory.contains(addr) ? memory.at(addr).val : 0; @@ -263,6 +320,9 @@ AvmMemTraceBuilder::MemRead AvmMemTraceBuilder::indirect_read_and_load_from_memo case IndirectRegister::IND_C: sub_clk = SUB_CLK_IND_LOAD_C; break; + case IndirectRegister::IND_D: + sub_clk = SUB_CLK_IND_LOAD_D; + break; } FF val = memory.contains(addr) ? memory.at(addr).val : 0; 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 14c1d8accc5..31bc2e4b915 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 @@ -11,12 +11,15 @@ class AvmMemTraceBuilder { 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; + static const uint32_t SUB_CLK_IND_LOAD_D = 3; + static const uint32_t SUB_CLK_LOAD_A = 4; + static const uint32_t SUB_CLK_LOAD_B = 5; + static const uint32_t SUB_CLK_LOAD_C = 6; + static const uint32_t SUB_CLK_LOAD_D = 7; + static const uint32_t SUB_CLK_STORE_A = 8; + static const uint32_t SUB_CLK_STORE_B = 9; + static const uint32_t SUB_CLK_STORE_C = 10; + static const uint32_t SUB_CLK_STORE_D = 11; // Keeps track of the number of times a mem tag err should appear in the trace // clk -> count @@ -33,7 +36,9 @@ class AvmMemTraceBuilder { bool m_rw = false; bool m_tag_err = false; FF m_one_min_inv{}; - bool m_sel_mov = false; + bool m_sel_mov_a = false; + bool m_sel_mov_b = false; + bool m_sel_cmov = false; bool m_tag_err_count_relevant = false; /** @@ -83,6 +88,10 @@ class AvmMemTraceBuilder { std::vector finalize(); MemEntry read_and_load_mov_opcode(uint32_t clk, uint32_t addr); + std::array read_and_load_cmov_opcode(uint32_t clk, + uint32_t a_addr, + uint32_t b_addr, + uint32_t cond_addr); MemRead read_and_load_from_memory( uint32_t clk, IntermRegister interm_reg, uint32_t addr, AvmMemoryTag r_in_tag, AvmMemoryTag w_in_tag); MemRead indirect_read_and_load_from_memory(uint32_t clk, IndirectRegister ind_reg, uint32_t addr); 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 4a31987c2b1..5c4a20515ad 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -39,7 +39,7 @@ void AvmTraceBuilder::reset() } AvmTraceBuilder::IndirectThreeResolution AvmTraceBuilder::resolve_ind_three( - uint32_t clk, uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset) + uint32_t clk, uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t c_offset) { bool indirect_flag_a = is_operand_indirect(indirect, 0); bool indirect_flag_b = is_operand_indirect(indirect, 1); @@ -47,7 +47,7 @@ AvmTraceBuilder::IndirectThreeResolution AvmTraceBuilder::resolve_ind_three( uint32_t direct_a_offset = a_offset; uint32_t direct_b_offset = b_offset; - uint32_t direct_dst_offset = dst_offset; + uint32_t direct_c_offset = c_offset; bool tag_match = true; @@ -64,9 +64,8 @@ AvmTraceBuilder::IndirectThreeResolution AvmTraceBuilder::resolve_ind_three( } if (indirect_flag_c) { - auto read_ind_c = - mem_trace_builder.indirect_read_and_load_from_memory(clk, IndirectRegister::IND_C, dst_offset); - direct_dst_offset = uint32_t(read_ind_c.val); + auto read_ind_c = mem_trace_builder.indirect_read_and_load_from_memory(clk, IndirectRegister::IND_C, c_offset); + direct_c_offset = uint32_t(read_ind_c.val); tag_match = tag_match && read_ind_c.tag_match; } @@ -74,7 +73,7 @@ AvmTraceBuilder::IndirectThreeResolution AvmTraceBuilder::resolve_ind_three( .tag_match = tag_match, .direct_a_offset = direct_a_offset, .direct_b_offset = direct_b_offset, - .direct_dst_offset = direct_dst_offset, + .direct_c_offset = direct_c_offset, .indirect_flag_a = indirect_flag_a, .indirect_flag_b = indirect_flag_b, .indirect_flag_c = indirect_flag_c, @@ -115,7 +114,7 @@ void AvmTraceBuilder::op_add( FF c = tag_match ? alu_trace_builder.op_add(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -131,7 +130,7 @@ void AvmTraceBuilder::op_add( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -178,7 +177,7 @@ void AvmTraceBuilder::op_sub( FF c = tag_match ? alu_trace_builder.op_sub(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -194,7 +193,7 @@ void AvmTraceBuilder::op_sub( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -241,7 +240,7 @@ void AvmTraceBuilder::op_mul( FF c = tag_match ? alu_trace_builder.op_mul(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -257,7 +256,7 @@ void AvmTraceBuilder::op_mul( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -313,7 +312,7 @@ void AvmTraceBuilder::op_div( } // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -330,7 +329,7 @@ void AvmTraceBuilder::op_div( .avm_main_inv = tag_match ? inv : FF(1), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -444,7 +443,7 @@ void AvmTraceBuilder::op_eq( FF c = tag_match ? alu_trace_builder.op_eq(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, AvmMemoryTag::U8); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, AvmMemoryTag::U8); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -460,7 +459,7 @@ void AvmTraceBuilder::op_eq( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -494,7 +493,7 @@ void AvmTraceBuilder::op_and( FF c = tag_match ? bin_trace_builder.op_and(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -512,7 +511,7 @@ void AvmTraceBuilder::op_and( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -546,7 +545,7 @@ void AvmTraceBuilder::op_or( FF c = tag_match ? bin_trace_builder.op_or(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -564,7 +563,7 @@ void AvmTraceBuilder::op_or( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -598,7 +597,7 @@ void AvmTraceBuilder::op_xor( FF c = tag_match ? bin_trace_builder.op_xor(a, b, in_tag, clk) : FF(0); // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, in_tag); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, in_tag); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -616,7 +615,7 @@ void AvmTraceBuilder::op_xor( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -651,7 +650,7 @@ void AvmTraceBuilder::op_lt( range_checked_required = true; // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, AvmMemoryTag::U8); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, AvmMemoryTag::U8); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -667,7 +666,7 @@ void AvmTraceBuilder::op_lt( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -702,7 +701,7 @@ void AvmTraceBuilder::op_lte( range_checked_required = true; // Write into memory value c from intermediate register ic. - mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, AvmMemoryTag::U8); + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_c_offset, c, in_tag, AvmMemoryTag::U8); main_trace.push_back(Row{ .avm_main_clk = clk, @@ -718,7 +717,7 @@ void AvmTraceBuilder::op_lte( .avm_main_internal_return_ptr = FF(internal_return_ptr), .avm_main_mem_idx_a = FF(res.direct_a_offset), .avm_main_mem_idx_b = FF(res.direct_b_offset), - .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_idx_c = FF(res.direct_c_offset), .avm_main_mem_op_a = FF(1), .avm_main_mem_op_b = FF(1), .avm_main_mem_op_c = FF(1), @@ -832,6 +831,114 @@ void AvmTraceBuilder::op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst .avm_main_r_in_tag = static_cast(tag), .avm_main_rwc = 1, .avm_main_sel_mov = 1, + .avm_main_sel_mov_a = 1, + .avm_main_tag_err = static_cast(!tag_match), + .avm_main_w_in_tag = static_cast(tag), + }); +} + +/** + * @brief Copy value and tag from a memory cell at position src_offset to the + * memory cell at position dst_offset. src_offset is a_offset if the value + * defined by cond_offset is non-zero. Otherwise, src_offset is b_offset. + * + * @param indirect A byte encoding information about indirect/direct memory access. + * @param a_offset Offset of first candidate source memory cell + * @param b_offset Offset of second candidate source memory cell + * @param cond_offset Offset of the condition determining the source offset (a_offset or b_offset) + * @param dst_offset Offset of destination memory cell + */ +void AvmTraceBuilder::op_cmov( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t cond_offset, uint32_t dst_offset) +{ + auto const clk = static_cast(main_trace.size()); + bool tag_match = true; + uint32_t direct_a_offset = a_offset; + uint32_t direct_b_offset = b_offset; + uint32_t direct_cond_offset = cond_offset; + uint32_t direct_dst_offset = dst_offset; + + bool indirect_a_flag = is_operand_indirect(indirect, 0); + bool indirect_b_flag = is_operand_indirect(indirect, 1); + bool indirect_cond_flag = is_operand_indirect(indirect, 2); + bool indirect_dst_flag = is_operand_indirect(indirect, 3); + + if (indirect_a_flag) { + auto read_ind_a = mem_trace_builder.indirect_read_and_load_from_memory(clk, IndirectRegister::IND_A, a_offset); + direct_a_offset = uint32_t(read_ind_a.val); + tag_match = tag_match && read_ind_a.tag_match; + } + + if (indirect_b_flag) { + auto read_ind_b = mem_trace_builder.indirect_read_and_load_from_memory(clk, IndirectRegister::IND_B, b_offset); + direct_b_offset = uint32_t(read_ind_b.val); + tag_match = tag_match && read_ind_b.tag_match; + } + + if (indirect_cond_flag) { + auto read_ind_d = + mem_trace_builder.indirect_read_and_load_from_memory(clk, IndirectRegister::IND_D, cond_offset); + direct_cond_offset = uint32_t(read_ind_d.val); + tag_match = tag_match && read_ind_d.tag_match; + } + + if (indirect_dst_flag) { + auto read_ind_c = + mem_trace_builder.indirect_read_and_load_from_memory(clk, IndirectRegister::IND_C, dst_offset); + direct_dst_offset = uint32_t(read_ind_c.val); + tag_match = tag_match && read_ind_c.tag_match; + } + + // Reading from memory and loading into ia or ib without tag check. We also load the conditional value + // in id without any tag check. + std::array const cmov_res = + mem_trace_builder.read_and_load_cmov_opcode(clk, direct_a_offset, direct_b_offset, direct_cond_offset); + + AvmMemTraceBuilder::MemEntry const& a_mem_entry = cmov_res.at(0); + AvmMemTraceBuilder::MemEntry const& b_mem_entry = cmov_res.at(1); + AvmMemTraceBuilder::MemEntry const& cond_mem_entry = cmov_res.at(2); + + const bool id_zero = cond_mem_entry.val == 0; + + auto const& val = id_zero ? b_mem_entry.val : a_mem_entry.val; + auto const& tag = id_zero ? b_mem_entry.tag : a_mem_entry.tag; + + // Write into memory from intermediate register ic. + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, direct_dst_offset, val, tag, tag); + + FF const inv = !id_zero ? cond_mem_entry.val.invert() : 1; + + main_trace.push_back(Row{ + .avm_main_clk = clk, + .avm_main_ia = a_mem_entry.val, + .avm_main_ib = b_mem_entry.val, + .avm_main_ic = val, + .avm_main_id = cond_mem_entry.val, + .avm_main_id_zero = static_cast(id_zero), + .avm_main_ind_a = indirect_a_flag ? a_offset : 0, + .avm_main_ind_b = indirect_b_flag ? b_offset : 0, + .avm_main_ind_c = indirect_dst_flag ? dst_offset : 0, + .avm_main_ind_d = indirect_cond_flag ? cond_offset : 0, + .avm_main_ind_op_a = static_cast(indirect_a_flag), + .avm_main_ind_op_b = static_cast(indirect_b_flag), + .avm_main_ind_op_c = static_cast(indirect_dst_flag), + .avm_main_ind_op_d = static_cast(indirect_cond_flag), + .avm_main_internal_return_ptr = internal_return_ptr, + .avm_main_inv = inv, + .avm_main_mem_idx_a = direct_a_offset, + .avm_main_mem_idx_b = direct_b_offset, + .avm_main_mem_idx_c = direct_dst_offset, + .avm_main_mem_idx_d = direct_cond_offset, + .avm_main_mem_op_a = 1, + .avm_main_mem_op_b = 1, + .avm_main_mem_op_c = 1, + .avm_main_mem_op_d = 1, + .avm_main_pc = pc++, + .avm_main_r_in_tag = static_cast(tag), + .avm_main_rwc = 1, + .avm_main_sel_cmov = 1, + .avm_main_sel_mov_a = static_cast(!id_zero), + .avm_main_sel_mov_b = static_cast(id_zero), .avm_main_tag_err = static_cast(!tag_match), .avm_main_w_in_tag = static_cast(tag), }); @@ -1267,7 +1374,9 @@ std::vector AvmTraceBuilder::finalize() dest.avm_mem_tag = FF(static_cast(src.m_tag)); dest.avm_mem_tag_err = FF(static_cast(src.m_tag_err)); dest.avm_mem_one_min_inv = src.m_one_min_inv; - dest.avm_mem_sel_mov = FF(static_cast(src.m_sel_mov)); + dest.avm_mem_sel_mov_a = FF(static_cast(src.m_sel_mov_a)); + dest.avm_mem_sel_mov_b = FF(static_cast(src.m_sel_mov_b)); + dest.avm_mem_sel_cmov = FF(static_cast(src.m_sel_cmov)); dest.incl_mem_tag_err_counts = FF(static_cast(src.m_tag_err_count_relevant)); @@ -1284,6 +1393,10 @@ std::vector AvmTraceBuilder::finalize() case AvmMemTraceBuilder::SUB_CLK_STORE_C: dest.avm_mem_op_c = 1; break; + case AvmMemTraceBuilder::SUB_CLK_LOAD_D: + case AvmMemTraceBuilder::SUB_CLK_STORE_D: + dest.avm_mem_op_d = 1; + break; case AvmMemTraceBuilder::SUB_CLK_IND_LOAD_A: dest.avm_mem_ind_op_a = 1; break; @@ -1293,10 +1406,18 @@ std::vector AvmTraceBuilder::finalize() case AvmMemTraceBuilder::SUB_CLK_IND_LOAD_C: dest.avm_mem_ind_op_c = 1; break; + case AvmMemTraceBuilder::SUB_CLK_IND_LOAD_D: + dest.avm_mem_ind_op_d = 1; + break; default: break; } + if (src.m_sel_cmov) { + dest.avm_mem_skip_check_tag = dest.avm_mem_op_d + dest.avm_mem_op_a * (-dest.avm_mem_sel_mov_a + 1) + + dest.avm_mem_op_b * (-dest.avm_mem_sel_mov_b + 1); + } + if (i + 1 < mem_trace_size) { auto const& next = mem_trace.at(i + 1); dest.avm_mem_lastAccess = FF(static_cast(src.m_addr != next.m_addr)); @@ -1429,16 +1550,6 @@ std::vector AvmTraceBuilder::finalize() } } - // Deriving redundant selectors/tags for the main trace. - for (Row& r : main_trace) { - if ((r.avm_main_sel_op_add == FF(1) || r.avm_main_sel_op_sub == FF(1) || r.avm_main_sel_op_mul == FF(1) || - r.avm_main_sel_op_eq == FF(1) || r.avm_main_sel_op_not == FF(1) || r.avm_main_sel_op_lt || - r.avm_main_sel_op_lte) && - r.avm_main_tag_err == FF(0)) { - r.avm_main_alu_sel = FF(1); - } - } - // Add Binary Trace table for (size_t i = 0; i < bin_trace_size; i++) { auto const& src = bin_trace.at(i); 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 4d65afdc45c..c4e72a0c3ff 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -68,6 +68,10 @@ class AvmTraceBuilder { // Move (copy) the value and tag of a memory cell to another one. void op_mov(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset); + // Move (copy) the value and tag of a memory cell to another one whereby the source + // is determined conditionally based on a conditional value determined by cond_offset. + void op_cmov(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t cond_offset, uint32_t dst_offset); + // Jump to a given program counter. void jump(uint32_t jmp_dest); @@ -101,7 +105,7 @@ class AvmTraceBuilder { bool tag_match = false; uint32_t direct_a_offset; uint32_t direct_b_offset; - uint32_t direct_dst_offset; + uint32_t direct_c_offset; bool indirect_flag_a = false; bool indirect_flag_b = false; @@ -118,7 +122,7 @@ class AvmTraceBuilder { void finalise_mem_trace_lookup_counts(); IndirectThreeResolution resolve_ind_three( - uint32_t clk, uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset); + uint32_t clk, uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t c_offset); uint32_t pc = 0; uint32_t internal_return_ptr = CALLSTACK_OFFSET; diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp index 42e931cbdf3..fe2b81f0e34 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -41,9 +41,11 @@ #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_d.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/relations/generated/avm/perm_main_mem_ind_d.hpp" #include "barretenberg/vm/generated/avm_flavor.hpp" namespace bb { @@ -134,32 +136,42 @@ template struct AvmFullRow { FF avm_main_ia{}; FF avm_main_ib{}; FF avm_main_ic{}; + FF avm_main_id{}; + FF avm_main_id_zero{}; FF avm_main_ind_a{}; FF avm_main_ind_b{}; FF avm_main_ind_c{}; + FF avm_main_ind_d{}; FF avm_main_ind_op_a{}; FF avm_main_ind_op_b{}; FF avm_main_ind_op_c{}; + FF avm_main_ind_op_d{}; FF avm_main_internal_return_ptr{}; FF avm_main_inv{}; FF avm_main_last{}; FF avm_main_mem_idx_a{}; FF avm_main_mem_idx_b{}; FF avm_main_mem_idx_c{}; + FF avm_main_mem_idx_d{}; FF avm_main_mem_op_a{}; FF avm_main_mem_op_b{}; FF avm_main_mem_op_c{}; + FF avm_main_mem_op_d{}; FF avm_main_op_err{}; FF avm_main_pc{}; FF avm_main_r_in_tag{}; FF avm_main_rwa{}; FF avm_main_rwb{}; FF avm_main_rwc{}; + FF avm_main_rwd{}; + FF avm_main_sel_cmov{}; FF avm_main_sel_halt{}; FF avm_main_sel_internal_call{}; FF avm_main_sel_internal_return{}; FF avm_main_sel_jump{}; FF avm_main_sel_mov{}; + FF avm_main_sel_mov_a{}; + FF avm_main_sel_mov_b{}; FF avm_main_sel_op_add{}; FF avm_main_sel_op_and{}; FF avm_main_sel_op_div{}; @@ -180,15 +192,20 @@ template struct AvmFullRow { FF avm_mem_ind_op_a{}; FF avm_mem_ind_op_b{}; FF avm_mem_ind_op_c{}; + FF avm_mem_ind_op_d{}; FF avm_mem_last{}; FF avm_mem_lastAccess{}; FF avm_mem_one_min_inv{}; FF avm_mem_op_a{}; FF avm_mem_op_b{}; FF avm_mem_op_c{}; + FF avm_mem_op_d{}; FF avm_mem_r_in_tag{}; FF avm_mem_rw{}; - FF avm_mem_sel_mov{}; + FF avm_mem_sel_cmov{}; + FF avm_mem_sel_mov_a{}; + FF avm_mem_sel_mov_b{}; + FF avm_mem_skip_check_tag{}; FF avm_mem_sub_clk{}; FF avm_mem_tag{}; FF avm_mem_tag_err{}; @@ -199,9 +216,11 @@ template struct AvmFullRow { FF perm_main_mem_a{}; FF perm_main_mem_b{}; FF perm_main_mem_c{}; + FF perm_main_mem_d{}; FF perm_main_mem_ind_a{}; FF perm_main_mem_ind_b{}; FF perm_main_mem_ind_c{}; + FF perm_main_mem_ind_d{}; FF lookup_byte_lengths{}; FF lookup_byte_operations{}; FF incl_main_tag_err{}; @@ -285,8 +304,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 224; - static constexpr size_t num_polys = 195; + static constexpr size_t num_fixed_columns = 241; + static constexpr size_t num_polys = 212; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -387,32 +406,42 @@ class AvmCircuitBuilder { polys.avm_main_ia[i] = rows[i].avm_main_ia; polys.avm_main_ib[i] = rows[i].avm_main_ib; polys.avm_main_ic[i] = rows[i].avm_main_ic; + polys.avm_main_id[i] = rows[i].avm_main_id; + polys.avm_main_id_zero[i] = rows[i].avm_main_id_zero; 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_d[i] = rows[i].avm_main_ind_d; 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_ind_op_d[i] = rows[i].avm_main_ind_op_d; polys.avm_main_internal_return_ptr[i] = rows[i].avm_main_internal_return_ptr; polys.avm_main_inv[i] = rows[i].avm_main_inv; polys.avm_main_last[i] = rows[i].avm_main_last; 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; + polys.avm_main_mem_idx_d[i] = rows[i].avm_main_mem_idx_d; polys.avm_main_mem_op_a[i] = rows[i].avm_main_mem_op_a; polys.avm_main_mem_op_b[i] = rows[i].avm_main_mem_op_b; polys.avm_main_mem_op_c[i] = rows[i].avm_main_mem_op_c; + polys.avm_main_mem_op_d[i] = rows[i].avm_main_mem_op_d; polys.avm_main_op_err[i] = rows[i].avm_main_op_err; polys.avm_main_pc[i] = rows[i].avm_main_pc; polys.avm_main_r_in_tag[i] = rows[i].avm_main_r_in_tag; 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_rwd[i] = rows[i].avm_main_rwd; + polys.avm_main_sel_cmov[i] = rows[i].avm_main_sel_cmov; polys.avm_main_sel_halt[i] = rows[i].avm_main_sel_halt; polys.avm_main_sel_internal_call[i] = rows[i].avm_main_sel_internal_call; polys.avm_main_sel_internal_return[i] = rows[i].avm_main_sel_internal_return; polys.avm_main_sel_jump[i] = rows[i].avm_main_sel_jump; polys.avm_main_sel_mov[i] = rows[i].avm_main_sel_mov; + polys.avm_main_sel_mov_a[i] = rows[i].avm_main_sel_mov_a; + polys.avm_main_sel_mov_b[i] = rows[i].avm_main_sel_mov_b; polys.avm_main_sel_op_add[i] = rows[i].avm_main_sel_op_add; polys.avm_main_sel_op_and[i] = rows[i].avm_main_sel_op_and; polys.avm_main_sel_op_div[i] = rows[i].avm_main_sel_op_div; @@ -433,15 +462,20 @@ class AvmCircuitBuilder { polys.avm_mem_ind_op_a[i] = rows[i].avm_mem_ind_op_a; polys.avm_mem_ind_op_b[i] = rows[i].avm_mem_ind_op_b; polys.avm_mem_ind_op_c[i] = rows[i].avm_mem_ind_op_c; + polys.avm_mem_ind_op_d[i] = rows[i].avm_mem_ind_op_d; polys.avm_mem_last[i] = rows[i].avm_mem_last; polys.avm_mem_lastAccess[i] = rows[i].avm_mem_lastAccess; polys.avm_mem_one_min_inv[i] = rows[i].avm_mem_one_min_inv; polys.avm_mem_op_a[i] = rows[i].avm_mem_op_a; polys.avm_mem_op_b[i] = rows[i].avm_mem_op_b; polys.avm_mem_op_c[i] = rows[i].avm_mem_op_c; + polys.avm_mem_op_d[i] = rows[i].avm_mem_op_d; polys.avm_mem_r_in_tag[i] = rows[i].avm_mem_r_in_tag; polys.avm_mem_rw[i] = rows[i].avm_mem_rw; - polys.avm_mem_sel_mov[i] = rows[i].avm_mem_sel_mov; + polys.avm_mem_sel_cmov[i] = rows[i].avm_mem_sel_cmov; + polys.avm_mem_sel_mov_a[i] = rows[i].avm_mem_sel_mov_a; + polys.avm_mem_sel_mov_b[i] = rows[i].avm_mem_sel_mov_b; + polys.avm_mem_skip_check_tag[i] = rows[i].avm_mem_skip_check_tag; polys.avm_mem_sub_clk[i] = rows[i].avm_mem_sub_clk; polys.avm_mem_tag[i] = rows[i].avm_mem_tag; polys.avm_mem_tag_err[i] = rows[i].avm_mem_tag_err; @@ -602,6 +636,9 @@ class AvmCircuitBuilder { if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_C")) { return false; } + if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_D")) { + return false; + } if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_IND_A")) { return false; } @@ -611,6 +648,9 @@ class AvmCircuitBuilder { if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_IND_C")) { return false; } + if (!evaluate_logderivative.template operator()>("PERM_MAIN_MEM_IND_D")) { + return false; + } if (!evaluate_logderivative.template operator()>("LOOKUP_BYTE_LENGTHS")) { return false; } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index 353ee278c6f..0964aa33632 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -43,9 +43,11 @@ #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_d.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/relations/generated/avm/perm_main_mem_ind_d.hpp" #include "barretenberg/transcript/transcript.hpp" namespace bb { @@ -67,20 +69,22 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 193; + static constexpr size_t NUM_WITNESS_ENTITIES = 210; 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 = 224; + static constexpr size_t NUM_ALL_ENTITIES = 241; using GrandProductRelations = std::tuple, perm_main_bin_relation, perm_main_mem_a_relation, perm_main_mem_b_relation, perm_main_mem_c_relation, + perm_main_mem_d_relation, perm_main_mem_ind_a_relation, perm_main_mem_ind_b_relation, perm_main_mem_ind_c_relation, + perm_main_mem_ind_d_relation, lookup_byte_lengths_relation, lookup_byte_operations_relation, incl_main_tag_err_relation, @@ -112,9 +116,11 @@ class AvmFlavor { perm_main_mem_a_relation, perm_main_mem_b_relation, perm_main_mem_c_relation, + perm_main_mem_d_relation, perm_main_mem_ind_a_relation, perm_main_mem_ind_b_relation, perm_main_mem_ind_c_relation, + perm_main_mem_ind_d_relation, lookup_byte_lengths_relation, lookup_byte_operations_relation, incl_main_tag_err_relation, @@ -252,32 +258,42 @@ class AvmFlavor { avm_main_ia, avm_main_ib, avm_main_ic, + avm_main_id, + avm_main_id_zero, avm_main_ind_a, avm_main_ind_b, avm_main_ind_c, + avm_main_ind_d, avm_main_ind_op_a, avm_main_ind_op_b, avm_main_ind_op_c, + avm_main_ind_op_d, avm_main_internal_return_ptr, avm_main_inv, avm_main_last, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, + avm_main_mem_idx_d, avm_main_mem_op_a, avm_main_mem_op_b, avm_main_mem_op_c, + avm_main_mem_op_d, avm_main_op_err, avm_main_pc, avm_main_r_in_tag, avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_rwd, + avm_main_sel_cmov, avm_main_sel_halt, avm_main_sel_internal_call, avm_main_sel_internal_return, avm_main_sel_jump, avm_main_sel_mov, + avm_main_sel_mov_a, + avm_main_sel_mov_b, avm_main_sel_op_add, avm_main_sel_op_and, avm_main_sel_op_div, @@ -298,15 +314,20 @@ class AvmFlavor { avm_mem_ind_op_a, avm_mem_ind_op_b, avm_mem_ind_op_c, + avm_mem_ind_op_d, avm_mem_last, avm_mem_lastAccess, avm_mem_one_min_inv, avm_mem_op_a, avm_mem_op_b, avm_mem_op_c, + avm_mem_op_d, avm_mem_r_in_tag, avm_mem_rw, - avm_mem_sel_mov, + avm_mem_sel_cmov, + avm_mem_sel_mov_a, + avm_mem_sel_mov_b, + avm_mem_skip_check_tag, avm_mem_sub_clk, avm_mem_tag, avm_mem_tag_err, @@ -317,9 +338,11 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_d, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + perm_main_mem_ind_d, lookup_byte_lengths, lookup_byte_operations, incl_main_tag_err, @@ -448,32 +471,42 @@ class AvmFlavor { avm_main_ia, avm_main_ib, avm_main_ic, + avm_main_id, + avm_main_id_zero, avm_main_ind_a, avm_main_ind_b, avm_main_ind_c, + avm_main_ind_d, avm_main_ind_op_a, avm_main_ind_op_b, avm_main_ind_op_c, + avm_main_ind_op_d, avm_main_internal_return_ptr, avm_main_inv, avm_main_last, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, + avm_main_mem_idx_d, avm_main_mem_op_a, avm_main_mem_op_b, avm_main_mem_op_c, + avm_main_mem_op_d, avm_main_op_err, avm_main_pc, avm_main_r_in_tag, avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_rwd, + avm_main_sel_cmov, avm_main_sel_halt, avm_main_sel_internal_call, avm_main_sel_internal_return, avm_main_sel_jump, avm_main_sel_mov, + avm_main_sel_mov_a, + avm_main_sel_mov_b, avm_main_sel_op_add, avm_main_sel_op_and, avm_main_sel_op_div, @@ -494,15 +527,20 @@ class AvmFlavor { avm_mem_ind_op_a, avm_mem_ind_op_b, avm_mem_ind_op_c, + avm_mem_ind_op_d, avm_mem_last, avm_mem_lastAccess, avm_mem_one_min_inv, avm_mem_op_a, avm_mem_op_b, avm_mem_op_c, + avm_mem_op_d, avm_mem_r_in_tag, avm_mem_rw, - avm_mem_sel_mov, + avm_mem_sel_cmov, + avm_mem_sel_mov_a, + avm_mem_sel_mov_b, + avm_mem_skip_check_tag, avm_mem_sub_clk, avm_mem_tag, avm_mem_tag_err, @@ -513,9 +551,11 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_d, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + perm_main_mem_ind_d, lookup_byte_lengths, lookup_byte_operations, incl_main_tag_err, @@ -649,32 +689,42 @@ class AvmFlavor { avm_main_ia, avm_main_ib, avm_main_ic, + avm_main_id, + avm_main_id_zero, avm_main_ind_a, avm_main_ind_b, avm_main_ind_c, + avm_main_ind_d, avm_main_ind_op_a, avm_main_ind_op_b, avm_main_ind_op_c, + avm_main_ind_op_d, avm_main_internal_return_ptr, avm_main_inv, avm_main_last, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, + avm_main_mem_idx_d, avm_main_mem_op_a, avm_main_mem_op_b, avm_main_mem_op_c, + avm_main_mem_op_d, avm_main_op_err, avm_main_pc, avm_main_r_in_tag, avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_rwd, + avm_main_sel_cmov, avm_main_sel_halt, avm_main_sel_internal_call, avm_main_sel_internal_return, avm_main_sel_jump, avm_main_sel_mov, + avm_main_sel_mov_a, + avm_main_sel_mov_b, avm_main_sel_op_add, avm_main_sel_op_and, avm_main_sel_op_div, @@ -695,15 +745,20 @@ class AvmFlavor { avm_mem_ind_op_a, avm_mem_ind_op_b, avm_mem_ind_op_c, + avm_mem_ind_op_d, avm_mem_last, avm_mem_lastAccess, avm_mem_one_min_inv, avm_mem_op_a, avm_mem_op_b, avm_mem_op_c, + avm_mem_op_d, avm_mem_r_in_tag, avm_mem_rw, - avm_mem_sel_mov, + avm_mem_sel_cmov, + avm_mem_sel_mov_a, + avm_mem_sel_mov_b, + avm_mem_skip_check_tag, avm_mem_sub_clk, avm_mem_tag, avm_mem_tag_err, @@ -714,9 +769,11 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_d, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + perm_main_mem_ind_d, lookup_byte_lengths, lookup_byte_operations, incl_main_tag_err, @@ -876,32 +933,42 @@ class AvmFlavor { avm_main_ia, avm_main_ib, avm_main_ic, + avm_main_id, + avm_main_id_zero, avm_main_ind_a, avm_main_ind_b, avm_main_ind_c, + avm_main_ind_d, avm_main_ind_op_a, avm_main_ind_op_b, avm_main_ind_op_c, + avm_main_ind_op_d, avm_main_internal_return_ptr, avm_main_inv, avm_main_last, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, + avm_main_mem_idx_d, avm_main_mem_op_a, avm_main_mem_op_b, avm_main_mem_op_c, + avm_main_mem_op_d, avm_main_op_err, avm_main_pc, avm_main_r_in_tag, avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_rwd, + avm_main_sel_cmov, avm_main_sel_halt, avm_main_sel_internal_call, avm_main_sel_internal_return, avm_main_sel_jump, avm_main_sel_mov, + avm_main_sel_mov_a, + avm_main_sel_mov_b, avm_main_sel_op_add, avm_main_sel_op_and, avm_main_sel_op_div, @@ -922,15 +989,20 @@ class AvmFlavor { avm_mem_ind_op_a, avm_mem_ind_op_b, avm_mem_ind_op_c, + avm_mem_ind_op_d, avm_mem_last, avm_mem_lastAccess, avm_mem_one_min_inv, avm_mem_op_a, avm_mem_op_b, avm_mem_op_c, + avm_mem_op_d, avm_mem_r_in_tag, avm_mem_rw, - avm_mem_sel_mov, + avm_mem_sel_cmov, + avm_mem_sel_mov_a, + avm_mem_sel_mov_b, + avm_mem_skip_check_tag, avm_mem_sub_clk, avm_mem_tag, avm_mem_tag_err, @@ -941,9 +1013,11 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_d, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + perm_main_mem_ind_d, lookup_byte_lengths, lookup_byte_operations, incl_main_tag_err, @@ -1103,32 +1177,42 @@ class AvmFlavor { avm_main_ia, avm_main_ib, avm_main_ic, + avm_main_id, + avm_main_id_zero, avm_main_ind_a, avm_main_ind_b, avm_main_ind_c, + avm_main_ind_d, avm_main_ind_op_a, avm_main_ind_op_b, avm_main_ind_op_c, + avm_main_ind_op_d, avm_main_internal_return_ptr, avm_main_inv, avm_main_last, avm_main_mem_idx_a, avm_main_mem_idx_b, avm_main_mem_idx_c, + avm_main_mem_idx_d, avm_main_mem_op_a, avm_main_mem_op_b, avm_main_mem_op_c, + avm_main_mem_op_d, avm_main_op_err, avm_main_pc, avm_main_r_in_tag, avm_main_rwa, avm_main_rwb, avm_main_rwc, + avm_main_rwd, + avm_main_sel_cmov, avm_main_sel_halt, avm_main_sel_internal_call, avm_main_sel_internal_return, avm_main_sel_jump, avm_main_sel_mov, + avm_main_sel_mov_a, + avm_main_sel_mov_b, avm_main_sel_op_add, avm_main_sel_op_and, avm_main_sel_op_div, @@ -1149,15 +1233,20 @@ class AvmFlavor { avm_mem_ind_op_a, avm_mem_ind_op_b, avm_mem_ind_op_c, + avm_mem_ind_op_d, avm_mem_last, avm_mem_lastAccess, avm_mem_one_min_inv, avm_mem_op_a, avm_mem_op_b, avm_mem_op_c, + avm_mem_op_d, avm_mem_r_in_tag, avm_mem_rw, - avm_mem_sel_mov, + avm_mem_sel_cmov, + avm_mem_sel_mov_a, + avm_mem_sel_mov_b, + avm_mem_skip_check_tag, avm_mem_sub_clk, avm_mem_tag, avm_mem_tag_err, @@ -1168,9 +1257,11 @@ class AvmFlavor { perm_main_mem_a, perm_main_mem_b, perm_main_mem_c, + perm_main_mem_d, perm_main_mem_ind_a, perm_main_mem_ind_b, perm_main_mem_ind_c, + perm_main_mem_ind_d, lookup_byte_lengths, lookup_byte_operations, incl_main_tag_err, @@ -1278,12 +1369,16 @@ class AvmFlavor { prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( @@ -1503,32 +1598,42 @@ class AvmFlavor { Base::avm_main_ia = "AVM_MAIN_IA"; Base::avm_main_ib = "AVM_MAIN_IB"; Base::avm_main_ic = "AVM_MAIN_IC"; + Base::avm_main_id = "AVM_MAIN_ID"; + Base::avm_main_id_zero = "AVM_MAIN_ID_ZERO"; 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_d = "AVM_MAIN_IND_D"; 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_ind_op_d = "AVM_MAIN_IND_OP_D"; Base::avm_main_internal_return_ptr = "AVM_MAIN_INTERNAL_RETURN_PTR"; Base::avm_main_inv = "AVM_MAIN_INV"; Base::avm_main_last = "AVM_MAIN_LAST"; 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"; + Base::avm_main_mem_idx_d = "AVM_MAIN_MEM_IDX_D"; Base::avm_main_mem_op_a = "AVM_MAIN_MEM_OP_A"; Base::avm_main_mem_op_b = "AVM_MAIN_MEM_OP_B"; Base::avm_main_mem_op_c = "AVM_MAIN_MEM_OP_C"; + Base::avm_main_mem_op_d = "AVM_MAIN_MEM_OP_D"; Base::avm_main_op_err = "AVM_MAIN_OP_ERR"; Base::avm_main_pc = "AVM_MAIN_PC"; Base::avm_main_r_in_tag = "AVM_MAIN_R_IN_TAG"; Base::avm_main_rwa = "AVM_MAIN_RWA"; Base::avm_main_rwb = "AVM_MAIN_RWB"; Base::avm_main_rwc = "AVM_MAIN_RWC"; + Base::avm_main_rwd = "AVM_MAIN_RWD"; + Base::avm_main_sel_cmov = "AVM_MAIN_SEL_CMOV"; Base::avm_main_sel_halt = "AVM_MAIN_SEL_HALT"; Base::avm_main_sel_internal_call = "AVM_MAIN_SEL_INTERNAL_CALL"; Base::avm_main_sel_internal_return = "AVM_MAIN_SEL_INTERNAL_RETURN"; Base::avm_main_sel_jump = "AVM_MAIN_SEL_JUMP"; Base::avm_main_sel_mov = "AVM_MAIN_SEL_MOV"; + Base::avm_main_sel_mov_a = "AVM_MAIN_SEL_MOV_A"; + Base::avm_main_sel_mov_b = "AVM_MAIN_SEL_MOV_B"; Base::avm_main_sel_op_add = "AVM_MAIN_SEL_OP_ADD"; Base::avm_main_sel_op_and = "AVM_MAIN_SEL_OP_AND"; Base::avm_main_sel_op_div = "AVM_MAIN_SEL_OP_DIV"; @@ -1549,15 +1654,20 @@ class AvmFlavor { Base::avm_mem_ind_op_a = "AVM_MEM_IND_OP_A"; Base::avm_mem_ind_op_b = "AVM_MEM_IND_OP_B"; Base::avm_mem_ind_op_c = "AVM_MEM_IND_OP_C"; + Base::avm_mem_ind_op_d = "AVM_MEM_IND_OP_D"; Base::avm_mem_last = "AVM_MEM_LAST"; Base::avm_mem_lastAccess = "AVM_MEM_LASTACCESS"; Base::avm_mem_one_min_inv = "AVM_MEM_ONE_MIN_INV"; Base::avm_mem_op_a = "AVM_MEM_OP_A"; Base::avm_mem_op_b = "AVM_MEM_OP_B"; Base::avm_mem_op_c = "AVM_MEM_OP_C"; + Base::avm_mem_op_d = "AVM_MEM_OP_D"; Base::avm_mem_r_in_tag = "AVM_MEM_R_IN_TAG"; Base::avm_mem_rw = "AVM_MEM_RW"; - Base::avm_mem_sel_mov = "AVM_MEM_SEL_MOV"; + Base::avm_mem_sel_cmov = "AVM_MEM_SEL_CMOV"; + Base::avm_mem_sel_mov_a = "AVM_MEM_SEL_MOV_A"; + Base::avm_mem_sel_mov_b = "AVM_MEM_SEL_MOV_B"; + Base::avm_mem_skip_check_tag = "AVM_MEM_SKIP_CHECK_TAG"; Base::avm_mem_sub_clk = "AVM_MEM_SUB_CLK"; Base::avm_mem_tag = "AVM_MEM_TAG"; Base::avm_mem_tag_err = "AVM_MEM_TAG_ERR"; @@ -1568,9 +1678,11 @@ 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_d = "PERM_MAIN_MEM_D"; 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::perm_main_mem_ind_d = "PERM_MAIN_MEM_IND_D"; Base::lookup_byte_lengths = "LOOKUP_BYTE_LENGTHS"; Base::lookup_byte_operations = "LOOKUP_BYTE_OPERATIONS"; Base::incl_main_tag_err = "INCL_MAIN_TAG_ERR"; @@ -1715,32 +1827,42 @@ class AvmFlavor { Commitment avm_main_ia; Commitment avm_main_ib; Commitment avm_main_ic; + Commitment avm_main_id; + Commitment avm_main_id_zero; Commitment avm_main_ind_a; Commitment avm_main_ind_b; Commitment avm_main_ind_c; + Commitment avm_main_ind_d; Commitment avm_main_ind_op_a; Commitment avm_main_ind_op_b; Commitment avm_main_ind_op_c; + Commitment avm_main_ind_op_d; Commitment avm_main_internal_return_ptr; Commitment avm_main_inv; Commitment avm_main_last; Commitment avm_main_mem_idx_a; Commitment avm_main_mem_idx_b; Commitment avm_main_mem_idx_c; + Commitment avm_main_mem_idx_d; Commitment avm_main_mem_op_a; Commitment avm_main_mem_op_b; Commitment avm_main_mem_op_c; + Commitment avm_main_mem_op_d; Commitment avm_main_op_err; Commitment avm_main_pc; Commitment avm_main_r_in_tag; Commitment avm_main_rwa; Commitment avm_main_rwb; Commitment avm_main_rwc; + Commitment avm_main_rwd; + Commitment avm_main_sel_cmov; Commitment avm_main_sel_halt; Commitment avm_main_sel_internal_call; Commitment avm_main_sel_internal_return; Commitment avm_main_sel_jump; Commitment avm_main_sel_mov; + Commitment avm_main_sel_mov_a; + Commitment avm_main_sel_mov_b; Commitment avm_main_sel_op_add; Commitment avm_main_sel_op_and; Commitment avm_main_sel_op_div; @@ -1761,15 +1883,20 @@ class AvmFlavor { Commitment avm_mem_ind_op_a; Commitment avm_mem_ind_op_b; Commitment avm_mem_ind_op_c; + Commitment avm_mem_ind_op_d; Commitment avm_mem_last; Commitment avm_mem_lastAccess; Commitment avm_mem_one_min_inv; Commitment avm_mem_op_a; Commitment avm_mem_op_b; Commitment avm_mem_op_c; + Commitment avm_mem_op_d; Commitment avm_mem_r_in_tag; Commitment avm_mem_rw; - Commitment avm_mem_sel_mov; + Commitment avm_mem_sel_cmov; + Commitment avm_mem_sel_mov_a; + Commitment avm_mem_sel_mov_b; + Commitment avm_mem_skip_check_tag; Commitment avm_mem_sub_clk; Commitment avm_mem_tag; Commitment avm_mem_tag_err; @@ -1780,9 +1907,11 @@ class AvmFlavor { Commitment perm_main_mem_a; Commitment perm_main_mem_b; Commitment perm_main_mem_c; + Commitment perm_main_mem_d; Commitment perm_main_mem_ind_a; Commitment perm_main_mem_ind_b; Commitment perm_main_mem_ind_c; + Commitment perm_main_mem_ind_d; Commitment lookup_byte_lengths; Commitment lookup_byte_operations; Commitment incl_main_tag_err; @@ -1928,32 +2057,42 @@ class AvmFlavor { avm_main_ia = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_ib = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_ic = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_id = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_id_zero = 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_d = 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_ind_op_d = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_internal_return_ptr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_inv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_last = 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); + avm_main_mem_idx_d = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_mem_op_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_mem_op_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_mem_op_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_mem_op_d = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_op_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_pc = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_r_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_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_rwd = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_cmov = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_halt = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_internal_call = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_internal_return = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_jump = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_mov = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_mov_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_mov_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_add = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_and = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_div = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1974,15 +2113,20 @@ class AvmFlavor { avm_mem_ind_op_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_ind_op_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_ind_op_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_ind_op_d = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_last = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_lastAccess = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_one_min_inv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_op_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_op_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_op_c = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_op_d = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_r_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_rw = deserialize_from_buffer(Transcript::proof_data, num_frs_read); - avm_mem_sel_mov = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_sel_cmov = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_sel_mov_a = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_sel_mov_b = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_skip_check_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_sub_clk = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1993,9 +2137,11 @@ 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_d = 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); + perm_main_mem_ind_d = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_byte_lengths = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_byte_operations = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_main_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2144,32 +2290,42 @@ class AvmFlavor { serialize_to_buffer(avm_main_ia, Transcript::proof_data); serialize_to_buffer(avm_main_ib, Transcript::proof_data); serialize_to_buffer(avm_main_ic, Transcript::proof_data); + serialize_to_buffer(avm_main_id, Transcript::proof_data); + serialize_to_buffer(avm_main_id_zero, 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_d, 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_ind_op_d, Transcript::proof_data); serialize_to_buffer(avm_main_internal_return_ptr, Transcript::proof_data); serialize_to_buffer(avm_main_inv, Transcript::proof_data); serialize_to_buffer(avm_main_last, 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); + serialize_to_buffer(avm_main_mem_idx_d, Transcript::proof_data); serialize_to_buffer(avm_main_mem_op_a, Transcript::proof_data); serialize_to_buffer(avm_main_mem_op_b, Transcript::proof_data); serialize_to_buffer(avm_main_mem_op_c, Transcript::proof_data); + serialize_to_buffer(avm_main_mem_op_d, Transcript::proof_data); serialize_to_buffer(avm_main_op_err, Transcript::proof_data); serialize_to_buffer(avm_main_pc, Transcript::proof_data); serialize_to_buffer(avm_main_r_in_tag, Transcript::proof_data); 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_rwd, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_cmov, Transcript::proof_data); serialize_to_buffer(avm_main_sel_halt, Transcript::proof_data); serialize_to_buffer(avm_main_sel_internal_call, Transcript::proof_data); serialize_to_buffer(avm_main_sel_internal_return, Transcript::proof_data); serialize_to_buffer(avm_main_sel_jump, Transcript::proof_data); serialize_to_buffer(avm_main_sel_mov, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_mov_a, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_mov_b, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_add, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_and, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_div, Transcript::proof_data); @@ -2190,15 +2346,20 @@ class AvmFlavor { serialize_to_buffer(avm_mem_ind_op_a, Transcript::proof_data); serialize_to_buffer(avm_mem_ind_op_b, Transcript::proof_data); serialize_to_buffer(avm_mem_ind_op_c, Transcript::proof_data); + serialize_to_buffer(avm_mem_ind_op_d, Transcript::proof_data); serialize_to_buffer(avm_mem_last, Transcript::proof_data); serialize_to_buffer(avm_mem_lastAccess, Transcript::proof_data); serialize_to_buffer(avm_mem_one_min_inv, Transcript::proof_data); serialize_to_buffer(avm_mem_op_a, Transcript::proof_data); serialize_to_buffer(avm_mem_op_b, Transcript::proof_data); serialize_to_buffer(avm_mem_op_c, Transcript::proof_data); + serialize_to_buffer(avm_mem_op_d, Transcript::proof_data); serialize_to_buffer(avm_mem_r_in_tag, Transcript::proof_data); serialize_to_buffer(avm_mem_rw, Transcript::proof_data); - serialize_to_buffer(avm_mem_sel_mov, Transcript::proof_data); + serialize_to_buffer(avm_mem_sel_cmov, Transcript::proof_data); + serialize_to_buffer(avm_mem_sel_mov_a, Transcript::proof_data); + serialize_to_buffer(avm_mem_sel_mov_b, Transcript::proof_data); + serialize_to_buffer(avm_mem_skip_check_tag, Transcript::proof_data); serialize_to_buffer(avm_mem_sub_clk, Transcript::proof_data); serialize_to_buffer(avm_mem_tag, Transcript::proof_data); serialize_to_buffer(avm_mem_tag_err, Transcript::proof_data); @@ -2209,9 +2370,11 @@ 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_d, 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(perm_main_mem_ind_d, Transcript::proof_data); serialize_to_buffer(lookup_byte_lengths, Transcript::proof_data); serialize_to_buffer(lookup_byte_operations, Transcript::proof_data); serialize_to_buffer(incl_main_tag_err, Transcript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp index 6d1bacc8d97..f204511330f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp @@ -143,32 +143,42 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_main_ia = commitment_key->commit(key->avm_main_ia); witness_commitments.avm_main_ib = commitment_key->commit(key->avm_main_ib); witness_commitments.avm_main_ic = commitment_key->commit(key->avm_main_ic); + witness_commitments.avm_main_id = commitment_key->commit(key->avm_main_id); + witness_commitments.avm_main_id_zero = commitment_key->commit(key->avm_main_id_zero); witness_commitments.avm_main_ind_a = commitment_key->commit(key->avm_main_ind_a); witness_commitments.avm_main_ind_b = commitment_key->commit(key->avm_main_ind_b); witness_commitments.avm_main_ind_c = commitment_key->commit(key->avm_main_ind_c); + witness_commitments.avm_main_ind_d = commitment_key->commit(key->avm_main_ind_d); witness_commitments.avm_main_ind_op_a = commitment_key->commit(key->avm_main_ind_op_a); witness_commitments.avm_main_ind_op_b = commitment_key->commit(key->avm_main_ind_op_b); witness_commitments.avm_main_ind_op_c = commitment_key->commit(key->avm_main_ind_op_c); + witness_commitments.avm_main_ind_op_d = commitment_key->commit(key->avm_main_ind_op_d); witness_commitments.avm_main_internal_return_ptr = commitment_key->commit(key->avm_main_internal_return_ptr); witness_commitments.avm_main_inv = commitment_key->commit(key->avm_main_inv); witness_commitments.avm_main_last = commitment_key->commit(key->avm_main_last); witness_commitments.avm_main_mem_idx_a = commitment_key->commit(key->avm_main_mem_idx_a); witness_commitments.avm_main_mem_idx_b = commitment_key->commit(key->avm_main_mem_idx_b); witness_commitments.avm_main_mem_idx_c = commitment_key->commit(key->avm_main_mem_idx_c); + witness_commitments.avm_main_mem_idx_d = commitment_key->commit(key->avm_main_mem_idx_d); witness_commitments.avm_main_mem_op_a = commitment_key->commit(key->avm_main_mem_op_a); witness_commitments.avm_main_mem_op_b = commitment_key->commit(key->avm_main_mem_op_b); witness_commitments.avm_main_mem_op_c = commitment_key->commit(key->avm_main_mem_op_c); + witness_commitments.avm_main_mem_op_d = commitment_key->commit(key->avm_main_mem_op_d); witness_commitments.avm_main_op_err = commitment_key->commit(key->avm_main_op_err); witness_commitments.avm_main_pc = commitment_key->commit(key->avm_main_pc); witness_commitments.avm_main_r_in_tag = commitment_key->commit(key->avm_main_r_in_tag); witness_commitments.avm_main_rwa = commitment_key->commit(key->avm_main_rwa); witness_commitments.avm_main_rwb = commitment_key->commit(key->avm_main_rwb); witness_commitments.avm_main_rwc = commitment_key->commit(key->avm_main_rwc); + witness_commitments.avm_main_rwd = commitment_key->commit(key->avm_main_rwd); + witness_commitments.avm_main_sel_cmov = commitment_key->commit(key->avm_main_sel_cmov); witness_commitments.avm_main_sel_halt = commitment_key->commit(key->avm_main_sel_halt); witness_commitments.avm_main_sel_internal_call = commitment_key->commit(key->avm_main_sel_internal_call); witness_commitments.avm_main_sel_internal_return = commitment_key->commit(key->avm_main_sel_internal_return); witness_commitments.avm_main_sel_jump = commitment_key->commit(key->avm_main_sel_jump); witness_commitments.avm_main_sel_mov = commitment_key->commit(key->avm_main_sel_mov); + witness_commitments.avm_main_sel_mov_a = commitment_key->commit(key->avm_main_sel_mov_a); + witness_commitments.avm_main_sel_mov_b = commitment_key->commit(key->avm_main_sel_mov_b); witness_commitments.avm_main_sel_op_add = commitment_key->commit(key->avm_main_sel_op_add); witness_commitments.avm_main_sel_op_and = commitment_key->commit(key->avm_main_sel_op_and); witness_commitments.avm_main_sel_op_div = commitment_key->commit(key->avm_main_sel_op_div); @@ -189,15 +199,20 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_mem_ind_op_a = commitment_key->commit(key->avm_mem_ind_op_a); witness_commitments.avm_mem_ind_op_b = commitment_key->commit(key->avm_mem_ind_op_b); witness_commitments.avm_mem_ind_op_c = commitment_key->commit(key->avm_mem_ind_op_c); + witness_commitments.avm_mem_ind_op_d = commitment_key->commit(key->avm_mem_ind_op_d); witness_commitments.avm_mem_last = commitment_key->commit(key->avm_mem_last); witness_commitments.avm_mem_lastAccess = commitment_key->commit(key->avm_mem_lastAccess); witness_commitments.avm_mem_one_min_inv = commitment_key->commit(key->avm_mem_one_min_inv); witness_commitments.avm_mem_op_a = commitment_key->commit(key->avm_mem_op_a); witness_commitments.avm_mem_op_b = commitment_key->commit(key->avm_mem_op_b); witness_commitments.avm_mem_op_c = commitment_key->commit(key->avm_mem_op_c); + witness_commitments.avm_mem_op_d = commitment_key->commit(key->avm_mem_op_d); witness_commitments.avm_mem_r_in_tag = commitment_key->commit(key->avm_mem_r_in_tag); witness_commitments.avm_mem_rw = commitment_key->commit(key->avm_mem_rw); - witness_commitments.avm_mem_sel_mov = commitment_key->commit(key->avm_mem_sel_mov); + witness_commitments.avm_mem_sel_cmov = commitment_key->commit(key->avm_mem_sel_cmov); + witness_commitments.avm_mem_sel_mov_a = commitment_key->commit(key->avm_mem_sel_mov_a); + witness_commitments.avm_mem_sel_mov_b = commitment_key->commit(key->avm_mem_sel_mov_b); + witness_commitments.avm_mem_skip_check_tag = commitment_key->commit(key->avm_mem_skip_check_tag); witness_commitments.avm_mem_sub_clk = commitment_key->commit(key->avm_mem_sub_clk); witness_commitments.avm_mem_tag = commitment_key->commit(key->avm_mem_tag); witness_commitments.avm_mem_tag_err = commitment_key->commit(key->avm_mem_tag_err); @@ -318,12 +333,16 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_main_ia, witness_commitments.avm_main_ia); transcript->send_to_verifier(commitment_labels.avm_main_ib, witness_commitments.avm_main_ib); transcript->send_to_verifier(commitment_labels.avm_main_ic, witness_commitments.avm_main_ic); + transcript->send_to_verifier(commitment_labels.avm_main_id, witness_commitments.avm_main_id); + transcript->send_to_verifier(commitment_labels.avm_main_id_zero, witness_commitments.avm_main_id_zero); transcript->send_to_verifier(commitment_labels.avm_main_ind_a, witness_commitments.avm_main_ind_a); transcript->send_to_verifier(commitment_labels.avm_main_ind_b, witness_commitments.avm_main_ind_b); transcript->send_to_verifier(commitment_labels.avm_main_ind_c, witness_commitments.avm_main_ind_c); + transcript->send_to_verifier(commitment_labels.avm_main_ind_d, witness_commitments.avm_main_ind_d); transcript->send_to_verifier(commitment_labels.avm_main_ind_op_a, witness_commitments.avm_main_ind_op_a); transcript->send_to_verifier(commitment_labels.avm_main_ind_op_b, witness_commitments.avm_main_ind_op_b); transcript->send_to_verifier(commitment_labels.avm_main_ind_op_c, witness_commitments.avm_main_ind_op_c); + transcript->send_to_verifier(commitment_labels.avm_main_ind_op_d, witness_commitments.avm_main_ind_op_d); transcript->send_to_verifier(commitment_labels.avm_main_internal_return_ptr, witness_commitments.avm_main_internal_return_ptr); transcript->send_to_verifier(commitment_labels.avm_main_inv, witness_commitments.avm_main_inv); @@ -331,15 +350,19 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_main_mem_idx_a, witness_commitments.avm_main_mem_idx_a); transcript->send_to_verifier(commitment_labels.avm_main_mem_idx_b, witness_commitments.avm_main_mem_idx_b); transcript->send_to_verifier(commitment_labels.avm_main_mem_idx_c, witness_commitments.avm_main_mem_idx_c); + transcript->send_to_verifier(commitment_labels.avm_main_mem_idx_d, witness_commitments.avm_main_mem_idx_d); transcript->send_to_verifier(commitment_labels.avm_main_mem_op_a, witness_commitments.avm_main_mem_op_a); transcript->send_to_verifier(commitment_labels.avm_main_mem_op_b, witness_commitments.avm_main_mem_op_b); transcript->send_to_verifier(commitment_labels.avm_main_mem_op_c, witness_commitments.avm_main_mem_op_c); + transcript->send_to_verifier(commitment_labels.avm_main_mem_op_d, witness_commitments.avm_main_mem_op_d); transcript->send_to_verifier(commitment_labels.avm_main_op_err, witness_commitments.avm_main_op_err); transcript->send_to_verifier(commitment_labels.avm_main_pc, witness_commitments.avm_main_pc); transcript->send_to_verifier(commitment_labels.avm_main_r_in_tag, witness_commitments.avm_main_r_in_tag); transcript->send_to_verifier(commitment_labels.avm_main_rwa, witness_commitments.avm_main_rwa); transcript->send_to_verifier(commitment_labels.avm_main_rwb, witness_commitments.avm_main_rwb); transcript->send_to_verifier(commitment_labels.avm_main_rwc, witness_commitments.avm_main_rwc); + transcript->send_to_verifier(commitment_labels.avm_main_rwd, witness_commitments.avm_main_rwd); + transcript->send_to_verifier(commitment_labels.avm_main_sel_cmov, witness_commitments.avm_main_sel_cmov); transcript->send_to_verifier(commitment_labels.avm_main_sel_halt, witness_commitments.avm_main_sel_halt); transcript->send_to_verifier(commitment_labels.avm_main_sel_internal_call, witness_commitments.avm_main_sel_internal_call); @@ -347,6 +370,8 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_main_sel_internal_return); transcript->send_to_verifier(commitment_labels.avm_main_sel_jump, witness_commitments.avm_main_sel_jump); transcript->send_to_verifier(commitment_labels.avm_main_sel_mov, witness_commitments.avm_main_sel_mov); + transcript->send_to_verifier(commitment_labels.avm_main_sel_mov_a, witness_commitments.avm_main_sel_mov_a); + transcript->send_to_verifier(commitment_labels.avm_main_sel_mov_b, witness_commitments.avm_main_sel_mov_b); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_add, witness_commitments.avm_main_sel_op_add); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_and, witness_commitments.avm_main_sel_op_and); transcript->send_to_verifier(commitment_labels.avm_main_sel_op_div, witness_commitments.avm_main_sel_op_div); @@ -367,15 +392,20 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_mem_ind_op_a, witness_commitments.avm_mem_ind_op_a); transcript->send_to_verifier(commitment_labels.avm_mem_ind_op_b, witness_commitments.avm_mem_ind_op_b); transcript->send_to_verifier(commitment_labels.avm_mem_ind_op_c, witness_commitments.avm_mem_ind_op_c); + transcript->send_to_verifier(commitment_labels.avm_mem_ind_op_d, witness_commitments.avm_mem_ind_op_d); transcript->send_to_verifier(commitment_labels.avm_mem_last, witness_commitments.avm_mem_last); transcript->send_to_verifier(commitment_labels.avm_mem_lastAccess, witness_commitments.avm_mem_lastAccess); transcript->send_to_verifier(commitment_labels.avm_mem_one_min_inv, witness_commitments.avm_mem_one_min_inv); transcript->send_to_verifier(commitment_labels.avm_mem_op_a, witness_commitments.avm_mem_op_a); transcript->send_to_verifier(commitment_labels.avm_mem_op_b, witness_commitments.avm_mem_op_b); transcript->send_to_verifier(commitment_labels.avm_mem_op_c, witness_commitments.avm_mem_op_c); + transcript->send_to_verifier(commitment_labels.avm_mem_op_d, witness_commitments.avm_mem_op_d); transcript->send_to_verifier(commitment_labels.avm_mem_r_in_tag, witness_commitments.avm_mem_r_in_tag); transcript->send_to_verifier(commitment_labels.avm_mem_rw, witness_commitments.avm_mem_rw); - transcript->send_to_verifier(commitment_labels.avm_mem_sel_mov, witness_commitments.avm_mem_sel_mov); + transcript->send_to_verifier(commitment_labels.avm_mem_sel_cmov, witness_commitments.avm_mem_sel_cmov); + transcript->send_to_verifier(commitment_labels.avm_mem_sel_mov_a, witness_commitments.avm_mem_sel_mov_a); + transcript->send_to_verifier(commitment_labels.avm_mem_sel_mov_b, witness_commitments.avm_mem_sel_mov_b); + transcript->send_to_verifier(commitment_labels.avm_mem_skip_check_tag, witness_commitments.avm_mem_skip_check_tag); transcript->send_to_verifier(commitment_labels.avm_mem_sub_clk, witness_commitments.avm_mem_sub_clk); transcript->send_to_verifier(commitment_labels.avm_mem_tag, witness_commitments.avm_mem_tag); transcript->send_to_verifier(commitment_labels.avm_mem_tag_err, witness_commitments.avm_mem_tag_err); @@ -423,9 +453,11 @@ void AvmProver::execute_log_derivative_inverse_round() witness_commitments.perm_main_mem_a = commitment_key->commit(key->perm_main_mem_a); witness_commitments.perm_main_mem_b = commitment_key->commit(key->perm_main_mem_b); witness_commitments.perm_main_mem_c = commitment_key->commit(key->perm_main_mem_c); + witness_commitments.perm_main_mem_d = commitment_key->commit(key->perm_main_mem_d); witness_commitments.perm_main_mem_ind_a = commitment_key->commit(key->perm_main_mem_ind_a); witness_commitments.perm_main_mem_ind_b = commitment_key->commit(key->perm_main_mem_ind_b); witness_commitments.perm_main_mem_ind_c = commitment_key->commit(key->perm_main_mem_ind_c); + witness_commitments.perm_main_mem_ind_d = commitment_key->commit(key->perm_main_mem_ind_d); witness_commitments.lookup_byte_lengths = commitment_key->commit(key->lookup_byte_lengths); witness_commitments.lookup_byte_operations = commitment_key->commit(key->lookup_byte_operations); witness_commitments.incl_main_tag_err = commitment_key->commit(key->incl_main_tag_err); @@ -454,9 +486,11 @@ void AvmProver::execute_log_derivative_inverse_round() transcript->send_to_verifier(commitment_labels.perm_main_mem_a, witness_commitments.perm_main_mem_a); transcript->send_to_verifier(commitment_labels.perm_main_mem_b, witness_commitments.perm_main_mem_b); transcript->send_to_verifier(commitment_labels.perm_main_mem_c, witness_commitments.perm_main_mem_c); + transcript->send_to_verifier(commitment_labels.perm_main_mem_d, witness_commitments.perm_main_mem_d); transcript->send_to_verifier(commitment_labels.perm_main_mem_ind_a, witness_commitments.perm_main_mem_ind_a); transcript->send_to_verifier(commitment_labels.perm_main_mem_ind_b, witness_commitments.perm_main_mem_ind_b); transcript->send_to_verifier(commitment_labels.perm_main_mem_ind_c, witness_commitments.perm_main_mem_ind_c); + transcript->send_to_verifier(commitment_labels.perm_main_mem_ind_d, witness_commitments.perm_main_mem_ind_d); transcript->send_to_verifier(commitment_labels.lookup_byte_lengths, witness_commitments.lookup_byte_lengths); transcript->send_to_verifier(commitment_labels.lookup_byte_operations, witness_commitments.lookup_byte_operations); transcript->send_to_verifier(commitment_labels.incl_main_tag_err, witness_commitments.incl_main_tag_err); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index aabdf2c2d6b..e195267791b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -177,15 +177,21 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) commitments.avm_main_ia = transcript->template receive_from_prover(commitment_labels.avm_main_ia); commitments.avm_main_ib = transcript->template receive_from_prover(commitment_labels.avm_main_ib); commitments.avm_main_ic = transcript->template receive_from_prover(commitment_labels.avm_main_ic); + commitments.avm_main_id = transcript->template receive_from_prover(commitment_labels.avm_main_id); + commitments.avm_main_id_zero = + transcript->template receive_from_prover(commitment_labels.avm_main_id_zero); 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_d = transcript->template receive_from_prover(commitment_labels.avm_main_ind_d); 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_ind_op_d = + transcript->template receive_from_prover(commitment_labels.avm_main_ind_op_d); commitments.avm_main_internal_return_ptr = transcript->template receive_from_prover(commitment_labels.avm_main_internal_return_ptr); commitments.avm_main_inv = transcript->template receive_from_prover(commitment_labels.avm_main_inv); @@ -196,12 +202,16 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_main_mem_idx_b); commitments.avm_main_mem_idx_c = transcript->template receive_from_prover(commitment_labels.avm_main_mem_idx_c); + commitments.avm_main_mem_idx_d = + transcript->template receive_from_prover(commitment_labels.avm_main_mem_idx_d); commitments.avm_main_mem_op_a = transcript->template receive_from_prover(commitment_labels.avm_main_mem_op_a); commitments.avm_main_mem_op_b = transcript->template receive_from_prover(commitment_labels.avm_main_mem_op_b); commitments.avm_main_mem_op_c = transcript->template receive_from_prover(commitment_labels.avm_main_mem_op_c); + commitments.avm_main_mem_op_d = + transcript->template receive_from_prover(commitment_labels.avm_main_mem_op_d); commitments.avm_main_op_err = transcript->template receive_from_prover(commitment_labels.avm_main_op_err); commitments.avm_main_pc = transcript->template receive_from_prover(commitment_labels.avm_main_pc); @@ -210,6 +220,9 @@ 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_rwd = transcript->template receive_from_prover(commitment_labels.avm_main_rwd); + commitments.avm_main_sel_cmov = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_cmov); commitments.avm_main_sel_halt = transcript->template receive_from_prover(commitment_labels.avm_main_sel_halt); commitments.avm_main_sel_internal_call = @@ -220,6 +233,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_main_sel_jump); commitments.avm_main_sel_mov = transcript->template receive_from_prover(commitment_labels.avm_main_sel_mov); + commitments.avm_main_sel_mov_a = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_mov_a); + commitments.avm_main_sel_mov_b = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_mov_b); commitments.avm_main_sel_op_add = transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_add); commitments.avm_main_sel_op_and = @@ -258,6 +275,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_mem_ind_op_b); commitments.avm_mem_ind_op_c = transcript->template receive_from_prover(commitment_labels.avm_mem_ind_op_c); + commitments.avm_mem_ind_op_d = + transcript->template receive_from_prover(commitment_labels.avm_mem_ind_op_d); commitments.avm_mem_last = transcript->template receive_from_prover(commitment_labels.avm_mem_last); commitments.avm_mem_lastAccess = transcript->template receive_from_prover(commitment_labels.avm_mem_lastAccess); @@ -266,11 +285,18 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) commitments.avm_mem_op_a = transcript->template receive_from_prover(commitment_labels.avm_mem_op_a); commitments.avm_mem_op_b = transcript->template receive_from_prover(commitment_labels.avm_mem_op_b); commitments.avm_mem_op_c = transcript->template receive_from_prover(commitment_labels.avm_mem_op_c); + commitments.avm_mem_op_d = transcript->template receive_from_prover(commitment_labels.avm_mem_op_d); commitments.avm_mem_r_in_tag = transcript->template receive_from_prover(commitment_labels.avm_mem_r_in_tag); commitments.avm_mem_rw = transcript->template receive_from_prover(commitment_labels.avm_mem_rw); - commitments.avm_mem_sel_mov = - transcript->template receive_from_prover(commitment_labels.avm_mem_sel_mov); + commitments.avm_mem_sel_cmov = + transcript->template receive_from_prover(commitment_labels.avm_mem_sel_cmov); + commitments.avm_mem_sel_mov_a = + transcript->template receive_from_prover(commitment_labels.avm_mem_sel_mov_a); + commitments.avm_mem_sel_mov_b = + transcript->template receive_from_prover(commitment_labels.avm_mem_sel_mov_b); + commitments.avm_mem_skip_check_tag = + transcript->template receive_from_prover(commitment_labels.avm_mem_skip_check_tag); commitments.avm_mem_sub_clk = transcript->template receive_from_prover(commitment_labels.avm_mem_sub_clk); commitments.avm_mem_tag = transcript->template receive_from_prover(commitment_labels.avm_mem_tag); @@ -335,12 +361,16 @@ 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_d = + transcript->template receive_from_prover(commitment_labels.perm_main_mem_d); 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.perm_main_mem_ind_d = + transcript->template receive_from_prover(commitment_labels.perm_main_mem_ind_d); commitments.lookup_byte_lengths = transcript->template receive_from_prover(commitment_labels.lookup_byte_lengths); commitments.lookup_byte_operations = 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 0feab83b36e..f505eb16ce5 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,62 @@ TEST_F(AvmExecutionTests, movOpcode) gen_proof_and_validate(bytecode, std::move(trace), {}); } +// Positive test with CMOV. +TEST_F(AvmExecutionTests, cmovOpcode) +{ + std::string bytecode_hex = to_hex(OpCode::SET) + // opcode SET + "00" // Indirect flag + "01" // U8 + "03" // val 3 + "00000010" // a_offset 16 + + to_hex(OpCode::SET) + // opcode SET + "00" // Indirect flag + "02" // U16 + "0004" // val 4 + "00000011" // b_offset 17 + + to_hex(OpCode::SET) + // opcode SET + "00" // Indirect flag + "03" // U32 + "00000005" // val 5 + "00000020" // cond_offset 32 + + to_hex(OpCode::CMOV) + // opcode CMOV + "00" // Indirect flag + "00000010" // a_offset 16 + "00000011" // b_offset 17 + "00000020" // cond_offset 32 + "00000012" // dst_offset 18 + + 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)); + + // CMOV + EXPECT_THAT(instructions.at(3), + AllOf(Field(&Instruction::op_code, OpCode::CMOV), + Field(&Instruction::operands, + ElementsAre(VariantWith(0), + VariantWith(16), + VariantWith(17), + VariantWith(32), + VariantWith(18))))); + + auto trace = Execution::gen_trace(instructions); + + // Find the first row enabling the CMOV selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_cmov == 1; }); + EXPECT_EQ(row->avm_main_ia, 3); + EXPECT_EQ(row->avm_main_ib, 4); + EXPECT_EQ(row->avm_main_ic, 3); + EXPECT_EQ(row->avm_main_id, 5); + + gen_proof_and_validate(bytecode, std::move(trace), {}); +} + // Positive test with indirect MOV. TEST_F(AvmExecutionTests, indMovOpcode) { 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 1e7d9a4530b..b02ee50d2ec 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 @@ -19,9 +19,13 @@ class AvmMemOpcodeTests : public ::testing::Test { std::vector trace; size_t main_idx; size_t mem_a_idx; + size_t mem_b_idx; size_t mem_c_idx; + size_t mem_d_idx; size_t mem_ind_a_idx; + size_t mem_ind_b_idx; size_t mem_ind_c_idx; + size_t mem_ind_d_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"); }; @@ -46,12 +50,42 @@ class AvmMemOpcodeTests : public ::testing::Test { trace = trace_builder.finalize(); } + void build_cmov_trace_neg_test(bool mov_a) + { + trace_builder.op_set(0, 1979, 10, AvmMemoryTag::U16); // a + trace_builder.op_set(0, 1980, 11, AvmMemoryTag::U16); // b + trace_builder.op_set(0, mov_a ? 9871 : 0, 20, AvmMemoryTag::U64); // Non-zero/zero condition value (we move a/b) + + trace_builder.op_cmov(0, 10, 11, 20, 12); + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_cmov_indices(0); + } + static std::function gen_matcher(FF clk, uint32_t sub_clk) { return [clk, sub_clk](Row r) { return r.avm_mem_clk == clk && r.avm_mem_sub_clk == sub_clk; }; }; - void compute_common_indices(FF clk, bool indirect) + void compute_index_a(FF clk, bool indirect) + { + // Find the memory trace position corresponding to the load sub-operation of register ia. + auto row = + std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_LOAD_A)); + ASSERT_TRUE(row != trace.end()); + mem_a_idx = static_cast(row - trace.begin()); + + // Find the memory trace position of the indirect load for register ia. + if (indirect) { + row = std::ranges::find_if( + trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_IND_LOAD_A)); + ASSERT_TRUE(row != trace.end()); + mem_ind_a_idx = static_cast(row - trace.begin()); + } + } + + void compute_index_c(FF clk, bool indirect) { // Find the memory trace position corresponding to the write sub-operation of register ic. auto row = @@ -77,20 +111,46 @@ class AvmMemOpcodeTests : public ::testing::Test { auto clk = row->avm_main_clk; - // Find the memory trace position corresponding to the load sub-operation of register ia. - row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_LOAD_A)); + compute_index_a(clk, indirect); + compute_index_c(clk, indirect); + } + + void compute_cmov_indices(uint8_t indirect) + { + // Find the first row enabling the CMOV selector + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_cmov == FF(1); }); ASSERT_TRUE(row != trace.end()); - mem_a_idx = static_cast(row - trace.begin()); + main_idx = static_cast(row - trace.begin()); - // Find the memory trace position of the indirect load for register ia. - if (indirect) { + auto clk = row->avm_main_clk; + compute_index_a(clk, is_operand_indirect(indirect, 0)); + compute_index_c(clk, is_operand_indirect(indirect, 2)); + + // Find the memory trace position corresponding to the load sub-operation of register ib. + row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_LOAD_B)); + ASSERT_TRUE(row != trace.end()); + mem_b_idx = static_cast(row - trace.begin()); + + // Find the memory trace position of the indirect load for register ib. + if (is_operand_indirect(indirect, 1)) { row = std::ranges::find_if( - trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_IND_LOAD_A)); + trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_IND_LOAD_B)); ASSERT_TRUE(row != trace.end()); - mem_ind_a_idx = static_cast(row - trace.begin()); + mem_ind_b_idx = static_cast(row - trace.begin()); } - compute_common_indices(clk, indirect); + // Find the memory trace position corresponding to the load sub-operation of register id. + row = std::ranges::find_if(trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_LOAD_D)); + ASSERT_TRUE(row != trace.end()); + mem_d_idx = static_cast(row - trace.begin()); + + // Find the memory trace position of the indirect load for register id. + if (is_operand_indirect(indirect, 3)) { + row = std::ranges::find_if( + trace.begin(), trace.end(), gen_matcher(clk, AvmMemTraceBuilder::SUB_CLK_IND_LOAD_D)); + ASSERT_TRUE(row != trace.end()); + mem_ind_d_idx = static_cast(row - trace.begin()); + } } void validate_mov_trace(bool indirect, @@ -111,7 +171,9 @@ class AvmMemOpcodeTests : public ::testing::Test { Field(&Row::avm_main_mem_idx_c, dir_dst_offset))); } EXPECT_THAT(main_row, - AllOf(Field(&Row::avm_main_ia, val_ff), + AllOf(Field(&Row::avm_main_sel_mov, 1), + Field(&Row::avm_main_sel_mov_a, 1), + Field(&Row::avm_main_ia, val_ff), Field(&Row::avm_main_ib, 0), Field(&Row::avm_main_ic, val_ff), Field(&Row::avm_main_r_in_tag, static_cast(tag)), @@ -123,7 +185,7 @@ class AvmMemOpcodeTests : public ::testing::Test { AllOf(Field(&Row::avm_mem_tag_err, 0), Field(&Row::avm_mem_r_in_tag, static_cast(tag)), Field(&Row::avm_mem_tag, static_cast(tag)), - Field(&Row::avm_mem_sel_mov, 1), + Field(&Row::avm_mem_sel_mov_a, 1), Field(&Row::avm_mem_addr, indirect ? dir_src_offset : src_offset), Field(&Row::avm_mem_val, val_ff), Field(&Row::avm_mem_rw, 0), @@ -161,6 +223,101 @@ class AvmMemOpcodeTests : public ::testing::Test { validate_trace(std::move(trace)); } + + void common_cmov_trace_validate(bool indirect, + FF const& a, + FF const& b, + FF const& d, + uint32_t addr_a, + uint32_t addr_b, + uint32_t addr_c, + uint32_t addr_d, + AvmMemoryTag tag_a, + AvmMemoryTag tag_b, + AvmMemoryTag tag_d) + { + bool const mov_a = d != 0; + AvmMemoryTag const mov_tag = mov_a ? tag_a : tag_b; + FF const& mov_val = mov_a ? a : b; + FF const inv = mov_a ? d.invert() : 1; + + EXPECT_THAT(trace.at(main_idx), + AllOf(Field("ia", &Row::avm_main_ia, a), + Field("ib", &Row::avm_main_ib, b), + Field("ic", &Row::avm_main_ic, mov_val), + Field("id", &Row::avm_main_id, d), + Field("op_a", &Row::avm_main_mem_op_a, 1), + Field("op_b", &Row::avm_main_mem_op_b, 1), + Field("op_c", &Row::avm_main_mem_op_c, 1), + Field("op_d", &Row::avm_main_mem_op_d, 1), + Field("rwa", &Row::avm_main_rwa, 0), + Field("rwb", &Row::avm_main_rwb, 0), + Field("rwc", &Row::avm_main_rwc, 1), + Field("rwd", &Row::avm_main_rwd, 0), + Field("mem_idx_a", &Row::avm_main_mem_idx_a, addr_a), + Field("mem_idx_b", &Row::avm_main_mem_idx_b, addr_b), + Field("mem_idx_c", &Row::avm_main_mem_idx_c, addr_c), + Field("mem_idx_d", &Row::avm_main_mem_idx_d, addr_d), + Field("ind_op_a", &Row::avm_main_ind_op_a, static_cast(indirect)), + Field("ind_op_b", &Row::avm_main_ind_op_b, static_cast(indirect)), + Field("ind_op_c", &Row::avm_main_ind_op_c, static_cast(indirect)), + Field("ind_op_d", &Row::avm_main_ind_op_d, static_cast(indirect)), + Field("sel_cmov", &Row::avm_main_sel_cmov, 1), + Field("sel_mov_a", &Row::avm_main_sel_mov_a, mov_a), + Field("sel_mov_b", &Row::avm_main_sel_mov_b, !mov_a), + Field("r_in_tag", &Row::avm_main_r_in_tag, static_cast(mov_tag)), + Field("w_in_tag", &Row::avm_main_w_in_tag, static_cast(mov_tag)), + Field("inv", &Row::avm_main_inv, inv))); + + EXPECT_THAT(trace.at(mem_a_idx), + AllOf(Field("r_in_tag", &Row::avm_mem_r_in_tag, static_cast(mov_tag)), + Field("w_in_tag", &Row::avm_mem_w_in_tag, static_cast(mov_tag)), + Field("tag", &Row::avm_mem_tag, static_cast(tag_a)), + Field("sel_mov_a", &Row::avm_mem_sel_mov_a, mov_a), + Field("mem_addr", &Row::avm_mem_addr, addr_a), + Field("val", &Row::avm_mem_val, a), + Field("rw", &Row::avm_mem_rw, 0), + Field("skip_check_tag", &Row::avm_mem_skip_check_tag, mov_a ? 0 : 1), + Field("op_a", &Row::avm_mem_op_a, 1), + Field("ind_op_a", &Row::avm_mem_ind_op_a, 0))); + + EXPECT_THAT(trace.at(mem_b_idx), + AllOf(Field("r_in_tag", &Row::avm_mem_r_in_tag, static_cast(mov_tag)), + Field("w_in_tag", &Row::avm_mem_w_in_tag, static_cast(mov_tag)), + Field("tag", &Row::avm_mem_tag, static_cast(tag_b)), + Field("tag_err", &Row::avm_mem_tag_err, 0), + Field("sel_mov_b", &Row::avm_mem_sel_mov_b, !mov_a), + Field("mem_addr", &Row::avm_mem_addr, addr_b), + Field("val", &Row::avm_mem_val, b), + Field("rw", &Row::avm_mem_rw, 0), + Field("skip_check_tag", &Row::avm_mem_skip_check_tag, mov_a ? 1 : 0), + Field("op_b", &Row::avm_mem_op_b, 1), + Field("ind_op_b", &Row::avm_mem_ind_op_b, 0))); + + EXPECT_THAT(trace.at(mem_c_idx), + AllOf(Field("r_in_tag", &Row::avm_mem_r_in_tag, static_cast(mov_tag)), + Field("w_in_tag", &Row::avm_mem_w_in_tag, static_cast(mov_tag)), + Field("tag", &Row::avm_mem_tag, static_cast(mov_tag)), + Field("tag_err", &Row::avm_mem_tag_err, 0), + Field("mem_addr", &Row::avm_mem_addr, addr_c), + Field("val", &Row::avm_mem_val, mov_a ? a : b), + Field("rw", &Row::avm_mem_rw, 1), + Field("skip_check_tag", &Row::avm_mem_skip_check_tag, 0), + Field("op_c", &Row::avm_mem_op_c, 1), + Field("ind_op_c", &Row::avm_mem_ind_op_c, 0))); + + EXPECT_THAT(trace.at(mem_d_idx), + AllOf(Field("r_in_tag", &Row::avm_mem_r_in_tag, static_cast(mov_tag)), + Field("w_in_tag", &Row::avm_mem_w_in_tag, static_cast(mov_tag)), + Field("tag", &Row::avm_mem_tag, static_cast(tag_d)), + Field("tag_err", &Row::avm_mem_tag_err, 0), + Field("mem_addr", &Row::avm_mem_addr, addr_d), + Field("val", &Row::avm_mem_val, d), + Field("rw", &Row::avm_mem_rw, 0), + Field("skip_check_tag", &Row::avm_mem_skip_check_tag, 1), + Field("op_d", &Row::avm_mem_op_d, 1), + Field("ind_op_d", &Row::avm_mem_ind_op_d, 0))); + } }; class AvmMemOpcodeNegativeTests : public AvmMemOpcodeTests {}; @@ -171,6 +328,10 @@ class AvmMemOpcodeNegativeTests : public AvmMemOpcodeTests {}; * ******************************************************************************/ +/****************************************************************************** + * MOV Opcode + ******************************************************************************/ + TEST_F(AvmMemOpcodeTests, basicMov) { build_mov_trace(false, 42, 9, 13, AvmMemoryTag::U64); @@ -233,13 +394,126 @@ TEST_F(AvmMemOpcodeTests, indirectMovInvalidAddressTag) validate_trace(std::move(trace)); } +/****************************************************************************** + * CMOV Opcode + ******************************************************************************/ + +TEST_F(AvmMemOpcodeTests, allDirectCMovA) +{ + trace_builder.op_set(0, 1979, 10, AvmMemoryTag::U16); // a + trace_builder.op_set(0, 1980, 11, AvmMemoryTag::U128); // b + trace_builder.op_set(0, 987162, 20, AvmMemoryTag::U64); // Non-zero condition value (we move a) + trace_builder.op_set(0, 8, 12, AvmMemoryTag::U32); // Target, should be overwritten + + trace_builder.op_cmov(0, 10, 11, 20, 12); + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_cmov_indices(0); + common_cmov_trace_validate( + false, 1979, 1980, 987162, 10, 11, 12, 20, AvmMemoryTag::U16, AvmMemoryTag::U128, AvmMemoryTag::U64); + validate_trace_check_circuit(std::move(trace)); +} + +TEST_F(AvmMemOpcodeTests, allDirectCMovB) +{ + trace_builder.op_set(0, 1979, 10, AvmMemoryTag::U8); // a + trace_builder.op_set(0, 1980, 11, AvmMemoryTag::U8); // b + trace_builder.op_set(0, 0, 20, AvmMemoryTag::U64); // Zero condition value (we move b) + trace_builder.op_set(0, 8, 12, AvmMemoryTag::U32); // Target, should be overwritten + + trace_builder.op_cmov(0, 10, 11, 20, 12); + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_cmov_indices(0); + common_cmov_trace_validate( + false, 1979, 1980, 0, 10, 11, 12, 20, AvmMemoryTag::U8, AvmMemoryTag::U8, AvmMemoryTag::U64); + validate_trace_check_circuit(std::move(trace)); +} + +TEST_F(AvmMemOpcodeTests, allDirectCMovConditionUninitialized) +{ + trace_builder.op_set(0, 1979, 10, AvmMemoryTag::U8); // a + trace_builder.op_set(0, 1980, 11, AvmMemoryTag::U8); // b + // Address 20 is unitialized and we use it as the condition + // value. It will be therefore zero. (we move b) + + trace_builder.op_cmov(0, 10, 11, 20, 12); + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_cmov_indices(0); + common_cmov_trace_validate( + false, 1979, 1980, 0, 10, 11, 12, 20, AvmMemoryTag::U8, AvmMemoryTag::U8, AvmMemoryTag::U0); + validate_trace_check_circuit(std::move(trace)); +} + +TEST_F(AvmMemOpcodeTests, allDirectCMovOverwriteA) +{ + trace_builder.op_set(0, 1979, 10, AvmMemoryTag::U8); // a + trace_builder.op_set(0, 1980, 11, AvmMemoryTag::U8); // b + trace_builder.op_set(0, 0, 20, AvmMemoryTag::U64); // Zero condition value (we move b) + + trace_builder.op_cmov(0, 10, 11, 20, 10); + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_cmov_indices(0); + common_cmov_trace_validate( + false, 1979, 1980, 0, 10, 11, 10, 20, AvmMemoryTag::U8, AvmMemoryTag::U8, AvmMemoryTag::U64); + validate_trace_check_circuit(std::move(trace)); +} + +TEST_F(AvmMemOpcodeTests, allIndirectCMovA) +{ + // a b c d + // Val 1979 1980 1979 987162 + // Dir Addr 10 11 12 20 + // Ind Addr 110 111 112 120 + + trace_builder.op_set(0, 10, 110, AvmMemoryTag::U32); + trace_builder.op_set(0, 11, 111, AvmMemoryTag::U32); + trace_builder.op_set(0, 12, 112, AvmMemoryTag::U32); + trace_builder.op_set(0, 20, 120, AvmMemoryTag::U32); + + trace_builder.op_set(0, 1979, 10, AvmMemoryTag::U16); // a + trace_builder.op_set(0, 1980, 11, AvmMemoryTag::U128); // b + trace_builder.op_set(0, 987162, 20, AvmMemoryTag::U64); // Non-zero condition value (we move a) + trace_builder.op_set(0, 8, 12, AvmMemoryTag::U32); // Target, should be overwritten + + trace_builder.op_cmov(15, 110, 111, 120, 112); + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_cmov_indices(15); + common_cmov_trace_validate( + true, 1979, 1980, 987162, 10, 11, 12, 20, AvmMemoryTag::U16, AvmMemoryTag::U128, AvmMemoryTag::U64); + validate_trace_check_circuit(std::move(trace)); +} + +TEST_F(AvmMemOpcodeTests, allIndirectCMovAllUnitialized) +{ + trace_builder.op_cmov(15, 10, 11, 20, 10); + trace_builder.return_op(0, 0, 0); + trace = trace_builder.finalize(); + + compute_cmov_indices(15); + common_cmov_trace_validate(true, 0, 0, 0, 0, 0, 0, 0, AvmMemoryTag::U0, AvmMemoryTag::U0, AvmMemoryTag::U0); + validate_trace_check_circuit(std::move(trace)); +} + +/****************************************************************************** + * SET Opcode + ******************************************************************************/ + TEST_F(AvmMemOpcodeTests, directSet) { trace_builder.op_set(0, 5683, 99, AvmMemoryTag::U128); trace_builder.return_op(0, 0, 0); trace = trace_builder.finalize(); - compute_common_indices(0, false); + compute_index_c(0, false); auto const& row = trace.at(1); EXPECT_THAT(row, @@ -267,7 +541,7 @@ TEST_F(AvmMemOpcodeTests, indirectSet) trace_builder.return_op(0, 0, 0); trace = trace_builder.finalize(); - compute_common_indices(1, true); + compute_index_c(1, true); auto const& row = trace.at(2); EXPECT_THAT(row, @@ -307,7 +581,7 @@ TEST_F(AvmMemOpcodeTests, indirectSetWrongTag) trace_builder.return_op(0, 0, 0); trace = trace_builder.finalize(); - compute_common_indices(1, true); + compute_index_c(1, true); auto const& row = trace.at(2); EXPECT_THAT(row, @@ -336,6 +610,10 @@ TEST_F(AvmMemOpcodeTests, indirectSetWrongTag) * ******************************************************************************/ +/****************************************************************************** + * MOV Opcode + ******************************************************************************/ + TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputErrorTag) { build_mov_trace(false, 234, 0, 1, AvmMemoryTag::U8); @@ -351,7 +629,7 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputValue) compute_mov_indices(false); trace.at(main_idx).avm_main_ic = 233; - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "MOV_SAME_VALUE"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "MOV_SAME_VALUE_A"); } TEST_F(AvmMemOpcodeNegativeTests, indMovWrongOutputValue) @@ -360,7 +638,7 @@ TEST_F(AvmMemOpcodeNegativeTests, indMovWrongOutputValue) compute_mov_indices(true); trace.at(main_idx).avm_main_ic = 8733; - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "MOV_SAME_VALUE"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "MOV_SAME_VALUE_A"); } // We want to test that the output tag for MOV cannot be altered. @@ -405,7 +683,7 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagDisabledSelector) trace.at(mem_a_idx).avm_mem_w_in_tag = tag_u64; trace.at(mem_a_idx).avm_mem_tag_err = 1; trace.at(mem_a_idx).avm_mem_one_min_inv = one_min_inverse_diff; - trace.at(mem_a_idx).avm_mem_sel_mov = 0; + trace.at(mem_a_idx).avm_mem_sel_mov_a = 0; trace.at(mem_c_idx).avm_mem_tag = tag_u64; trace.at(mem_c_idx).avm_mem_r_in_tag = tag_u64; trace.at(mem_c_idx).avm_mem_w_in_tag = tag_u64; @@ -447,4 +725,63 @@ TEST_F(AvmMemOpcodeNegativeTests, movWrongOutputTagMainTraceRead) EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "PERM_MAIN_MEM_C"); } +/****************************************************************************** + * CMOV Opcode + ******************************************************************************/ +TEST_F(AvmMemOpcodeNegativeTests, cmovBInsteadA) +{ + build_cmov_trace_neg_test(true); + + trace.at(main_idx).avm_main_ic = 1980; + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "MOV_SAME_VALUE_A"); +} + +TEST_F(AvmMemOpcodeNegativeTests, cmovAInsteadB) +{ + build_cmov_trace_neg_test(false); + + trace.at(main_idx).avm_main_ic = 1979; + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "MOV_SAME_VALUE_B"); +} + +TEST_F(AvmMemOpcodeNegativeTests, cmovAChangeTag) +{ + build_cmov_trace_neg_test(true); + + trace.at(mem_c_idx).avm_mem_tag = static_cast(AvmMemoryTag::U32); + trace.at(mem_c_idx).avm_mem_w_in_tag = static_cast(AvmMemoryTag::U32); + trace.at(main_idx).avm_main_w_in_tag = static_cast(AvmMemoryTag::U32); + + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "MOV_MAIN_SAME_TAG"); +} + +TEST_F(AvmMemOpcodeNegativeTests, cmovASkipCheckAbuse) +{ + build_cmov_trace_neg_test(true); + + trace.at(mem_a_idx).avm_mem_skip_check_tag = 1; + + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "SKIP_CHECK_TAG"); +} + +TEST_F(AvmMemOpcodeNegativeTests, cmovASkipCheckAbuseDisableSelMovA) +{ + build_cmov_trace_neg_test(true); + + trace.at(mem_a_idx).avm_mem_skip_check_tag = 1; + trace.at(mem_a_idx).avm_mem_sel_mov_a = 0; + + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "PERM_MAIN_MEM_A"); +} + +TEST_F(AvmMemOpcodeNegativeTests, cmovBSkipCheckAbuseDisableSelMovB) +{ + build_cmov_trace_neg_test(false); + + trace.at(mem_b_idx).avm_mem_skip_check_tag = 1; + trace.at(mem_b_idx).avm_mem_sel_mov_b = 0; + + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "PERM_MAIN_MEM_B"); +} + } // namespace tests_avm