diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index 42141360f38..4306643acf3 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -400,6 +400,12 @@ namespace avm_main(256); #[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}; + #[LOOKUP_MEM_RNG_CHK_LO] + avm_mem.rng_chk_sel {avm_mem.diff_lo} in sel_rng_16 {clk}; + + #[LOOKUP_MEM_RNG_CHK_HI] + avm_mem.rng_chk_sel {avm_mem.diff_hi} in sel_rng_16 {clk}; + //====== Inter-table Shift Constraints (Lookups) ============================================ // Currently only used for shift operations but can be generalised for other uses. diff --git a/barretenberg/cpp/pil/avm/avm_mem.pil b/barretenberg/cpp/pil/avm/avm_mem.pil index 34834214487..be3edb0b12d 100644 --- a/barretenberg/cpp/pil/avm/avm_mem.pil +++ b/barretenberg/cpp/pil/avm/avm_mem.pil @@ -1,17 +1,17 @@ - - include "avm_main.pil"; namespace avm_mem(256); // ========= Table MEM-TR ================= pol commit clk; - pol commit sub_clk; + pol commit tsp; // Timestamp derived form clk and sub-operation types (SUB_CLK) pol commit addr; pol commit tag; // Memory tag (0: uninitialized, 1: u8, 2: u16, 3: u32, 4: u64, 5: u128, 6:field) pol commit val; + pol commit rw; // Enum: 0 (read), 1 (write) pol commit lastAccess; // Boolean (1 when this row is the last of a given address) pol commit last; // Boolean indicating the last row of the memory trace (not execution trace) - pol commit rw; // Enum: 0 (read), 1 (write) + pol commit mem_sel; // Selector for every row pertaining to the memory trace + pol commit rng_chk_sel; // Selector for row on which range-checks apply. 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) @@ -41,6 +41,9 @@ namespace avm_mem(256); // Helper columns pol commit one_min_inv; // Extra value to prove r_in_tag != tag with error handling + // pol DIFF: Difference between two consecutive timestamps or two consecutive addresses + pol commit diff_hi; // Higher 16-bit limb of diff. + pol commit diff_lo; // Lower 16-bit limb of diff. // Type constraints lastAccess * (1 - lastAccess) = 0; @@ -56,18 +59,43 @@ namespace avm_mem(256); 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) + // TODO: 1) Ensure that addr is constrained to be 32 bits by the main trace and/or bytecode decomposition + // 2) Ensure that tag, r_in_tag, w_in_tag are properly constrained by the main trace and/or bytecode decomposition + // Definition of mem_sel + mem_sel = op_a + op_b + op_c + op_d + ind_op_a + ind_op_b + ind_op_c + ind_op_d; // Maximum one memory operation enabled per row - 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; + mem_sel * (mem_sel - 1) = 0; // TODO: might be infered by the main trace + + // Enforce the memory entries to be contiguous, i.e., as soon as + // mem_sel is disabled all subsequent rows have mem_sel disabled. + #[MEM_CONTIGUOUS] + (1 - avm_main.first) * mem_sel' * (1 - mem_sel) = 0; + + // Memory trace rows cannot start at first row + #[MEM_FIRST_EMPTY] + avm_main.first * mem_sel = 0; + + // Definition of rng_chk_sel. It is a boolean as mem_sel and last are booleans. + rng_chk_sel = mem_sel * (1 - last); // sub_clk derivation + // Current sub_clk range is [0,12) which is subdivided as follows: + // [0,4): indirect memory operations (read-only resolution of the direct address) + // [4,8): direct read memory operations + // [8, 12): direct write memory operations + // Each sub-range of 4 values correspond to registers ordered as a, b, c, d. + + pol NUM_SUB_CLK = 12; 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. + pol 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. + + #[TIMESTAMP] + tsp = NUM_SUB_CLK * clk + SUB_CLK; + #[LAST_ACCESS_FIRST_ROW] + avm_main.first * (1 - lastAccess) = 0; // Remark: lastAccess == 1 on first row and therefore any relation with the // multiplicative term (1 - lastAccess) implicitly includes (1 - avm_main.first) // Similarly, this includes (1 - last) as well. @@ -80,20 +108,21 @@ namespace avm_mem(256); // We need: lastAccess == 1 ==> addr' > addr // The above implies: addr' == addr ==> lastAccess == 0 // This condition does not apply on the last row. - // clk + 1 used as an expression for positive integers - // TODO: Uncomment when lookups are supported - // (1 - first) * (1 - last) * lastAccess { (addr' - addr) } in clk + 1; // Gated inclusion check. Is it supported? - - // TODO: following constraint - // addr' == addr && clk == clk' ==> sub_clk' - sub_clk > 0 - // Can be enforced with (1 - first) * (1 - lastAccess) { 6 * (clk' - clk) + sub_clk' - sub_clk } in clk + 1 - - // Alternatively to the above, one could require - // that addr' - addr is 0 or 1 (needs to add placeholders addr values): - // (addr' - addr) * (addr' - addr) - (addr' - addr) = 0; - // if addr' - addr is 0 or 1, the following is equiv. to lastAccess - // (addr' - addr) - + + // In addition, we need addr' == addr ==> tsp' > tsp + // For all rows pertaining to the memory trace (mem_sel == 1) except the last one, + // i.e., when rng_chk_sel == 1, we compute the difference: + // 1) addr' - addr if lastAccess == 1 + // 2) tsp' - tsp if lastAccess == 0 (i.e., whenever addr' == addr) + pol DIFF = lastAccess * (addr' - addr) + (1 - lastAccess) * (tsp' - tsp); + + // We perform a 32-bit range check of DIFF which proves that addr' > addr if lastAccess == 1 + // and tsp' > tsp whenever addr' == addr + // Therefore, we ensure proper grouping of each address and each memory access pertaining to a given + // address is sorted according the arrow of time. + #[DIFF_RNG_CHK_DEC] + rng_chk_sel * (DIFF - diff_hi * 2**16 - diff_lo) = 0; + // lastAccess == 0 && rw' == 0 ==> val == val' // This condition does not apply on the last row. // Note: in barretenberg, a shifted polynomial will be 0 on the last row (shift is not cyclic) @@ -110,12 +139,12 @@ namespace avm_mem(256); // Constrain that the first load from a given address has value 0. (Consistency of memory initialization.) // We do not constrain that the tag == 0 as the 0 value is compatible with any memory type. - // If we set lastAccess = 1 on the first row, we can enforce this (should be ok as long as we do not shift lastAccess): + // As we enforce lastAccess = 1 on the first row, the following condition applies also for the first memory entry: #[MEM_ZERO_INIT] lastAccess * (1 - rw') * val' = 0; // Skip check tag - #[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. 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 2de1a2fe5b0..26b504f9ce2 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_mem.hpp @@ -7,30 +7,38 @@ namespace bb::Avm_vm { template struct Avm_memRow { + FF avm_main_first{}; FF avm_mem_addr{}; FF avm_mem_addr_shift{}; + FF avm_mem_clk{}; + FF avm_mem_diff_hi{}; + FF avm_mem_diff_lo{}; 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_mem_sel{}; + FF avm_mem_mem_sel_shift{}; 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_rng_chk_sel{}; FF avm_mem_rw{}; FF avm_mem_rw_shift{}; 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{}; FF avm_mem_tag_shift{}; + FF avm_mem_tsp{}; + FF avm_mem_tsp_shift{}; FF avm_mem_val{}; FF avm_mem_val_shift{}; FF avm_mem_w_in_tag{}; @@ -40,33 +48,48 @@ inline std::string get_relation_label_avm_mem(int index) { switch (index) { case 14: - return "MEM_LAST_ACCESS_DELIMITER"; + return "MEM_CONTIGUOUS"; case 15: + return "MEM_FIRST_EMPTY"; + + case 17: + return "TIMESTAMP"; + + case 18: + return "LAST_ACCESS_FIRST_ROW"; + + case 19: + return "MEM_LAST_ACCESS_DELIMITER"; + + case 20: + return "DIFF_RNG_CHK_DEC"; + + case 21: return "MEM_READ_WRITE_VAL_CONSISTENCY"; - case 16: + case 22: return "MEM_READ_WRITE_TAG_CONSISTENCY"; - case 17: + case 23: return "MEM_ZERO_INIT"; - case 18: + case 24: return "SKIP_CHECK_TAG"; - case 19: + case 25: return "MEM_IN_TAG_CONSISTENCY_1"; - case 20: + case 26: return "MEM_IN_TAG_CONSISTENCY_2"; - case 21: + case 27: return "NO_TAG_ERR_WRITE_OR_SKIP"; - case 23: + case 29: return "NO_TAG_ERR_WRITE"; - case 32: + case 38: return "MOV_SAME_TAG"; } return std::to_string(index); @@ -76,8 +99,9 @@ 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, 3, 3, 4, 3, 4, 4, 4, 4, 5, 3, 3, 3, 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, 2, 3, 4, 3, 3, 4, 3, 3, + 4, 4, 4, 4, 4, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }; template @@ -187,15 +211,11 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(12); - auto tmp = ((((((((avm_mem_op_a + avm_mem_op_b) + avm_mem_op_c) + avm_mem_op_d) + avm_mem_ind_op_a) + + auto tmp = (avm_mem_mem_sel - + (((((((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))); + avm_mem_ind_op_d)); tmp *= scaling_factor; std::get<12>(evals) += tmp; } @@ -203,16 +223,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(13); - 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))))); + auto tmp = (avm_mem_mem_sel * (avm_mem_mem_sel - FF(1))); tmp *= scaling_factor; std::get<13>(evals) += tmp; } @@ -220,7 +231,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(14); - auto tmp = ((-avm_mem_lastAccess + FF(1)) * (avm_mem_addr_shift - avm_mem_addr)); + auto tmp = (((-avm_main_first + FF(1)) * avm_mem_mem_sel_shift) * (-avm_mem_mem_sel + FF(1))); tmp *= scaling_factor; std::get<14>(evals) += tmp; } @@ -228,8 +239,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(15); - auto tmp = - (((-avm_mem_lastAccess + FF(1)) * (-avm_mem_rw_shift + FF(1))) * (avm_mem_val_shift - avm_mem_val)); + auto tmp = (avm_main_first * avm_mem_mem_sel); tmp *= scaling_factor; std::get<15>(evals) += tmp; } @@ -237,8 +247,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(16); - auto tmp = - (((-avm_mem_lastAccess + FF(1)) * (-avm_mem_rw_shift + FF(1))) * (avm_mem_tag_shift - avm_mem_tag)); + auto tmp = (avm_mem_rng_chk_sel - (avm_mem_mem_sel * (-avm_mem_last + FF(1)))); tmp *= scaling_factor; std::get<16>(evals) += tmp; } @@ -246,7 +255,15 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(17); - auto tmp = ((avm_mem_lastAccess * (-avm_mem_rw_shift + FF(1))) * avm_mem_val_shift); + auto tmp = + (avm_mem_tsp - + ((avm_mem_clk * FF(12)) + + (avm_mem_mem_sel * + ((((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<17>(evals) += tmp; } @@ -254,9 +271,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(18); - 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)))))); + auto tmp = (avm_main_first * (-avm_mem_lastAccess + FF(1))); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -264,8 +279,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(19); - 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)); + auto tmp = ((-avm_mem_lastAccess + FF(1)) * (avm_mem_addr_shift - avm_mem_addr)); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -273,7 +287,10 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = ((-avm_mem_tag_err + FF(1)) * avm_mem_one_min_inv); + auto tmp = (avm_mem_rng_chk_sel * ((((avm_mem_lastAccess * (avm_mem_addr_shift - avm_mem_addr)) + + ((-avm_mem_lastAccess + FF(1)) * (avm_mem_tsp_shift - avm_mem_tsp))) - + (avm_mem_diff_hi * FF(65536))) - + avm_mem_diff_lo)); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -281,7 +298,8 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = ((avm_mem_skip_check_tag + avm_mem_rw) * avm_mem_tag_err); + 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<21>(evals) += tmp; } @@ -289,7 +307,8 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = (avm_mem_rw * (avm_mem_w_in_tag - avm_mem_tag)); + 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<22>(evals) += tmp; } @@ -297,7 +316,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (avm_mem_rw * avm_mem_tag_err); + auto tmp = ((avm_mem_lastAccess * (-avm_mem_rw_shift + FF(1))) * avm_mem_val_shift); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -305,7 +324,9 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = (avm_mem_ind_op_a * (avm_mem_r_in_tag - FF(3))); + 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<24>(evals) += tmp; } @@ -313,7 +334,8 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (avm_mem_ind_op_b * (avm_mem_r_in_tag - FF(3))); + 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<25>(evals) += tmp; } @@ -321,7 +343,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = (avm_mem_ind_op_c * (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<26>(evals) += tmp; } @@ -329,7 +351,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = (avm_mem_ind_op_d * (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<27>(evals) += tmp; } @@ -337,7 +359,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(28); - auto tmp = (avm_mem_ind_op_a * avm_mem_rw); + auto tmp = (avm_mem_rw * (avm_mem_w_in_tag - avm_mem_tag)); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -345,7 +367,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(29); - auto tmp = (avm_mem_ind_op_b * avm_mem_rw); + auto tmp = (avm_mem_rw * avm_mem_tag_err); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -353,7 +375,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(30); - auto tmp = (avm_mem_ind_op_c * avm_mem_rw); + auto tmp = (avm_mem_ind_op_a * (avm_mem_r_in_tag - FF(3))); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -361,7 +383,7 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(31); - auto tmp = (avm_mem_ind_op_d * avm_mem_rw); + auto tmp = (avm_mem_ind_op_b * (avm_mem_r_in_tag - FF(3))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -369,10 +391,58 @@ template class avm_memImpl { { Avm_DECLARE_VIEWS(32); - auto tmp = ((avm_mem_sel_mov_a + avm_mem_sel_mov_b) * avm_mem_tag_err); + auto tmp = (avm_mem_ind_op_c * (avm_mem_r_in_tag - FF(3))); tmp *= scaling_factor; std::get<32>(evals) += tmp; } + // Contribution 33 + { + Avm_DECLARE_VIEWS(33); + + auto tmp = (avm_mem_ind_op_d * (avm_mem_r_in_tag - FF(3))); + tmp *= scaling_factor; + std::get<33>(evals) += tmp; + } + // Contribution 34 + { + Avm_DECLARE_VIEWS(34); + + auto tmp = (avm_mem_ind_op_a * avm_mem_rw); + tmp *= scaling_factor; + std::get<34>(evals) += tmp; + } + // Contribution 35 + { + Avm_DECLARE_VIEWS(35); + + auto tmp = (avm_mem_ind_op_b * avm_mem_rw); + tmp *= scaling_factor; + std::get<35>(evals) += tmp; + } + // Contribution 36 + { + Avm_DECLARE_VIEWS(36); + + auto tmp = (avm_mem_ind_op_c * avm_mem_rw); + tmp *= scaling_factor; + std::get<36>(evals) += tmp; + } + // Contribution 37 + { + Avm_DECLARE_VIEWS(37); + + auto tmp = (avm_mem_ind_op_d * avm_mem_rw); + tmp *= scaling_factor; + std::get<37>(evals) += tmp; + } + // Contribution 38 + { + Avm_DECLARE_VIEWS(38); + + auto tmp = ((avm_mem_sel_mov_a + avm_mem_sel_mov_b) * avm_mem_tag_err); + tmp *= scaling_factor; + std::get<38>(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 9dce9599042..5225e83adfa 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -154,26 +154,30 @@ [[maybe_unused]] auto avm_main_w_in_tag = View(new_term.avm_main_w_in_tag); \ [[maybe_unused]] auto avm_mem_addr = View(new_term.avm_mem_addr); \ [[maybe_unused]] auto avm_mem_clk = View(new_term.avm_mem_clk); \ + [[maybe_unused]] auto avm_mem_diff_hi = View(new_term.avm_mem_diff_hi); \ + [[maybe_unused]] auto avm_mem_diff_lo = View(new_term.avm_mem_diff_lo); \ [[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_mem_sel = View(new_term.avm_mem_mem_sel); \ [[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_rng_chk_sel = View(new_term.avm_mem_rng_chk_sel); \ [[maybe_unused]] auto avm_mem_rw = View(new_term.avm_mem_rw); \ [[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); \ + [[maybe_unused]] auto avm_mem_tsp = View(new_term.avm_mem_tsp); \ [[maybe_unused]] auto avm_mem_val = View(new_term.avm_mem_val); \ [[maybe_unused]] auto avm_mem_w_in_tag = View(new_term.avm_mem_w_in_tag); \ [[maybe_unused]] auto perm_main_alu = View(new_term.perm_main_alu); \ @@ -190,6 +194,8 @@ [[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); \ [[maybe_unused]] auto incl_mem_tag_err = View(new_term.incl_mem_tag_err); \ + [[maybe_unused]] auto lookup_mem_rng_chk_lo = View(new_term.lookup_mem_rng_chk_lo); \ + [[maybe_unused]] auto lookup_mem_rng_chk_hi = View(new_term.lookup_mem_rng_chk_hi); \ [[maybe_unused]] auto lookup_pow_2_0 = View(new_term.lookup_pow_2_0); \ [[maybe_unused]] auto lookup_pow_2_1 = View(new_term.lookup_pow_2_1); \ [[maybe_unused]] auto lookup_u8_0 = View(new_term.lookup_u8_0); \ @@ -213,6 +219,8 @@ [[maybe_unused]] auto lookup_byte_operations_counts = View(new_term.lookup_byte_operations_counts); \ [[maybe_unused]] auto incl_main_tag_err_counts = View(new_term.incl_main_tag_err_counts); \ [[maybe_unused]] auto incl_mem_tag_err_counts = View(new_term.incl_mem_tag_err_counts); \ + [[maybe_unused]] auto lookup_mem_rng_chk_lo_counts = View(new_term.lookup_mem_rng_chk_lo_counts); \ + [[maybe_unused]] auto lookup_mem_rng_chk_hi_counts = View(new_term.lookup_mem_rng_chk_hi_counts); \ [[maybe_unused]] auto lookup_pow_2_0_counts = View(new_term.lookup_pow_2_0_counts); \ [[maybe_unused]] auto lookup_pow_2_1_counts = View(new_term.lookup_pow_2_1_counts); \ [[maybe_unused]] auto lookup_u8_0_counts = View(new_term.lookup_u8_0_counts); \ @@ -270,6 +278,8 @@ [[maybe_unused]] auto avm_main_internal_return_ptr_shift = View(new_term.avm_main_internal_return_ptr_shift); \ [[maybe_unused]] auto avm_main_pc_shift = View(new_term.avm_main_pc_shift); \ [[maybe_unused]] auto avm_mem_addr_shift = View(new_term.avm_mem_addr_shift); \ + [[maybe_unused]] auto avm_mem_mem_sel_shift = View(new_term.avm_mem_mem_sel_shift); \ [[maybe_unused]] auto avm_mem_rw_shift = View(new_term.avm_mem_rw_shift); \ [[maybe_unused]] auto avm_mem_tag_shift = View(new_term.avm_mem_tag_shift); \ + [[maybe_unused]] auto avm_mem_tsp_shift = View(new_term.avm_mem_tsp_shift); \ [[maybe_unused]] auto avm_mem_val_shift = View(new_term.avm_mem_val_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_mem_rng_chk_hi.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_mem_rng_chk_hi.hpp new file mode 100644 index 00000000000..534c53a0f5f --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_mem_rng_chk_hi.hpp @@ -0,0 +1,167 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_mem_rng_chk_hi_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 4; + + /** + * @brief The degree of the read term if implemented arbitrarily. This value is not used by basic and scaled read + * terms, but will cause compilation error if not defined + * + */ + static constexpr size_t READ_TERM_DEGREE = 0; + + /** + * @brief The degree of the write term if implemented arbitrarily. This value is not used by the basic write + * term, but will cause compilation error if not defined + * + */ + + static constexpr size_t WRITE_TERM_DEGREE = 0; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial exists at this index. + * Otherwise the value needs to be set to zero. + * + * @details If this is true then the lookup takes place in this row + * + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.avm_mem_rng_chk_sel == 1 || in.avm_main_sel_rng_16 == 1); + } + + /** + * @brief Subprocedure for computing the value deciding if the inverse polynomial value needs to be checked in this + * row + * + * @tparam Accumulator Type specified by the lookup relation + * @tparam AllEntities Values/Univariates of all entities row + * @param in Value/Univariate of all entities at row/edge + * @return Accumulator + */ + + template + static inline auto compute_inverse_exists(const AllEntities& in) + { + using View = typename Accumulator::View; + const auto is_operation = View(in.avm_mem_rng_chk_sel); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + return (is_operation + is_table_entry - is_operation * is_table_entry); + } + + /** + * @brief Get all the entities for the lookup when need to update them + * + * @details The generic structure of this tuple is described in ./generic_lookup_relation.hpp . The following is + description for the current case: + The entities are returned as a tuple of references in the following order (this is for ): + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that specifies how many times the lookup table entry at this row has been looked up + * - READ_TERMS entities/polynomials that enable individual lookup operations + * - The entity/polynomial that enables adding an entry to the lookup table in this row + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the basic tuple being looked up as the first read term + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the previous accumulators in the second read term + (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the shifts in the second read term (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the current accumulators in the second read term + (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing basic tuples added to the table + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_mem_rng_chk_hi, + in.lookup_mem_rng_chk_hi_counts, + in.avm_mem_rng_chk_sel, + in.avm_main_sel_rng_16, + in.avm_mem_diff_hi, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_mem_rng_chk_hi, + in.lookup_mem_rng_chk_hi_counts, + in.avm_mem_rng_chk_sel, + in.avm_main_sel_rng_16, + in.avm_mem_diff_hi, + in.avm_main_clk); + } +}; + +template +using lookup_mem_rng_chk_hi_relation = GenericLookupRelation; +template using lookup_mem_rng_chk_hi = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_mem_rng_chk_lo.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_mem_rng_chk_lo.hpp new file mode 100644 index 00000000000..d59ef829c2d --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_mem_rng_chk_lo.hpp @@ -0,0 +1,167 @@ + + +#pragma once + +#include "barretenberg/relations/generic_lookup/generic_lookup_relation.hpp" + +#include +#include + +namespace bb { + +/** + * @brief This class contains an example of how to set LookupSettings classes used by the + * GenericLookupRelationImpl class to specify a scaled lookup + * + * @details To create your own lookup: + * 1) Create a copy of this class and rename it + * 2) Update all the values with the ones needed for your lookup + * 3) Update "DECLARE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" and "DEFINE_LOOKUP_IMPLEMENTATIONS_FOR_ALL_SETTINGS" to + * include the new settings + * 4) Add the relation with the chosen settings to Relations in the flavor (for example,"` + * using Relations = std::tuple>;)` + * + */ +class lookup_mem_rng_chk_lo_lookup_settings { + public: + /** + * @brief The number of read terms (how many lookups we perform) in each row + * + */ + static constexpr size_t READ_TERMS = 1; + /** + * @brief The number of write terms (how many additions to the lookup table we make) in each row + * + */ + static constexpr size_t WRITE_TERMS = 1; + + /** + * @brief The type of READ_TERM used for each read index (basic and scaled) + * + */ + static constexpr size_t READ_TERM_TYPES[READ_TERMS] = { 0 }; + + /** + * @brief They type of WRITE_TERM used for each write index + * + */ + static constexpr size_t WRITE_TERM_TYPES[WRITE_TERMS] = { 0 }; + + /** + * @brief How many values represent a single lookup object. This value is used by the automatic read term + * implementation in the relation in case the lookup is a basic or scaled tuple and in the write term if it's a + * basic tuple + * + */ + static constexpr size_t LOOKUP_TUPLE_SIZE = 1; + + /** + * @brief The polynomial degree of the relation telling us if the inverse polynomial value needs to be computed + * + */ + static constexpr size_t INVERSE_EXISTS_POLYNOMIAL_DEGREE = 4; + + /** + * @brief The degree of the read term if implemented arbitrarily. This value is not used by basic and scaled read + * terms, but will cause compilation error if not defined + * + */ + static constexpr size_t READ_TERM_DEGREE = 0; + + /** + * @brief The degree of the write term if implemented arbitrarily. This value is not used by the basic write + * term, but will cause compilation error if not defined + * + */ + + static constexpr size_t WRITE_TERM_DEGREE = 0; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial exists at this index. + * Otherwise the value needs to be set to zero. + * + * @details If this is true then the lookup takes place in this row + * + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.avm_mem_rng_chk_sel == 1 || in.avm_main_sel_rng_16 == 1); + } + + /** + * @brief Subprocedure for computing the value deciding if the inverse polynomial value needs to be checked in this + * row + * + * @tparam Accumulator Type specified by the lookup relation + * @tparam AllEntities Values/Univariates of all entities row + * @param in Value/Univariate of all entities at row/edge + * @return Accumulator + */ + + template + static inline auto compute_inverse_exists(const AllEntities& in) + { + using View = typename Accumulator::View; + const auto is_operation = View(in.avm_mem_rng_chk_sel); + const auto is_table_entry = View(in.avm_main_sel_rng_16); + return (is_operation + is_table_entry - is_operation * is_table_entry); + } + + /** + * @brief Get all the entities for the lookup when need to update them + * + * @details The generic structure of this tuple is described in ./generic_lookup_relation.hpp . The following is + description for the current case: + The entities are returned as a tuple of references in the following order (this is for ): + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that specifies how many times the lookup table entry at this row has been looked up + * - READ_TERMS entities/polynomials that enable individual lookup operations + * - The entity/polynomial that enables adding an entry to the lookup table in this row + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the basic tuple being looked up as the first read term + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the previous accumulators in the second read term + (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the shifts in the second read term (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing the current accumulators in the second read term + (scaled tuple) + * - LOOKUP_TUPLE_SIZE entities/polynomials representing basic tuples added to the table + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_mem_rng_chk_lo, + in.lookup_mem_rng_chk_lo_counts, + in.avm_mem_rng_chk_sel, + in.avm_main_sel_rng_16, + in.avm_mem_diff_lo, + in.avm_main_clk); + } + + /** + * @brief Get all the entities for the lookup when we only need to read them + * @details Same as in get_const_entities, but nonconst + * + * @return All the entities needed for the lookup + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.lookup_mem_rng_chk_lo, + in.lookup_mem_rng_chk_lo_counts, + in.avm_mem_rng_chk_sel, + in.avm_main_sel_rng_16, + in.avm_mem_diff_lo, + in.avm_main_clk); + } +}; + +template +using lookup_mem_rng_chk_lo_relation = GenericLookupRelation; +template using lookup_mem_rng_chk_lo = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp index 08691c39e83..4669bc3b46a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_helper.cpp @@ -1,4 +1,5 @@ #include "avm_helper.hpp" +#include "barretenberg/vm/avm_trace/avm_mem_trace.hpp" namespace bb::avm_trace { @@ -22,7 +23,8 @@ void log_avm_trace(std::vector const& trace, size_t beg, size_t end, bool e info("=======MEMORY TRACE=================================================================="); info("m_addr: ", trace.at(i).avm_mem_addr); info("m_clk: ", trace.at(i).avm_mem_clk); - info("m_sub_clk: ", trace.at(i).avm_mem_sub_clk); + info("m_tsp: ", trace.at(i).avm_mem_tsp); + info("m_sub_clk: ", uint32_t(trace.at(i).avm_mem_tsp) % AvmMemTraceBuilder::NUM_SUB_CLK); info("m_val: ", trace.at(i).avm_mem_val); info("m_rw: ", trace.at(i).avm_mem_rw); info("m_tag: ", trace.at(i).avm_mem_tag); @@ -72,6 +74,8 @@ void log_avm_trace(std::vector const& trace, size_t beg, size_t end, bool e info("mem_op_c: ", trace.at(i).avm_main_mem_op_c); info("mem_idx_c: ", trace.at(i).avm_main_mem_idx_c); info("rwc: ", trace.at(i).avm_main_rwc); + info("diff_hi: ", trace.at(i).avm_mem_diff_hi); + info("diff_lo: ", trace.at(i).avm_mem_diff_lo); if (enable_selectors) { info("=======SELECTORS======================================================================"); 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 f71de0c4136..80e2b4a31bb 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 @@ -20,6 +20,7 @@ class AvmMemTraceBuilder { 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; + static const uint32_t NUM_SUB_CLK = 12; // Keeps track of the number of times a mem tag err should appear in the trace // clk -> count 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 ff7cefbe1f8..39f54fe80b8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -1505,8 +1505,8 @@ void AvmTraceBuilder::finalise_mem_trace_lookup_counts() */ std::vector AvmTraceBuilder::finalize() { - bool const range_check_required = alu_trace_builder.is_range_check_required(); - + // bool const range_check_required = alu_trace_builder.is_range_check_required(); + bool const range_check_required = true; auto mem_trace = mem_trace_builder.finalize(); auto alu_trace = alu_trace_builder.finalize(); auto bin_trace = bin_trace_builder.finalize(); @@ -1518,6 +1518,10 @@ std::vector AvmTraceBuilder::finalize() // Get tag_err counts from the mem_trace_builder finalise_mem_trace_lookup_counts(); + // Data structure to collect all lookup counts pertaining to 32-bit range checks in memory trace + std::unordered_map mem_rng_check_lo_counts; + std::unordered_map mem_rng_check_hi_counts; + // Main Trace needs to be at least as big as the biggest subtrace. // If the bin_trace_size has entries, we need the main_trace to be as big as our byte lookup table (3 * 2**16 // long) @@ -1537,12 +1541,20 @@ std::vector AvmTraceBuilder::finalize() main_trace.at(*trace_size - 1).avm_main_last = FF(1); // Memory trace inclusion + + // We compute in the main loop the timestamp for next row. + // Perform initialization for index 0 outside of the loop provided that mem trace exists. + if (mem_trace_size > 0) { + main_trace.at(0).avm_mem_tsp = + FF(AvmMemTraceBuilder::NUM_SUB_CLK * mem_trace.at(0).m_clk + mem_trace.at(0).m_sub_clk); + } + for (size_t i = 0; i < mem_trace_size; i++) { auto const& src = mem_trace.at(i); auto& dest = main_trace.at(i); + dest.avm_mem_mem_sel = FF(1); dest.avm_mem_clk = FF(src.m_clk); - dest.avm_mem_sub_clk = FF(src.m_sub_clk); dest.avm_mem_addr = FF(src.m_addr); dest.avm_mem_val = src.m_val; dest.avm_mem_rw = FF(static_cast(src.m_rw)); @@ -1597,7 +1609,28 @@ std::vector AvmTraceBuilder::finalize() 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)); + auto& dest_next = main_trace.at(i + 1); + dest_next.avm_mem_tsp = FF(AvmMemTraceBuilder::NUM_SUB_CLK * next.m_clk + next.m_sub_clk); + + FF diff{}; + if (src.m_addr == next.m_addr) { + diff = dest_next.avm_mem_tsp - dest.avm_mem_tsp; + } else { + diff = next.m_addr - src.m_addr; + dest.avm_mem_lastAccess = FF(1); + } + dest.avm_mem_rng_chk_sel = FF(1); + + // Decomposition of diff + auto const diff_32 = uint32_t(diff); + auto const diff_hi = static_cast(diff_32 >> 16); + auto const diff_lo = static_cast(diff_32 & UINT16_MAX); + dest.avm_mem_diff_hi = FF(diff_hi); + dest.avm_mem_diff_lo = FF(diff_lo); + + // Add the range checks counts + mem_rng_check_hi_counts[diff_hi]++; + mem_rng_check_lo_counts[diff_lo]++; } else { dest.avm_mem_lastAccess = FF(1); dest.avm_mem_last = FF(1); @@ -1763,6 +1796,10 @@ std::vector AvmTraceBuilder::finalize() r.lookup_u16_12_counts = alu_trace_builder.u16_range_chk_counters[12][static_cast(i)]; r.lookup_u16_13_counts = alu_trace_builder.u16_range_chk_counters[13][static_cast(i)]; r.lookup_u16_14_counts = alu_trace_builder.u16_range_chk_counters[14][static_cast(i)]; + + r.lookup_mem_rng_chk_hi_counts = mem_rng_check_hi_counts[static_cast(i)]; + r.lookup_mem_rng_chk_lo_counts = mem_rng_check_lo_counts[static_cast(i)]; + r.avm_main_clk = FF(static_cast(i)); r.avm_main_sel_rng_16 = FF(1); } @@ -1826,6 +1863,7 @@ std::vector AvmTraceBuilder::finalize() bin_trace_builder.byte_length_counter[avm_in_tag + 1]; } } + // Adding extra row for the shifted values at the top of the execution trace. Row first_row = Row{ .avm_main_first = FF(1), .avm_mem_lastAccess = FF(1) }; main_trace.insert(main_trace.begin(), first_row); 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 f7e89924259..8e46d8e00f4 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_circuit_builder.hpp @@ -19,6 +19,8 @@ #include "barretenberg/relations/generated/avm/incl_mem_tag_err.hpp" #include "barretenberg/relations/generated/avm/lookup_byte_lengths.hpp" #include "barretenberg/relations/generated/avm/lookup_byte_operations.hpp" +#include "barretenberg/relations/generated/avm/lookup_mem_rng_chk_hi.hpp" +#include "barretenberg/relations/generated/avm/lookup_mem_rng_chk_lo.hpp" #include "barretenberg/relations/generated/avm/lookup_pow_2_0.hpp" #include "barretenberg/relations/generated/avm/lookup_pow_2_1.hpp" #include "barretenberg/relations/generated/avm/lookup_u16_0.hpp" @@ -205,26 +207,30 @@ template struct AvmFullRow { FF avm_main_w_in_tag{}; FF avm_mem_addr{}; FF avm_mem_clk{}; + FF avm_mem_diff_hi{}; + FF avm_mem_diff_lo{}; 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_mem_sel{}; 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_rng_chk_sel{}; FF avm_mem_rw{}; 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{}; + FF avm_mem_tsp{}; FF avm_mem_val{}; FF avm_mem_w_in_tag{}; FF perm_main_alu{}; @@ -241,6 +247,8 @@ template struct AvmFullRow { FF lookup_byte_operations{}; FF incl_main_tag_err{}; FF incl_mem_tag_err{}; + FF lookup_mem_rng_chk_lo{}; + FF lookup_mem_rng_chk_hi{}; FF lookup_pow_2_0{}; FF lookup_pow_2_1{}; FF lookup_u8_0{}; @@ -264,6 +272,8 @@ template struct AvmFullRow { FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; + FF lookup_mem_rng_chk_lo_counts{}; + FF lookup_mem_rng_chk_hi_counts{}; FF lookup_pow_2_0_counts{}; FF lookup_pow_2_1_counts{}; FF lookup_u8_0_counts{}; @@ -320,8 +330,10 @@ template struct AvmFullRow { FF avm_main_internal_return_ptr_shift{}; FF avm_main_pc_shift{}; FF avm_mem_addr_shift{}; + FF avm_mem_mem_sel_shift{}; FF avm_mem_rw_shift{}; FF avm_mem_tag_shift{}; + FF avm_mem_tsp_shift{}; FF avm_mem_val_shift{}; }; @@ -335,8 +347,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 270; - static constexpr size_t num_polys = 230; + static constexpr size_t num_fixed_columns = 280; + static constexpr size_t num_polys = 238; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -504,32 +516,38 @@ class AvmCircuitBuilder { polys.avm_main_w_in_tag[i] = rows[i].avm_main_w_in_tag; polys.avm_mem_addr[i] = rows[i].avm_mem_addr; polys.avm_mem_clk[i] = rows[i].avm_mem_clk; + polys.avm_mem_diff_hi[i] = rows[i].avm_mem_diff_hi; + polys.avm_mem_diff_lo[i] = rows[i].avm_mem_diff_lo; 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_mem_sel[i] = rows[i].avm_mem_mem_sel; 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_rng_chk_sel[i] = rows[i].avm_mem_rng_chk_sel; polys.avm_mem_rw[i] = rows[i].avm_mem_rw; 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; + polys.avm_mem_tsp[i] = rows[i].avm_mem_tsp; polys.avm_mem_val[i] = rows[i].avm_mem_val; polys.avm_mem_w_in_tag[i] = rows[i].avm_mem_w_in_tag; polys.lookup_byte_lengths_counts[i] = rows[i].lookup_byte_lengths_counts; polys.lookup_byte_operations_counts[i] = rows[i].lookup_byte_operations_counts; polys.incl_main_tag_err_counts[i] = rows[i].incl_main_tag_err_counts; polys.incl_mem_tag_err_counts[i] = rows[i].incl_mem_tag_err_counts; + polys.lookup_mem_rng_chk_lo_counts[i] = rows[i].lookup_mem_rng_chk_lo_counts; + polys.lookup_mem_rng_chk_hi_counts[i] = rows[i].lookup_mem_rng_chk_hi_counts; polys.lookup_pow_2_0_counts[i] = rows[i].lookup_pow_2_0_counts; polys.lookup_pow_2_1_counts[i] = rows[i].lookup_pow_2_1_counts; polys.lookup_u8_0_counts[i] = rows[i].lookup_u8_0_counts; @@ -588,8 +606,10 @@ class AvmCircuitBuilder { polys.avm_main_internal_return_ptr_shift = Polynomial(polys.avm_main_internal_return_ptr.shifted()); polys.avm_main_pc_shift = Polynomial(polys.avm_main_pc.shifted()); polys.avm_mem_addr_shift = Polynomial(polys.avm_mem_addr.shifted()); + polys.avm_mem_mem_sel_shift = Polynomial(polys.avm_mem_mem_sel.shifted()); polys.avm_mem_rw_shift = Polynomial(polys.avm_mem_rw.shifted()); polys.avm_mem_tag_shift = Polynomial(polys.avm_mem_tag.shifted()); + polys.avm_mem_tsp_shift = Polynomial(polys.avm_mem_tsp.shifted()); polys.avm_mem_val_shift = Polynomial(polys.avm_mem_val.shifted()); return polys; @@ -722,6 +742,12 @@ class AvmCircuitBuilder { if (!evaluate_logderivative.template operator()>("INCL_MEM_TAG_ERR")) { return false; } + if (!evaluate_logderivative.template operator()>("LOOKUP_MEM_RNG_CHK_LO")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_MEM_RNG_CHK_HI")) { + return false; + } if (!evaluate_logderivative.template operator()>("LOOKUP_POW_2_0")) { 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 1f16a50834d..e55fbc4dc80 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -21,6 +21,8 @@ #include "barretenberg/relations/generated/avm/incl_mem_tag_err.hpp" #include "barretenberg/relations/generated/avm/lookup_byte_lengths.hpp" #include "barretenberg/relations/generated/avm/lookup_byte_operations.hpp" +#include "barretenberg/relations/generated/avm/lookup_mem_rng_chk_hi.hpp" +#include "barretenberg/relations/generated/avm/lookup_mem_rng_chk_lo.hpp" #include "barretenberg/relations/generated/avm/lookup_pow_2_0.hpp" #include "barretenberg/relations/generated/avm/lookup_pow_2_1.hpp" #include "barretenberg/relations/generated/avm/lookup_u16_0.hpp" @@ -71,11 +73,11 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 228; + static constexpr size_t NUM_WITNESS_ENTITIES = 236; 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 = 270; + static constexpr size_t NUM_ALL_ENTITIES = 280; using GrandProductRelations = std::tuple, perm_main_bin_relation, @@ -91,6 +93,8 @@ class AvmFlavor { lookup_byte_operations_relation, incl_main_tag_err_relation, incl_mem_tag_err_relation, + lookup_mem_rng_chk_lo_relation, + lookup_mem_rng_chk_hi_relation, lookup_pow_2_0_relation, lookup_pow_2_1_relation, lookup_u8_0_relation, @@ -129,6 +133,8 @@ class AvmFlavor { lookup_byte_operations_relation, incl_main_tag_err_relation, incl_mem_tag_err_relation, + lookup_mem_rng_chk_lo_relation, + lookup_mem_rng_chk_hi_relation, lookup_pow_2_0_relation, lookup_pow_2_1_relation, lookup_u8_0_relation, @@ -331,26 +337,30 @@ class AvmFlavor { avm_main_w_in_tag, avm_mem_addr, avm_mem_clk, + avm_mem_diff_hi, + avm_mem_diff_lo, 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_mem_sel, 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_rng_chk_sel, avm_mem_rw, 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, + avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, perm_main_alu, @@ -367,6 +377,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_mem_rng_chk_lo, + lookup_mem_rng_chk_hi, lookup_pow_2_0, lookup_pow_2_1, lookup_u8_0, @@ -390,6 +402,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_mem_rng_chk_lo_counts, + lookup_mem_rng_chk_hi_counts, lookup_pow_2_0_counts, lookup_pow_2_1_counts, lookup_u8_0_counts, @@ -562,26 +576,30 @@ class AvmFlavor { avm_main_w_in_tag, avm_mem_addr, avm_mem_clk, + avm_mem_diff_hi, + avm_mem_diff_lo, 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_mem_sel, 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_rng_chk_sel, avm_mem_rw, 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, + avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, perm_main_alu, @@ -598,6 +616,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_mem_rng_chk_lo, + lookup_mem_rng_chk_hi, lookup_pow_2_0, lookup_pow_2_1, lookup_u8_0, @@ -621,6 +641,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_mem_rng_chk_lo_counts, + lookup_mem_rng_chk_hi_counts, lookup_pow_2_0_counts, lookup_pow_2_1_counts, lookup_u8_0_counts, @@ -798,26 +820,30 @@ class AvmFlavor { avm_main_w_in_tag, avm_mem_addr, avm_mem_clk, + avm_mem_diff_hi, + avm_mem_diff_lo, 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_mem_sel, 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_rng_chk_sel, avm_mem_rw, 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, + avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, perm_main_alu, @@ -834,6 +860,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_mem_rng_chk_lo, + lookup_mem_rng_chk_hi, lookup_pow_2_0, lookup_pow_2_1, lookup_u8_0, @@ -857,6 +885,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_mem_rng_chk_lo_counts, + lookup_mem_rng_chk_hi_counts, lookup_pow_2_0_counts, lookup_pow_2_1_counts, lookup_u8_0_counts, @@ -913,8 +943,10 @@ class AvmFlavor { avm_main_internal_return_ptr_shift, avm_main_pc_shift, avm_mem_addr_shift, + avm_mem_mem_sel_shift, avm_mem_rw_shift, avm_mem_tag_shift, + avm_mem_tsp_shift, avm_mem_val_shift) RefVector get_wires() @@ -1071,26 +1103,30 @@ class AvmFlavor { avm_main_w_in_tag, avm_mem_addr, avm_mem_clk, + avm_mem_diff_hi, + avm_mem_diff_lo, 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_mem_sel, 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_rng_chk_sel, avm_mem_rw, 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, + avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, perm_main_alu, @@ -1107,6 +1143,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_mem_rng_chk_lo, + lookup_mem_rng_chk_hi, lookup_pow_2_0, lookup_pow_2_1, lookup_u8_0, @@ -1130,6 +1168,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_mem_rng_chk_lo_counts, + lookup_mem_rng_chk_hi_counts, lookup_pow_2_0_counts, lookup_pow_2_1_counts, lookup_u8_0_counts, @@ -1186,8 +1226,10 @@ class AvmFlavor { avm_main_internal_return_ptr_shift, avm_main_pc_shift, avm_mem_addr_shift, + avm_mem_mem_sel_shift, avm_mem_rw_shift, avm_mem_tag_shift, + avm_mem_tsp_shift, avm_mem_val_shift }; }; RefVector get_unshifted() @@ -1344,26 +1386,30 @@ class AvmFlavor { avm_main_w_in_tag, avm_mem_addr, avm_mem_clk, + avm_mem_diff_hi, + avm_mem_diff_lo, 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_mem_sel, 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_rng_chk_sel, avm_mem_rw, 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, + avm_mem_tsp, avm_mem_val, avm_mem_w_in_tag, perm_main_alu, @@ -1380,6 +1426,8 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_mem_rng_chk_lo, + lookup_mem_rng_chk_hi, lookup_pow_2_0, lookup_pow_2_1, lookup_u8_0, @@ -1403,6 +1451,8 @@ class AvmFlavor { lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_mem_rng_chk_lo_counts, + lookup_mem_rng_chk_hi_counts, lookup_pow_2_0_counts, lookup_pow_2_1_counts, lookup_u8_0_counts, @@ -1462,8 +1512,10 @@ class AvmFlavor { avm_main_internal_return_ptr, avm_main_pc, avm_mem_addr, + avm_mem_mem_sel, avm_mem_rw, avm_mem_tag, + avm_mem_tsp, avm_mem_val }; }; RefVector get_shifted() @@ -1505,8 +1557,10 @@ class AvmFlavor { avm_main_internal_return_ptr_shift, avm_main_pc_shift, avm_mem_addr_shift, + avm_mem_mem_sel_shift, avm_mem_rw_shift, avm_mem_tag_shift, + avm_mem_tsp_shift, avm_mem_val_shift }; }; }; @@ -1557,8 +1611,10 @@ class AvmFlavor { avm_main_internal_return_ptr, avm_main_pc, avm_mem_addr, + avm_mem_mem_sel, avm_mem_rw, avm_mem_tag, + avm_mem_tsp, avm_mem_val }; }; @@ -1594,6 +1650,10 @@ 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>( @@ -1876,26 +1936,30 @@ class AvmFlavor { Base::avm_main_w_in_tag = "AVM_MAIN_W_IN_TAG"; Base::avm_mem_addr = "AVM_MEM_ADDR"; Base::avm_mem_clk = "AVM_MEM_CLK"; + Base::avm_mem_diff_hi = "AVM_MEM_DIFF_HI"; + Base::avm_mem_diff_lo = "AVM_MEM_DIFF_LO"; 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_mem_sel = "AVM_MEM_MEM_SEL"; 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_rng_chk_sel = "AVM_MEM_RNG_CHK_SEL"; Base::avm_mem_rw = "AVM_MEM_RW"; 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"; + Base::avm_mem_tsp = "AVM_MEM_TSP"; Base::avm_mem_val = "AVM_MEM_VAL"; Base::avm_mem_w_in_tag = "AVM_MEM_W_IN_TAG"; Base::perm_main_alu = "PERM_MAIN_ALU"; @@ -1912,6 +1976,8 @@ class AvmFlavor { Base::lookup_byte_operations = "LOOKUP_BYTE_OPERATIONS"; Base::incl_main_tag_err = "INCL_MAIN_TAG_ERR"; Base::incl_mem_tag_err = "INCL_MEM_TAG_ERR"; + Base::lookup_mem_rng_chk_lo = "LOOKUP_MEM_RNG_CHK_LO"; + Base::lookup_mem_rng_chk_hi = "LOOKUP_MEM_RNG_CHK_HI"; Base::lookup_pow_2_0 = "LOOKUP_POW_2_0"; Base::lookup_pow_2_1 = "LOOKUP_POW_2_1"; Base::lookup_u8_0 = "LOOKUP_U8_0"; @@ -1935,6 +2001,8 @@ class AvmFlavor { Base::lookup_byte_operations_counts = "LOOKUP_BYTE_OPERATIONS_COUNTS"; Base::incl_main_tag_err_counts = "INCL_MAIN_TAG_ERR_COUNTS"; Base::incl_mem_tag_err_counts = "INCL_MEM_TAG_ERR_COUNTS"; + Base::lookup_mem_rng_chk_lo_counts = "LOOKUP_MEM_RNG_CHK_LO_COUNTS"; + Base::lookup_mem_rng_chk_hi_counts = "LOOKUP_MEM_RNG_CHK_HI_COUNTS"; Base::lookup_pow_2_0_counts = "LOOKUP_POW_2_0_COUNTS"; Base::lookup_pow_2_1_counts = "LOOKUP_POW_2_1_COUNTS"; Base::lookup_u8_0_counts = "LOOKUP_U8_0_COUNTS"; @@ -2123,26 +2191,30 @@ class AvmFlavor { Commitment avm_main_w_in_tag; Commitment avm_mem_addr; Commitment avm_mem_clk; + Commitment avm_mem_diff_hi; + Commitment avm_mem_diff_lo; 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_mem_sel; 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_rng_chk_sel; Commitment avm_mem_rw; 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; + Commitment avm_mem_tsp; Commitment avm_mem_val; Commitment avm_mem_w_in_tag; Commitment perm_main_alu; @@ -2159,6 +2231,8 @@ class AvmFlavor { Commitment lookup_byte_operations; Commitment incl_main_tag_err; Commitment incl_mem_tag_err; + Commitment lookup_mem_rng_chk_lo; + Commitment lookup_mem_rng_chk_hi; Commitment lookup_pow_2_0; Commitment lookup_pow_2_1; Commitment lookup_u8_0; @@ -2182,6 +2256,8 @@ class AvmFlavor { Commitment lookup_byte_operations_counts; Commitment incl_main_tag_err_counts; Commitment incl_mem_tag_err_counts; + Commitment lookup_mem_rng_chk_lo_counts; + Commitment lookup_mem_rng_chk_hi_counts; Commitment lookup_pow_2_0_counts; Commitment lookup_pow_2_1_counts; Commitment lookup_u8_0_counts; @@ -2371,26 +2447,30 @@ class AvmFlavor { avm_main_w_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_addr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_clk = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_diff_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_mem_diff_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); 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_mem_sel = 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_rng_chk_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_rw = 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); + avm_mem_tsp = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_val = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_mem_w_in_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); perm_main_alu = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2407,6 +2487,8 @@ class AvmFlavor { 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); incl_mem_tag_err = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_mem_rng_chk_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_mem_rng_chk_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_pow_2_0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_pow_2_1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u8_0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2430,6 +2512,8 @@ class AvmFlavor { lookup_byte_operations_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_main_tag_err_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); incl_mem_tag_err_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_mem_rng_chk_lo_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_mem_rng_chk_hi_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_pow_2_0_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_pow_2_1_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_u8_0_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -2622,26 +2706,30 @@ class AvmFlavor { serialize_to_buffer(avm_main_w_in_tag, Transcript::proof_data); serialize_to_buffer(avm_mem_addr, Transcript::proof_data); serialize_to_buffer(avm_mem_clk, Transcript::proof_data); + serialize_to_buffer(avm_mem_diff_hi, Transcript::proof_data); + serialize_to_buffer(avm_mem_diff_lo, Transcript::proof_data); 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_mem_sel, 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_rng_chk_sel, Transcript::proof_data); serialize_to_buffer(avm_mem_rw, 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); + serialize_to_buffer(avm_mem_tsp, Transcript::proof_data); serialize_to_buffer(avm_mem_val, Transcript::proof_data); serialize_to_buffer(avm_mem_w_in_tag, Transcript::proof_data); serialize_to_buffer(perm_main_alu, Transcript::proof_data); @@ -2658,6 +2746,8 @@ class AvmFlavor { serialize_to_buffer(lookup_byte_operations, Transcript::proof_data); serialize_to_buffer(incl_main_tag_err, Transcript::proof_data); serialize_to_buffer(incl_mem_tag_err, Transcript::proof_data); + serialize_to_buffer(lookup_mem_rng_chk_lo, Transcript::proof_data); + serialize_to_buffer(lookup_mem_rng_chk_hi, Transcript::proof_data); serialize_to_buffer(lookup_pow_2_0, Transcript::proof_data); serialize_to_buffer(lookup_pow_2_1, Transcript::proof_data); serialize_to_buffer(lookup_u8_0, Transcript::proof_data); @@ -2681,6 +2771,8 @@ class AvmFlavor { serialize_to_buffer(lookup_byte_operations_counts, Transcript::proof_data); serialize_to_buffer(incl_main_tag_err_counts, Transcript::proof_data); serialize_to_buffer(incl_mem_tag_err_counts, Transcript::proof_data); + serialize_to_buffer(lookup_mem_rng_chk_lo_counts, Transcript::proof_data); + serialize_to_buffer(lookup_mem_rng_chk_hi_counts, Transcript::proof_data); serialize_to_buffer(lookup_pow_2_0_counts, Transcript::proof_data); serialize_to_buffer(lookup_pow_2_1_counts, Transcript::proof_data); serialize_to_buffer(lookup_u8_0_counts, 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 70a86ca3414..064a1e7e3ac 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp @@ -210,32 +210,38 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_main_w_in_tag = commitment_key->commit(key->avm_main_w_in_tag); witness_commitments.avm_mem_addr = commitment_key->commit(key->avm_mem_addr); witness_commitments.avm_mem_clk = commitment_key->commit(key->avm_mem_clk); + witness_commitments.avm_mem_diff_hi = commitment_key->commit(key->avm_mem_diff_hi); + witness_commitments.avm_mem_diff_lo = commitment_key->commit(key->avm_mem_diff_lo); 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_mem_sel = commitment_key->commit(key->avm_mem_mem_sel); 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_rng_chk_sel = commitment_key->commit(key->avm_mem_rng_chk_sel); witness_commitments.avm_mem_rw = commitment_key->commit(key->avm_mem_rw); 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); + witness_commitments.avm_mem_tsp = commitment_key->commit(key->avm_mem_tsp); witness_commitments.avm_mem_val = commitment_key->commit(key->avm_mem_val); witness_commitments.avm_mem_w_in_tag = commitment_key->commit(key->avm_mem_w_in_tag); witness_commitments.lookup_byte_lengths_counts = commitment_key->commit(key->lookup_byte_lengths_counts); witness_commitments.lookup_byte_operations_counts = commitment_key->commit(key->lookup_byte_operations_counts); witness_commitments.incl_main_tag_err_counts = commitment_key->commit(key->incl_main_tag_err_counts); witness_commitments.incl_mem_tag_err_counts = commitment_key->commit(key->incl_mem_tag_err_counts); + witness_commitments.lookup_mem_rng_chk_lo_counts = commitment_key->commit(key->lookup_mem_rng_chk_lo_counts); + witness_commitments.lookup_mem_rng_chk_hi_counts = commitment_key->commit(key->lookup_mem_rng_chk_hi_counts); witness_commitments.lookup_pow_2_0_counts = commitment_key->commit(key->lookup_pow_2_0_counts); witness_commitments.lookup_pow_2_1_counts = commitment_key->commit(key->lookup_pow_2_1_counts); witness_commitments.lookup_u8_0_counts = commitment_key->commit(key->lookup_u8_0_counts); @@ -421,26 +427,30 @@ void AvmProver::execute_wire_commitments_round() transcript->send_to_verifier(commitment_labels.avm_main_w_in_tag, witness_commitments.avm_main_w_in_tag); transcript->send_to_verifier(commitment_labels.avm_mem_addr, witness_commitments.avm_mem_addr); transcript->send_to_verifier(commitment_labels.avm_mem_clk, witness_commitments.avm_mem_clk); + transcript->send_to_verifier(commitment_labels.avm_mem_diff_hi, witness_commitments.avm_mem_diff_hi); + transcript->send_to_verifier(commitment_labels.avm_mem_diff_lo, witness_commitments.avm_mem_diff_lo); 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_mem_sel, witness_commitments.avm_mem_mem_sel); 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_rng_chk_sel, witness_commitments.avm_mem_rng_chk_sel); transcript->send_to_verifier(commitment_labels.avm_mem_rw, witness_commitments.avm_mem_rw); 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); + transcript->send_to_verifier(commitment_labels.avm_mem_tsp, witness_commitments.avm_mem_tsp); transcript->send_to_verifier(commitment_labels.avm_mem_val, witness_commitments.avm_mem_val); transcript->send_to_verifier(commitment_labels.avm_mem_w_in_tag, witness_commitments.avm_mem_w_in_tag); transcript->send_to_verifier(commitment_labels.lookup_byte_lengths_counts, @@ -451,6 +461,10 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.incl_main_tag_err_counts); transcript->send_to_verifier(commitment_labels.incl_mem_tag_err_counts, witness_commitments.incl_mem_tag_err_counts); + transcript->send_to_verifier(commitment_labels.lookup_mem_rng_chk_lo_counts, + witness_commitments.lookup_mem_rng_chk_lo_counts); + transcript->send_to_verifier(commitment_labels.lookup_mem_rng_chk_hi_counts, + witness_commitments.lookup_mem_rng_chk_hi_counts); transcript->send_to_verifier(commitment_labels.lookup_pow_2_0_counts, witness_commitments.lookup_pow_2_0_counts); transcript->send_to_verifier(commitment_labels.lookup_pow_2_1_counts, witness_commitments.lookup_pow_2_1_counts); transcript->send_to_verifier(commitment_labels.lookup_u8_0_counts, witness_commitments.lookup_u8_0_counts); @@ -496,6 +510,8 @@ void AvmProver::execute_log_derivative_inverse_round() 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); witness_commitments.incl_mem_tag_err = commitment_key->commit(key->incl_mem_tag_err); + witness_commitments.lookup_mem_rng_chk_lo = commitment_key->commit(key->lookup_mem_rng_chk_lo); + witness_commitments.lookup_mem_rng_chk_hi = commitment_key->commit(key->lookup_mem_rng_chk_hi); witness_commitments.lookup_pow_2_0 = commitment_key->commit(key->lookup_pow_2_0); witness_commitments.lookup_pow_2_1 = commitment_key->commit(key->lookup_pow_2_1); witness_commitments.lookup_u8_0 = commitment_key->commit(key->lookup_u8_0); @@ -531,6 +547,8 @@ void AvmProver::execute_log_derivative_inverse_round() 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); transcript->send_to_verifier(commitment_labels.incl_mem_tag_err, witness_commitments.incl_mem_tag_err); + transcript->send_to_verifier(commitment_labels.lookup_mem_rng_chk_lo, witness_commitments.lookup_mem_rng_chk_lo); + transcript->send_to_verifier(commitment_labels.lookup_mem_rng_chk_hi, witness_commitments.lookup_mem_rng_chk_hi); transcript->send_to_verifier(commitment_labels.lookup_pow_2_0, witness_commitments.lookup_pow_2_0); transcript->send_to_verifier(commitment_labels.lookup_pow_2_1, witness_commitments.lookup_pow_2_1); transcript->send_to_verifier(commitment_labels.lookup_u8_0, witness_commitments.lookup_u8_0); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index e71a0cf8833..89f357cc400 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -296,6 +296,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_main_w_in_tag); commitments.avm_mem_addr = transcript->template receive_from_prover(commitment_labels.avm_mem_addr); commitments.avm_mem_clk = transcript->template receive_from_prover(commitment_labels.avm_mem_clk); + commitments.avm_mem_diff_hi = + transcript->template receive_from_prover(commitment_labels.avm_mem_diff_hi); + commitments.avm_mem_diff_lo = + transcript->template receive_from_prover(commitment_labels.avm_mem_diff_lo); commitments.avm_mem_ind_op_a = transcript->template receive_from_prover(commitment_labels.avm_mem_ind_op_a); commitments.avm_mem_ind_op_b = @@ -307,6 +311,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) 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); + commitments.avm_mem_mem_sel = + transcript->template receive_from_prover(commitment_labels.avm_mem_mem_sel); commitments.avm_mem_one_min_inv = transcript->template receive_from_prover(commitment_labels.avm_mem_one_min_inv); commitments.avm_mem_op_a = transcript->template receive_from_prover(commitment_labels.avm_mem_op_a); @@ -315,6 +321,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) 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_rng_chk_sel = + transcript->template receive_from_prover(commitment_labels.avm_mem_rng_chk_sel); commitments.avm_mem_rw = transcript->template receive_from_prover(commitment_labels.avm_mem_rw); commitments.avm_mem_sel_cmov = transcript->template receive_from_prover(commitment_labels.avm_mem_sel_cmov); @@ -324,11 +332,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) 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); commitments.avm_mem_tag_err = transcript->template receive_from_prover(commitment_labels.avm_mem_tag_err); + commitments.avm_mem_tsp = transcript->template receive_from_prover(commitment_labels.avm_mem_tsp); commitments.avm_mem_val = transcript->template receive_from_prover(commitment_labels.avm_mem_val); commitments.avm_mem_w_in_tag = transcript->template receive_from_prover(commitment_labels.avm_mem_w_in_tag); @@ -340,6 +347,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.incl_main_tag_err_counts); commitments.incl_mem_tag_err_counts = transcript->template receive_from_prover(commitment_labels.incl_mem_tag_err_counts); + commitments.lookup_mem_rng_chk_lo_counts = + transcript->template receive_from_prover(commitment_labels.lookup_mem_rng_chk_lo_counts); + commitments.lookup_mem_rng_chk_hi_counts = + transcript->template receive_from_prover(commitment_labels.lookup_mem_rng_chk_hi_counts); commitments.lookup_pow_2_0_counts = transcript->template receive_from_prover(commitment_labels.lookup_pow_2_0_counts); commitments.lookup_pow_2_1_counts = @@ -410,6 +421,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.incl_main_tag_err); commitments.incl_mem_tag_err = transcript->template receive_from_prover(commitment_labels.incl_mem_tag_err); + commitments.lookup_mem_rng_chk_lo = + transcript->template receive_from_prover(commitment_labels.lookup_mem_rng_chk_lo); + commitments.lookup_mem_rng_chk_hi = + transcript->template receive_from_prover(commitment_labels.lookup_mem_rng_chk_hi); commitments.lookup_pow_2_0 = transcript->template receive_from_prover(commitment_labels.lookup_pow_2_0); commitments.lookup_pow_2_1 = transcript->template receive_from_prover(commitment_labels.lookup_pow_2_1); commitments.lookup_u8_0 = transcript->template receive_from_prover(commitment_labels.lookup_u8_0); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp index 6ae97a8bfd5..09791115ca4 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp @@ -353,7 +353,6 @@ TEST_F(AvmArithmeticTestsFF, subtraction) EXPECT_EQ(alu_row.avm_alu_cf, FF(0)); EXPECT_EQ(alu_row.avm_alu_u8_r0, FF(0)); - avm_trace::log_avm_trace(trace, 0, 10); validate_trace(std::move(trace)); } diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_cast.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_cast.test.cpp index c31805f6fca..8991c8d6bbe 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_cast.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_cast.test.cpp @@ -44,7 +44,7 @@ class AvmCastTests : public ::testing::Test { // Mem entry output ic write operation auto mem_row_c = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_STORE_C; + return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_STORE_C; }); ASSERT_TRUE(mem_row_c != trace.end()); mem_idx_c = static_cast(mem_row_c - trace.begin()); diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp index 0e7fdce2205..17f77cfd152 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_inter_table.test.cpp @@ -469,7 +469,7 @@ TEST_F(AvmPermMainMemNegativeTests, tagErrNotCopiedInMain) row->avm_main_ic = 1; // Find the memory row pertaining to write operation from Ic. auto mem_row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_STORE_C; + return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_STORE_C; }); // Adjust the output in the memory trace. @@ -572,8 +572,13 @@ TEST_F(AvmPermMainMemNegativeTests, wrongRwIaInMem) executeSub(21, 3); trace.at(mem_idx_a).avm_mem_rw = 1; // Write instead of read. - // Adjust sub_clk value - trace.at(mem_idx_a).avm_mem_sub_clk = AvmMemTraceBuilder::SUB_CLK_STORE_A; + // Adjust timestamp value + trace.at(mem_idx_a).avm_mem_tsp += FF(AvmMemTraceBuilder::SUB_CLK_STORE_A - AvmMemTraceBuilder::SUB_CLK_LOAD_A); + // Adjust diff value of previous row as well + FF diff = trace.at(mem_idx_a - 1).avm_mem_diff_lo + trace.at(mem_idx_a - 1).avm_mem_diff_hi * FF(1 << 16) + + FF(AvmMemTraceBuilder::SUB_CLK_STORE_A - AvmMemTraceBuilder::SUB_CLK_LOAD_A); + trace.at(mem_idx_a - 1).avm_mem_diff_hi = FF(uint32_t(diff) >> 16); + trace.at(mem_idx_a - 1).avm_mem_diff_lo = FF(uint32_t(diff) & UINT16_MAX); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "PERM_MAIN_MEM_A"); } @@ -583,8 +588,13 @@ TEST_F(AvmPermMainMemNegativeTests, wrongRwIbInMem) executeSub(21, 3); trace.at(mem_idx_b).avm_mem_rw = 1; // Write instead of read. - // Adjust sub_clk value - trace.at(mem_idx_b).avm_mem_sub_clk = AvmMemTraceBuilder::SUB_CLK_STORE_B; + // Adjust timestamp value + trace.at(mem_idx_b).avm_mem_tsp += FF(AvmMemTraceBuilder::SUB_CLK_STORE_B - AvmMemTraceBuilder::SUB_CLK_LOAD_B); + // Adjust diff value of previous row as well + FF diff = trace.at(mem_idx_b - 1).avm_mem_diff_lo + trace.at(mem_idx_b - 1).avm_mem_diff_hi * FF(1 << 16) + + FF(AvmMemTraceBuilder::SUB_CLK_STORE_B - AvmMemTraceBuilder::SUB_CLK_LOAD_B); + trace.at(mem_idx_b - 1).avm_mem_diff_hi = FF(uint32_t(diff) >> 16); + trace.at(mem_idx_b - 1).avm_mem_diff_lo = FF(uint32_t(diff) & UINT16_MAX); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "PERM_MAIN_MEM_B"); } @@ -597,8 +607,8 @@ TEST_F(AvmPermMainMemNegativeTests, wrongRwIcInMem) executeSub(11, 11); trace.at(mem_idx_c).avm_mem_rw = 0; // Read instead of write. - // Adjust sub_clk value - trace.at(mem_idx_c).avm_mem_sub_clk = AvmMemTraceBuilder::SUB_CLK_LOAD_C; + // Adjust timestamp value. + trace.at(mem_idx_c).avm_mem_tsp -= FF(AvmMemTraceBuilder::SUB_CLK_STORE_C - AvmMemTraceBuilder::SUB_CLK_LOAD_C); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "PERM_MAIN_MEM_C"); } @@ -606,7 +616,13 @@ TEST_F(AvmPermMainMemNegativeTests, wrongRwIcInMem) TEST_F(AvmPermMainMemNegativeTests, wrongClkIaInMem) { executeSub(87, 23); - trace.at(mem_idx_a).avm_mem_clk = 11; + trace.at(mem_idx_a).avm_mem_clk += 3; + trace.at(mem_idx_a).avm_mem_tsp += AvmMemTraceBuilder::NUM_SUB_CLK * 3; + // Adjust diff value of previous row as well + FF diff = trace.at(mem_idx_a - 1).avm_mem_diff_lo + trace.at(mem_idx_a - 1).avm_mem_diff_hi * FF(1 << 16) + + FF(AvmMemTraceBuilder::NUM_SUB_CLK * 3); + trace.at(mem_idx_a - 1).avm_mem_diff_hi = FF(uint32_t(diff) >> 16); + trace.at(mem_idx_a - 1).avm_mem_diff_lo = FF(uint32_t(diff) & UINT16_MAX); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "PERM_MAIN_MEM_A"); } @@ -614,7 +630,12 @@ TEST_F(AvmPermMainMemNegativeTests, wrongClkIaInMem) TEST_F(AvmPermMainMemNegativeTests, wrongClkIbInMem) { executeSub(87, 23); - trace.at(mem_idx_b).avm_mem_clk = 21; + trace.at(mem_idx_b).avm_mem_clk += 5; + trace.at(mem_idx_b).avm_mem_tsp += AvmMemTraceBuilder::NUM_SUB_CLK * 5; + FF diff = trace.at(mem_idx_b - 1).avm_mem_diff_lo + trace.at(mem_idx_b - 1).avm_mem_diff_hi * FF(1 << 16) + + FF(AvmMemTraceBuilder::NUM_SUB_CLK * 5); + trace.at(mem_idx_b - 1).avm_mem_diff_hi = FF(uint32_t(diff) >> 16); + trace.at(mem_idx_b - 1).avm_mem_diff_lo = FF(uint32_t(diff) & UINT16_MAX); EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "PERM_MAIN_MEM_B"); } @@ -622,7 +643,8 @@ TEST_F(AvmPermMainMemNegativeTests, wrongClkIbInMem) TEST_F(AvmPermMainMemNegativeTests, wrongClkIcInMem) { executeSub(87, 23); - trace.at(mem_idx_c).avm_mem_clk = 7; + trace.at(mem_idx_c).avm_mem_clk += 7; + trace.at(mem_idx_c).avm_mem_tsp += AvmMemTraceBuilder::NUM_SUB_CLK * 7; EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "PERM_MAIN_MEM_C"); } diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_mem_opcodes.test.cpp index b02ee50d2ec..59e0ac2497a 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 @@ -65,7 +65,7 @@ class AvmMemOpcodeTests : public ::testing::Test { 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; }; + return [clk, sub_clk](Row r) { return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + sub_clk; }; }; void compute_index_a(FF clk, bool indirect) diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp index 95c364acd05..e2f95c50d07 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_memory.test.cpp @@ -49,7 +49,7 @@ TEST_F(AvmMemoryTests, mismatchedTagAddOperation) // Find the memory trace position corresponding to the load sub-operation of register ia. row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_A; + return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_LOAD_A; }); EXPECT_TRUE(row != trace.end()); @@ -60,7 +60,7 @@ TEST_F(AvmMemoryTests, mismatchedTagAddOperation) // Find the memory trace position corresponding to the add sub-operation of register ib. row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_B; + return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_LOAD_B; }); EXPECT_TRUE(row != trace.end()); @@ -92,7 +92,7 @@ TEST_F(AvmMemoryTests, mismatchedTagEqOperation) // Find the memory trace position corresponding to the load sub-operation of register ia. row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_A; + return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_LOAD_A; }); EXPECT_TRUE(row != trace.end()); @@ -103,7 +103,7 @@ TEST_F(AvmMemoryTests, mismatchedTagEqOperation) // Find the memory trace position corresponding to the load sub-operation of register ib. row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_B; + return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_LOAD_B; }); EXPECT_TRUE(row != trace.end()); @@ -135,8 +135,8 @@ TEST_F(AvmMemoryTests, mLastAccessViolation) // Find the row for memory trace with last memory entry for address 1 (read for subtraction) row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_addr == FF(1) && - r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_A; + return r.avm_mem_addr == FF(1) && + r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_LOAD_A; }); EXPECT_TRUE(row != trace.end()); @@ -166,8 +166,8 @@ TEST_F(AvmMemoryTests, readWriteConsistencyValViolation) // Find the row for memory trace with last memory entry for address 2 (read for multiplication) row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_addr == FF(2) && - r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_A; + return r.avm_mem_addr == FF(2) && + r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_LOAD_A; }); EXPECT_TRUE(row != trace.end()); @@ -196,8 +196,8 @@ TEST_F(AvmMemoryTests, readWriteConsistencyTagViolation) // Find the row for memory trace with last memory entry for address 2 (read for multiplication) row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_addr == FF(2) && - r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_A; + return r.avm_mem_addr == FF(2) && + r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_LOAD_A; }); EXPECT_TRUE(row != trace.end()); @@ -237,7 +237,7 @@ TEST_F(AvmMemoryTests, mismatchedTagErrorViolation) // Find the memory trace position corresponding to the subtraction sub-operation of register ia. row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_A; + return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_LOAD_A; }); row->avm_mem_tag_err = FF(0); @@ -271,7 +271,7 @@ TEST_F(AvmMemoryTests, consistentTagNoErrorViolation) // Find the memory trace position corresponding to the fdiv sub-operation of register ia. row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_LOAD_A; + return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_LOAD_A; }); row->avm_mem_tag_err = FF(1); @@ -297,7 +297,7 @@ TEST_F(AvmMemoryTests, noErrorTagWriteViolation) // Find the memory trace position corresponding to the fdiv sub-operation of register ic. row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { - return r.avm_mem_clk == clk && r.avm_mem_sub_clk == AvmMemTraceBuilder::SUB_CLK_STORE_C; + return r.avm_mem_tsp == FF(AvmMemTraceBuilder::NUM_SUB_CLK) * clk + AvmMemTraceBuilder::SUB_CLK_STORE_C; }); ASSERT_TRUE(row != trace.end());