diff --git a/barretenberg/cpp/pil/avm/avm_alu.pil b/barretenberg/cpp/pil/avm/avm_alu.pil index 974b4a03871..224c8f3d6f3 100644 --- a/barretenberg/cpp/pil/avm/avm_alu.pil +++ b/barretenberg/cpp/pil/avm/avm_alu.pil @@ -18,6 +18,10 @@ namespace avm_alu(256); pol commit op_not; pol commit op_eq; pol commit alu_sel; // Predicate to activate the copy of intermediate registers to ALU table. + pol commit op_lt; + pol commit op_lte; + pol commit cmp_sel; // Predicate if LT or LTE is set + pol commit rng_chk_sel; // Predicate representing a range check row. // Instruction tag (1: u8, 2: u16, 3: u32, 4: u64, 5: u128, 6: field) copied from Main table pol commit in_tag; @@ -58,7 +62,8 @@ namespace avm_alu(256); pol commit cf; // Compute predicate telling whether there is a row entry in the ALU table. - alu_sel = op_add + op_sub + op_mul + op_not + op_eq; + alu_sel = op_add + op_sub + op_mul + op_not + op_eq + op_lt + op_lte; + cmp_sel = op_lt + op_lte; // ========= Type Constraints ============================================= // TODO: Range constraints @@ -129,6 +134,8 @@ namespace avm_alu(256); pol SUM_96 = SUM_64 + u16_r3 * 2**64 + u16_r4 * 2**80; pol SUM_128 = SUM_96 + u16_r5 * 2**96 + u16_r6 * 2**112; + + // ========= ADDITION/SUBTRACTION Operation Constraints =============================== // // Addition and subtraction relations are very similar and will be consolidated. @@ -257,11 +264,213 @@ namespace avm_alu(256); // Need an additional helper that holds the inverse of the difference; pol commit op_eq_diff_inv; - // If EQ selector is set, ic needs to be boolean + // If EQ or CMP_SEL selector is set, ic needs to be boolean #[ALU_RES_IS_BOOL] - op_eq * (ic * (1 - ic)) = 0; + (cmp_sel + op_eq) * (ic * (1 - ic)) = 0; #[ALU_OP_EQ] op_eq * (DIFF * (ic * (1 - op_eq_diff_inv) + op_eq_diff_inv) - 1 + ic) = 0; + // ========= LT/LTE Operation Constraints =============================== + // There are two routines that we utilise as part of this LT/LTE check + // (1) Decomposition into two 128-bit limbs, lo and hi respectively and a borrow (1 or 0); + // (2) 128 bit-range checks when checking an arithmetic operation has not overflowed the field. + + // ========= COMPARISON OPERATION - EXPLANATIONS ================================================= + // To simplify the comparison circuit, we implement a GreaterThan(GT) circuit. This is ideal since + // if we need a LT operation, we just swap the inputs and if we need the LTE operation, we just NOT the GT constraint + // Given the inputs x, y and q where x & y are integers in the range [0,...,p-1] and q is the boolean result to the query (x > y). + // Then there are two scenarios: + // (1) (x > y) -> x - y - 1 = result, where 0 <= result. i.e. the result does not underflow the field. + // (2)!(x > y) -> (x <= y) = y - x = result, where the same applies as above. + + // These conditions can be combined with the GT constraint, q (that x > y) as follows: + // (x - y - 1) * q + (y - x) (1 - q) = result + + // If LT, then swap ia and ib else keep the same + pol INPUT_IA = op_lt * ib + op_lte * ia; + pol INPUT_IB = op_lt * ia + op_lte * ib; + + pol commit borrow; + pol commit a_lo; + pol commit a_hi; + // Check INPUT_IA is well formed from its lo and hi limbs + #[INPUT_DECOMP_1] + INPUT_IA = (a_lo + 2 ** 128 * a_hi) * cmp_sel; + + pol commit b_lo; + pol commit b_hi; + // Check INPUT_IB is well formed from its lo and hi limbs + #[INPUT_DECOMP_2] + INPUT_IB = (b_lo + 2 ** 128 * b_hi) * cmp_sel; + + pol commit p_sub_a_lo; // p_lo - a_lo + pol commit p_sub_a_hi; // p_hi - a_hi + pol commit p_a_borrow; + p_a_borrow * (1 - p_a_borrow) = 0; + + // (p - 1) lower 128 bits = 53438638232309528389504892708671455232 + // (p - 1) upper 128 bits = 64323764613183177041862057485226039389 + + // Check that decomposition of a into lo and hi limbs do not overflow p. + // This is achieved by checking a does not underflow p: (p_lo > a_lo && p_hi >= ahi) || (p_lo <= a_lo && p_hi > a_hi) + // First condition is if borrow = 0, second condition is if borrow = 1 + // This underflow check is done by the 128-bit check that is performed on each of these lo and hi limbs. + #[SUB_LO_1] + (p_sub_a_lo - (53438638232309528389504892708671455232 - a_lo + p_a_borrow * 2 ** 128)) * cmp_sel = 0; + #[SUB_HI_1] + (p_sub_a_hi - (64323764613183177041862057485226039389 - a_hi - p_a_borrow)) * cmp_sel = 0; + + pol commit p_sub_b_lo; + pol commit p_sub_b_hi; + pol commit p_b_borrow; + p_b_borrow * (1 - p_b_borrow) = 0; + + // Check that decomposition of b into lo and hi limbs do not overflow/underflow p. + // This is achieved by checking (p_lo > b_lo && p_hi >= bhi) || (p_lo <= b_lo && p_hi > b_hi) + // First condition is if borrow = 0, second condition is if borrow = 1; + #[SUB_LO_2] + (p_sub_b_lo - (53438638232309528389504892708671455232 - b_lo + p_b_borrow * 2 ** 128)) * cmp_sel = 0; + #[SUB_HI_2] + (p_sub_b_hi - (64323764613183177041862057485226039389 - b_hi - p_b_borrow)) * cmp_sel = 0; + + // Calculate the combined relation: (a - b - 1) * q + (b -a ) * (1-q) + // Check that (a > b) by checking (a_lo > b_lo && a_hi >= bhi) || (alo <= b_lo && a_hi > b_hi) + // First condition is if borrow = 0, second condition is if borrow = 1; + pol A_SUB_B_LO = a_lo - b_lo - 1 + borrow * 2 ** 128; + pol A_SUB_B_HI = a_hi - b_hi - borrow; + + // Check that (a <= b) by checking (b_lo >= a_lo && b_hi >= a_hi) || (b_lo < a_lo && b_hi > a_hi) + // First condition is if borrow = 0, second condition is if borrow = 1; + pol B_SUB_A_LO = b_lo - a_lo + borrow * 2 ** 128; + pol B_SUB_A_HI = b_hi - a_hi - borrow; + + + // If this is a LT operation, we already swapped the inputs so the result of ic is still correct + // If this is a LTE operation, we invert the value of ic. + pol IS_GT = op_lt * ic + (1 - ic) * op_lte; + + // When IS_GT = 1, we enforce the condition that a > b and thus a - b - 1 does not underflow. + // When IS_GT = 0, we enforce the condition that a <= b and thus b - a does not underflow. + // ========= Analysing res_lo and res_hi scenarios for LTE ================================= + // (1) Assume a proof satisfies the constraints for LTE(x,y,1), i.e., x <= y + // Therefore ia = x, ib = y and ic = 1. + // (a) We do not swap the operands, so a = x and b = y, + // (b) IS_GT = 1 - ic = 0 + // (c) res_lo = B_SUB_A_LO and res_hi = B_SUB_A_HI + // (d) res_lo = y_lo - x_lo + borrow * 2**128 and res_hi = y_hi - x_hi - borrow. + // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, y_lo, we + // have the guarantee that res_lo >= 0 && res_hi >= 0. Furthermore, borrow is + // boolean and so we have two cases to consider: + // (i) borrow == 0 ==> y_lo >= x_lo && y_hi >= x_hi + // (ii) borrow == 1 ==> y_hi >= x_hi + 1 ==> y_hi > x_hi + // This concludes the proof as for both cases, we must have: y >= x + // + // (2) Assume a proof satisfies the constraints for LTE(x,y,0), i.e. x > y. + // Therefore ia = x, ib = y and ic = 0. + // (a) We do not swap the operands, so a = x and b = y, + // (b) IS_GT = 1 - ic = 1 + // (c) res_lo = A_SUB_B_LO and res_hi = A_SUB_B_HI + // (d) res_lo = x_lo - y_lo - 1 + borrow * 2**128 and res_hi = x_hi - y_hi - borrow. + // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, y_lo, we + // have the guarantee that res_lo >= 0 && res_hi >= 0. Furthermore, borrow is + // boolean and so we have two cases to consider: + // (i) borrow == 0 ==> x_lo > y_lo && x_hi >= y_hi + // (ii) borrow == 1 ==> x_hi > y_hi + // This concludes the proof as for both cases, we must have: x > y + // + + // ========= Analysing res_lo and res_hi scenarios for LT ================================== + // (1) Assume a proof satisfies the constraints for LT(x,y,1), i.e. x < y. + // Therefore ia = x, ib = y and ic = 1. + // (a) We DO swap the operands, so a = y and b = x, + // (b) IS_GT = ic = 1 + // (c) res_lo = A_SUB_B_LO and res_hi = A_SUB_B_HI, **remember we have swapped inputs** + // (d) res_lo = y_lo - x_lo - 1 + borrow * 2**128 and res_hi = y_hi - x_hi - borrow. + // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, y_lo, we + // have the guarantee that res_lo >= 0 && res_hi >= 0. Furthermore, borrow is + // boolean and so we have two cases to consider: + // (i) borrow == 0 ==> y_lo > x_lo && y_hi >= x_hi + // (ii) borrow == 1 ==> y_hi > x_hi + // This concludes the proof as for both cases, we must have: x < y + // + // (2) Assume a proof satisfies the constraint for LT(x,y,0), i.e. x >= y. + // Therefore ia = x, ib = y and ic = 0. + // (a) We DO swap the operands, so a = y and b = x, + // (b) IS_GT = ic = 0 + // (c) res_lo = B_SUB_A_LO and res_hi = B_SUB_A_HI, **remember we have swapped inputs** + // (d) res_lo = x_lo - y_lo + borrow * 2**128 and res_hi = x_hi - y_hi - borrow. + // (e) Due to 128-bit range checks on res_lo, res_hi, y_lo, x_lo, y_hi, y_lo, we + // have the guarantee that res_lo >= 0 && res_hi >= 0. Furthermore, borrow is + // boolean and so we have two cases to consider: + // (i) borrow == 0 ==> x_lo >= y_lo && x_hi >= y_hi + // (ii) borrow == 1 ==> x_hi > y_hi + // This concludes the proof as for both cases, we must have: x >= y + + pol commit res_lo; + pol commit res_hi; + #[RES_LO] + (res_lo - (A_SUB_B_LO * IS_GT + B_SUB_A_LO * (1 - IS_GT))) * cmp_sel = 0; + #[RES_HI] + (res_hi - (A_SUB_B_HI * IS_GT + B_SUB_A_HI * (1 - IS_GT))) * cmp_sel = 0; + + // ========= RANGE OPERATIONS =============================== + + // Each call to LT/LTE requires 5x 256-bit range checks. We keep track of how many are left here. + pol commit cmp_rng_ctr; + + // TODO: combine into 1 equation, left separate for debugging + // the number of range checks must decrement by 1 until it is equal to 0; + #[CMP_CTR_REL_1] + (cmp_rng_ctr' - cmp_rng_ctr + 1) * cmp_rng_ctr = 0; + // if this row is a comparison operation, the next range_check_remaining value is set to 4 + // it is not set to 5 since we do 1 as part of the comparison. + #[CMP_CTR_REL_2] + (cmp_rng_ctr' - 4) * cmp_sel = 0; + + rng_chk_sel * (1 - rng_chk_sel) = 0; + // If we have remaining range checks, we cannot have cmp_sel set. This prevents malicious truncating of the range + // checks by adding a new LT/LTE operation before all the range checks from the previous computation are complete. + rng_chk_sel * cmp_sel = 0; + + // rng_chk_sel = 1 when cmp_rng_ctr != 0 and rng_chk_sel = 0 when cmp_rng_ctr = 0; + #[CTR_NON_ZERO_REL] + cmp_rng_ctr * ((1 - rng_chk_sel) * (1 - op_eq_diff_inv) + op_eq_diff_inv) - rng_chk_sel = 0; + + // We perform a range check if we have some range checks remaining or we are performing a comparison op + pol RNG_CHK_OP = rng_chk_sel + cmp_sel; + + pol commit rng_chk_lookup_selector; + #[RNG_CHK_LOOKUP_SELECTOR] + rng_chk_lookup_selector = cmp_sel + rng_chk_sel; + + // Perform 128-bit range check on lo part + #[LOWER_CMP_RNG_CHK] + a_lo = SUM_128 * RNG_CHK_OP; + + + // Perform 128-bit range check on hi part + #[UPPER_CMP_RNG_CHK] + a_hi = (u16_r7 + u16_r8 * 2**16 + + u16_r9 * 2**32 + u16_r10 * 2**48 + + u16_r11 * 2**64 + u16_r12 * 2**80 + + u16_r13 * 2**96 + u16_r14 * 2**112) * RNG_CHK_OP; + + // Shift all elements "across" by 2 columns + // TODO: there is an optimisation where we are able to do 1 less range check as the range check on + // P_SUB_B is implied by the other range checks. + // Briefly: given a > b and p > a and p > a - b - 1, it is sufficient confirm that p > b without a range check + // To accomplish this we would likely change the order of the range_check so we can skip p_sub_b + #[SHIFT_RELS_0] + (a_lo' - b_lo) * rng_chk_sel' = 0; + (a_hi' - b_hi) * rng_chk_sel' = 0; + #[SHIFT_RELS_1] + (b_lo' - p_sub_a_lo) * rng_chk_sel' = 0; + (b_hi' - p_sub_a_hi) * rng_chk_sel' = 0; + #[SHIFT_RELS_2] + (p_sub_a_lo' - p_sub_b_lo) * rng_chk_sel'= 0; + (p_sub_a_hi' - p_sub_b_hi) * rng_chk_sel'= 0; + #[SHIFT_RELS_3] + (p_sub_b_lo' - res_lo) * rng_chk_sel'= 0; + (p_sub_b_hi' - res_hi) * rng_chk_sel'= 0; diff --git a/barretenberg/cpp/pil/avm/avm_main.pil b/barretenberg/cpp/pil/avm/avm_main.pil index 5e0b27d6a30..92fa0f4fa83 100644 --- a/barretenberg/cpp/pil/avm/avm_main.pil +++ b/barretenberg/cpp/pil/avm/avm_main.pil @@ -53,6 +53,10 @@ namespace avm_main(256); pol commit sel_op_or; // XOR pol commit sel_op_xor; + // LT + pol commit sel_op_lt; + // LTE + pol commit sel_op_lte; // Helper selector to characterize an ALU chiplet selector pol commit alu_sel; @@ -121,6 +125,8 @@ namespace avm_main(256); sel_op_and * (1 - sel_op_and) = 0; sel_op_or * (1 - sel_op_or) = 0; sel_op_xor * (1 - sel_op_xor) = 0; + sel_op_lt * (1 - sel_op_lt) = 0; + sel_op_lte * (1 - sel_op_lte) = 0; sel_internal_call * (1 - sel_internal_call) = 0; sel_internal_return * (1 - sel_internal_return) = 0; @@ -154,8 +160,8 @@ namespace avm_main(256); //====== COMPARATOR OPCODES CONSTRAINTS ===================================== // Enforce that the tag for the ouput of EQ opcode is u8 (i.e. equal to 1). - #[EQ_OUTPUT_U8] - sel_op_eq * (w_in_tag - 1) = 0; + #[OUTPUT_U8] + (sel_op_eq + sel_op_lte + sel_op_lt) * (w_in_tag - 1) = 0; // Relation for division over the finite field // If tag_err == 1 in a division, then ib == 0 and op_err == 1. @@ -254,14 +260,14 @@ namespace avm_main(256); // Predicate to activate the copy of intermediate registers to ALU table. If tag_err == 1, // the operation is not copied to the ALU table. // TODO: when division is moved to the alu, we will need to add the selector in the list below: - alu_sel = (sel_op_add + sel_op_sub + sel_op_mul + sel_op_not + sel_op_eq) * (1 - tag_err); + alu_sel = (sel_op_add + sel_op_sub + sel_op_mul + sel_op_not + sel_op_eq + sel_op_lt + sel_op_lte) * (1 - tag_err); #[PERM_MAIN_ALU] alu_sel {clk, ia, ib, ic, sel_op_add, sel_op_sub, - sel_op_mul, sel_op_eq, sel_op_not, r_in_tag} + sel_op_mul, sel_op_eq, sel_op_not, sel_op_lt, sel_op_lte, r_in_tag} is avm_alu.alu_sel {avm_alu.clk, avm_alu.ia, avm_alu.ib, avm_alu.ic, avm_alu.op_add, avm_alu.op_sub, - avm_alu.op_mul, avm_alu.op_eq, avm_alu.op_not, avm_alu.in_tag}; + avm_alu.op_mul, avm_alu.op_eq, avm_alu.op_not, avm_alu.op_lt, avm_alu.op_lte, avm_alu.in_tag}; // Based on the boolean selectors, we derive the binary op id to lookup in the table; // TODO: Check if having 4 columns (op_id + 3 boolean selectors) is more optimal that just using the op_id @@ -275,11 +281,11 @@ namespace avm_main(256); // the operation decomposition step during bytecode unpacking. #[BIN_SEL_2] bin_sel = sel_op_and + sel_op_or + sel_op_xor; - + #[PERM_MAIN_BIN] - bin_sel {ia, ib, ic, bin_op_id, r_in_tag} + bin_sel {clk, ia, ib, ic, bin_op_id, r_in_tag} is - avm_binary.start {avm_binary.acc_ia, avm_binary.acc_ib, avm_binary.acc_ic, avm_binary.op_id, avm_binary.in_tag}; + avm_binary.start {avm_binary.clk, avm_binary.acc_ia, avm_binary.acc_ib, avm_binary.acc_ic, avm_binary.op_id, avm_binary.in_tag}; #[PERM_MAIN_MEM_A] mem_op_a {clk, mem_idx_a, ia, rwa, r_in_tag, w_in_tag, sel_mov} @@ -303,4 +309,58 @@ namespace avm_main(256); ind_op_b {clk, ind_b, mem_idx_b} is avm_mem.ind_op_b {avm_mem.clk, avm_mem.addr, avm_mem.val}; #[PERM_MAIN_MEM_IND_C] - ind_op_c {clk, ind_c, mem_idx_c} is avm_mem.ind_op_c {avm_mem.clk, avm_mem.addr, avm_mem.val}; \ No newline at end of file + ind_op_c {clk, ind_c, mem_idx_c} is avm_mem.ind_op_c {avm_mem.clk, avm_mem.addr, avm_mem.val}; + + //====== Inter-table Constraints (Range Checks) ============================================ + // TODO: Investigate optimising these range checks. Handling non-FF elements should require less range checks. + #[LOOKUP_U8_0] + avm_alu.rng_chk_lookup_selector { avm_alu.u8_r0 } in sel_rng_8 { clk }; + + #[LOOKUP_U8_1] + avm_alu.rng_chk_lookup_selector { avm_alu.u8_r1 } in sel_rng_8 { clk }; + + #[LOOKUP_U16_0] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r0 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_1] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r1 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_2] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r2 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_3] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r3 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_4] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r4 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_5] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r5 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_6] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r6 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_7] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r7 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_8] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r8 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_9] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r9 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_10] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r10 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_11] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r11 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_12] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r12 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_13] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r13 } in sel_rng_16 { clk }; + + #[LOOKUP_U16_14] + avm_alu.rng_chk_lookup_selector {avm_alu.u16_r14 } in sel_rng_16 { clk }; + diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp index ef98385518f..fc4fcff7998 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_alu.hpp @@ -7,8 +7,20 @@ namespace bb::Avm_vm { template struct Avm_aluRow { + FF avm_alu_a_hi{}; + FF avm_alu_a_hi_shift{}; + FF avm_alu_a_lo{}; + FF avm_alu_a_lo_shift{}; FF avm_alu_alu_sel{}; + FF avm_alu_b_hi{}; + FF avm_alu_b_hi_shift{}; + FF avm_alu_b_lo{}; + FF avm_alu_b_lo_shift{}; + FF avm_alu_borrow{}; FF avm_alu_cf{}; + FF avm_alu_cmp_rng_ctr{}; + FF avm_alu_cmp_rng_ctr_shift{}; + FF avm_alu_cmp_sel{}; FF avm_alu_ff_tag{}; FF avm_alu_ia{}; FF avm_alu_ib{}; @@ -17,13 +29,35 @@ template struct Avm_aluRow { FF avm_alu_op_add{}; FF avm_alu_op_eq{}; FF avm_alu_op_eq_diff_inv{}; + FF avm_alu_op_lt{}; + FF avm_alu_op_lte{}; FF avm_alu_op_mul{}; FF avm_alu_op_not{}; FF avm_alu_op_sub{}; + FF avm_alu_p_a_borrow{}; + FF avm_alu_p_b_borrow{}; + FF avm_alu_p_sub_a_hi{}; + FF avm_alu_p_sub_a_hi_shift{}; + FF avm_alu_p_sub_a_lo{}; + FF avm_alu_p_sub_a_lo_shift{}; + FF avm_alu_p_sub_b_hi{}; + FF avm_alu_p_sub_b_hi_shift{}; + FF avm_alu_p_sub_b_lo{}; + FF avm_alu_p_sub_b_lo_shift{}; + FF avm_alu_res_hi{}; + FF avm_alu_res_lo{}; + FF avm_alu_rng_chk_lookup_selector{}; + FF avm_alu_rng_chk_sel{}; + FF avm_alu_rng_chk_sel_shift{}; FF avm_alu_u128_tag{}; FF avm_alu_u16_r0{}; FF avm_alu_u16_r0_shift{}; FF avm_alu_u16_r1{}; + FF avm_alu_u16_r10{}; + FF avm_alu_u16_r11{}; + FF avm_alu_u16_r12{}; + FF avm_alu_u16_r13{}; + FF avm_alu_u16_r14{}; FF avm_alu_u16_r1_shift{}; FF avm_alu_u16_r2{}; FF avm_alu_u16_r2_shift{}; @@ -37,6 +71,8 @@ template struct Avm_aluRow { FF avm_alu_u16_r6_shift{}; FF avm_alu_u16_r7{}; FF avm_alu_u16_r7_shift{}; + FF avm_alu_u16_r8{}; + FF avm_alu_u16_r9{}; FF avm_alu_u16_tag{}; FF avm_alu_u32_tag{}; FF avm_alu_u64_r0{}; @@ -49,35 +85,89 @@ template struct Avm_aluRow { inline std::string get_relation_label_avm_alu(int index) { switch (index) { - case 9: + case 10: return "ALU_ADD_SUB_1"; - case 10: + case 11: return "ALU_ADD_SUB_2"; - case 11: + case 12: return "ALU_MULTIPLICATION_FF"; - case 12: + case 13: return "ALU_MUL_COMMON_1"; - case 13: + case 14: return "ALU_MUL_COMMON_2"; - case 16: + case 17: return "ALU_MULTIPLICATION_OUT_U128"; - case 17: + case 18: return "ALU_FF_NOT_XOR"; - case 18: + case 19: return "ALU_OP_NOT"; - case 19: + case 20: return "ALU_RES_IS_BOOL"; - case 20: + case 21: return "ALU_OP_EQ"; + + case 22: + return "INPUT_DECOMP_1"; + + case 23: + return "INPUT_DECOMP_2"; + + case 25: + return "SUB_LO_1"; + + case 26: + return "SUB_HI_1"; + + case 28: + return "SUB_LO_2"; + + case 29: + return "SUB_HI_2"; + + case 30: + return "RES_LO"; + + case 31: + return "RES_HI"; + + case 32: + return "CMP_CTR_REL_1"; + + case 33: + return "CMP_CTR_REL_2"; + + case 36: + return "CTR_NON_ZERO_REL"; + + case 37: + return "RNG_CHK_LOOKUP_SELECTOR"; + + case 38: + return "LOWER_CMP_RNG_CHK"; + + case 39: + return "UPPER_CMP_RNG_CHK"; + + case 40: + return "SHIFT_RELS_0"; + + case 42: + return "SHIFT_RELS_1"; + + case 44: + return "SHIFT_RELS_2"; + + case 46: + return "SHIFT_RELS_3"; } return std::to_string(index); } @@ -86,8 +176,9 @@ template class avm_aluImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 8, 3, 4, 4, 5, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 6, 6, 8, 3, 4, 4, 5, 4, 4, + 3, 4, 3, 3, 4, 3, 6, 5, 3, 3, 3, 3, 4, 2, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, }; template @@ -102,7 +193,9 @@ template class avm_aluImpl { Avm_DECLARE_VIEWS(0); auto tmp = (avm_alu_alu_sel - - ((((avm_alu_op_add + avm_alu_op_sub) + avm_alu_op_mul) + avm_alu_op_not) + avm_alu_op_eq)); + ((((((avm_alu_op_add + avm_alu_op_sub) + avm_alu_op_mul) + avm_alu_op_not) + avm_alu_op_eq) + + avm_alu_op_lt) + + avm_alu_op_lte)); tmp *= scaling_factor; std::get<0>(evals) += tmp; } @@ -110,7 +203,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(1); - auto tmp = (avm_alu_ff_tag * (-avm_alu_ff_tag + FF(1))); + auto tmp = (avm_alu_cmp_sel - (avm_alu_op_lt + avm_alu_op_lte)); tmp *= scaling_factor; std::get<1>(evals) += tmp; } @@ -118,7 +211,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(2); - auto tmp = (avm_alu_u8_tag * (-avm_alu_u8_tag + FF(1))); + auto tmp = (avm_alu_ff_tag * (-avm_alu_ff_tag + FF(1))); tmp *= scaling_factor; std::get<2>(evals) += tmp; } @@ -126,7 +219,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(3); - auto tmp = (avm_alu_u16_tag * (-avm_alu_u16_tag + FF(1))); + auto tmp = (avm_alu_u8_tag * (-avm_alu_u8_tag + FF(1))); tmp *= scaling_factor; std::get<3>(evals) += tmp; } @@ -134,7 +227,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(4); - auto tmp = (avm_alu_u32_tag * (-avm_alu_u32_tag + FF(1))); + auto tmp = (avm_alu_u16_tag * (-avm_alu_u16_tag + FF(1))); tmp *= scaling_factor; std::get<4>(evals) += tmp; } @@ -142,7 +235,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(5); - auto tmp = (avm_alu_u64_tag * (-avm_alu_u64_tag + FF(1))); + auto tmp = (avm_alu_u32_tag * (-avm_alu_u32_tag + FF(1))); tmp *= scaling_factor; std::get<5>(evals) += tmp; } @@ -150,7 +243,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(6); - auto tmp = (avm_alu_u128_tag * (-avm_alu_u128_tag + FF(1))); + auto tmp = (avm_alu_u64_tag * (-avm_alu_u64_tag + FF(1))); tmp *= scaling_factor; std::get<6>(evals) += tmp; } @@ -158,11 +251,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(7); - auto tmp = - (avm_alu_alu_sel * - ((((((avm_alu_ff_tag + avm_alu_u8_tag) + avm_alu_u16_tag) + avm_alu_u32_tag) + avm_alu_u64_tag) + - avm_alu_u128_tag) - - FF(1))); + auto tmp = (avm_alu_u128_tag * (-avm_alu_u128_tag + FF(1))); tmp *= scaling_factor; std::get<7>(evals) += tmp; } @@ -170,10 +259,11 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(8); - auto tmp = (avm_alu_in_tag - (((((avm_alu_u8_tag + (avm_alu_u16_tag * FF(2))) + (avm_alu_u32_tag * FF(3))) + - (avm_alu_u64_tag * FF(4))) + - (avm_alu_u128_tag * FF(5))) + - (avm_alu_ff_tag * FF(6)))); + auto tmp = + (avm_alu_alu_sel * + ((((((avm_alu_ff_tag + avm_alu_u8_tag) + avm_alu_u16_tag) + avm_alu_u32_tag) + avm_alu_u64_tag) + + avm_alu_u128_tag) - + FF(1))); tmp *= scaling_factor; std::get<8>(evals) += tmp; } @@ -181,18 +271,10 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(9); - auto tmp = - (((avm_alu_op_add + avm_alu_op_sub) * - ((((((((((avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))) + (avm_alu_u16_r0 * FF(65536))) + - (avm_alu_u16_r1 * FF(4294967296UL))) + - (avm_alu_u16_r2 * FF(281474976710656UL))) + - (avm_alu_u16_r3 * FF(uint256_t{ 0, 1, 0, 0 }))) + - (avm_alu_u16_r4 * FF(uint256_t{ 0, 65536, 0, 0 }))) + - (avm_alu_u16_r5 * FF(uint256_t{ 0, 4294967296, 0, 0 }))) + - (avm_alu_u16_r6 * FF(uint256_t{ 0, 281474976710656, 0, 0 }))) - - avm_alu_ia) + - (avm_alu_ff_tag * avm_alu_ic))) + - ((avm_alu_op_add - avm_alu_op_sub) * ((avm_alu_cf * FF(uint256_t{ 0, 0, 1, 0 })) - avm_alu_ib))); + auto tmp = (avm_alu_in_tag - (((((avm_alu_u8_tag + (avm_alu_u16_tag * FF(2))) + (avm_alu_u32_tag * FF(3))) + + (avm_alu_u64_tag * FF(4))) + + (avm_alu_u128_tag * FF(5))) + + (avm_alu_ff_tag * FF(6)))); tmp *= scaling_factor; std::get<9>(evals) += tmp; } @@ -200,6 +282,25 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(10); + auto tmp = (((avm_alu_op_add + avm_alu_op_sub) * + ((((((((((avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))) + (avm_alu_u16_r0 * FF(65536))) + + (avm_alu_u16_r1 * FF(4294967296UL))) + + (avm_alu_u16_r2 * FF(281474976710656UL))) + + (avm_alu_u16_r3 * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + + (avm_alu_u16_r4 * FF(uint256_t{ 0UL, 65536UL, 0UL, 0UL }))) + + (avm_alu_u16_r5 * FF(uint256_t{ 0UL, 4294967296UL, 0UL, 0UL }))) + + (avm_alu_u16_r6 * FF(uint256_t{ 0UL, 281474976710656UL, 0UL, 0UL }))) - + avm_alu_ia) + + (avm_alu_ff_tag * avm_alu_ic))) + + ((avm_alu_op_add - avm_alu_op_sub) * + ((avm_alu_cf * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL })) - avm_alu_ib))); + tmp *= scaling_factor; + std::get<10>(evals) += tmp; + } + // Contribution 11 + { + Avm_DECLARE_VIEWS(11); + auto tmp = (((avm_alu_op_add + avm_alu_op_sub) * (((((((avm_alu_u8_tag * avm_alu_u8_r0) + (avm_alu_u16_tag * (avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))))) + @@ -213,43 +314,43 @@ template class avm_aluImpl { ((((((((avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))) + (avm_alu_u16_r0 * FF(65536))) + (avm_alu_u16_r1 * FF(4294967296UL))) + (avm_alu_u16_r2 * FF(281474976710656UL))) + - (avm_alu_u16_r3 * FF(uint256_t{ 0, 1, 0, 0 }))) + - (avm_alu_u16_r4 * FF(uint256_t{ 0, 65536, 0, 0 }))) + - (avm_alu_u16_r5 * FF(uint256_t{ 0, 4294967296, 0, 0 }))) + - (avm_alu_u16_r6 * FF(uint256_t{ 0, 281474976710656, 0, 0 }))))) + + (avm_alu_u16_r3 * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + + (avm_alu_u16_r4 * FF(uint256_t{ 0UL, 65536UL, 0UL, 0UL }))) + + (avm_alu_u16_r5 * FF(uint256_t{ 0UL, 4294967296UL, 0UL, 0UL }))) + + (avm_alu_u16_r6 * FF(uint256_t{ 0UL, 281474976710656UL, 0UL, 0UL }))))) + (avm_alu_ff_tag * avm_alu_ia)) - avm_alu_ic)) + ((avm_alu_ff_tag * (avm_alu_op_add - avm_alu_op_sub)) * avm_alu_ib)); tmp *= scaling_factor; - std::get<10>(evals) += tmp; + std::get<11>(evals) += tmp; } - // Contribution 11 + // Contribution 12 { - Avm_DECLARE_VIEWS(11); + Avm_DECLARE_VIEWS(12); auto tmp = ((avm_alu_ff_tag * avm_alu_op_mul) * ((avm_alu_ia * avm_alu_ib) - avm_alu_ic)); tmp *= scaling_factor; - std::get<11>(evals) += tmp; + std::get<12>(evals) += tmp; } - // Contribution 12 + // Contribution 13 { - Avm_DECLARE_VIEWS(12); + Avm_DECLARE_VIEWS(13); auto tmp = ((((-avm_alu_ff_tag + FF(1)) - avm_alu_u128_tag) * avm_alu_op_mul) * (((((((((avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))) + (avm_alu_u16_r0 * FF(65536))) + (avm_alu_u16_r1 * FF(4294967296UL))) + (avm_alu_u16_r2 * FF(281474976710656UL))) + - (avm_alu_u16_r3 * FF(uint256_t{ 0, 1, 0, 0 }))) + - (avm_alu_u16_r4 * FF(uint256_t{ 0, 65536, 0, 0 }))) + - (avm_alu_u16_r5 * FF(uint256_t{ 0, 4294967296, 0, 0 }))) + - (avm_alu_u16_r6 * FF(uint256_t{ 0, 281474976710656, 0, 0 }))) - + (avm_alu_u16_r3 * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + + (avm_alu_u16_r4 * FF(uint256_t{ 0UL, 65536UL, 0UL, 0UL }))) + + (avm_alu_u16_r5 * FF(uint256_t{ 0UL, 4294967296UL, 0UL, 0UL }))) + + (avm_alu_u16_r6 * FF(uint256_t{ 0UL, 281474976710656UL, 0UL, 0UL }))) - (avm_alu_ia * avm_alu_ib))); tmp *= scaling_factor; - std::get<12>(evals) += tmp; + std::get<13>(evals) += tmp; } - // Contribution 13 + // Contribution 14 { - Avm_DECLARE_VIEWS(13); + Avm_DECLARE_VIEWS(14); auto tmp = (avm_alu_op_mul * @@ -261,25 +362,25 @@ template class avm_aluImpl { (avm_alu_u16_r2 * FF(281474976710656UL))))) - (((-avm_alu_ff_tag + FF(1)) - avm_alu_u128_tag) * avm_alu_ic))); tmp *= scaling_factor; - std::get<13>(evals) += tmp; + std::get<14>(evals) += tmp; } - // Contribution 14 + // Contribution 15 { - Avm_DECLARE_VIEWS(14); + Avm_DECLARE_VIEWS(15); auto tmp = ((avm_alu_u128_tag * avm_alu_op_mul) * (((((avm_alu_u16_r0 + (avm_alu_u16_r1 * FF(65536))) + (avm_alu_u16_r2 * FF(4294967296UL))) + (avm_alu_u16_r3 * FF(281474976710656UL))) + ((((avm_alu_u16_r4 + (avm_alu_u16_r5 * FF(65536))) + (avm_alu_u16_r6 * FF(4294967296UL))) + (avm_alu_u16_r7 * FF(281474976710656UL))) * - FF(uint256_t{ 0, 1, 0, 0 }))) - + FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) - avm_alu_ia)); tmp *= scaling_factor; - std::get<14>(evals) += tmp; + std::get<15>(evals) += tmp; } - // Contribution 15 + // Contribution 16 { - Avm_DECLARE_VIEWS(15); + Avm_DECLARE_VIEWS(16); auto tmp = ((avm_alu_u128_tag * avm_alu_op_mul) * (((((avm_alu_u16_r0_shift + (avm_alu_u16_r1_shift * FF(65536))) + @@ -288,36 +389,28 @@ template class avm_aluImpl { ((((avm_alu_u16_r4_shift + (avm_alu_u16_r5_shift * FF(65536))) + (avm_alu_u16_r6_shift * FF(4294967296UL))) + (avm_alu_u16_r7_shift * FF(281474976710656UL))) * - FF(uint256_t{ 0, 1, 0, 0 }))) - + FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) - avm_alu_ib)); tmp *= scaling_factor; - std::get<15>(evals) += tmp; - } - // Contribution 16 - { - Avm_DECLARE_VIEWS(16); - - auto tmp = - ((avm_alu_u128_tag * avm_alu_op_mul) * - ((((avm_alu_ia * (((avm_alu_u16_r0_shift + (avm_alu_u16_r1_shift * FF(65536))) + - (avm_alu_u16_r2_shift * FF(4294967296UL))) + - (avm_alu_u16_r3_shift * FF(281474976710656UL)))) + - (((((avm_alu_u16_r0 + (avm_alu_u16_r1 * FF(65536))) + (avm_alu_u16_r2 * FF(4294967296UL))) + - (avm_alu_u16_r3 * FF(281474976710656UL))) * - (((avm_alu_u16_r4_shift + (avm_alu_u16_r5_shift * FF(65536))) + - (avm_alu_u16_r6_shift * FF(4294967296UL))) + - (avm_alu_u16_r7_shift * FF(281474976710656UL)))) * - FF(uint256_t{ 0, 1, 0, 0 }))) - - (((avm_alu_cf * FF(uint256_t{ 0, 1, 0, 0 })) + avm_alu_u64_r0) * FF(uint256_t{ 0, 0, 1, 0 }))) - - avm_alu_ic)); - tmp *= scaling_factor; std::get<16>(evals) += tmp; } // Contribution 17 { Avm_DECLARE_VIEWS(17); - auto tmp = (avm_alu_op_not * avm_alu_ff_tag); + auto tmp = ((avm_alu_u128_tag * avm_alu_op_mul) * + ((((avm_alu_ia * (((avm_alu_u16_r0_shift + (avm_alu_u16_r1_shift * FF(65536))) + + (avm_alu_u16_r2_shift * FF(4294967296UL))) + + (avm_alu_u16_r3_shift * FF(281474976710656UL)))) + + (((((avm_alu_u16_r0 + (avm_alu_u16_r1 * FF(65536))) + (avm_alu_u16_r2 * FF(4294967296UL))) + + (avm_alu_u16_r3 * FF(281474976710656UL))) * + (((avm_alu_u16_r4_shift + (avm_alu_u16_r5_shift * FF(65536))) + + (avm_alu_u16_r6_shift * FF(4294967296UL))) + + (avm_alu_u16_r7_shift * FF(281474976710656UL)))) * + FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) - + (((avm_alu_cf * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL })) + avm_alu_u64_r0) * + FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) - + avm_alu_ic)); tmp *= scaling_factor; std::get<17>(evals) += tmp; } @@ -325,12 +418,7 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(18); - auto tmp = (avm_alu_op_not * - ((avm_alu_ia + avm_alu_ic) - ((((((avm_alu_u8_tag * FF(256)) + (avm_alu_u16_tag * FF(65536))) + - (avm_alu_u32_tag * FF(4294967296UL))) + - (avm_alu_u64_tag * FF(uint256_t{ 0, 1, 0, 0 }))) + - (avm_alu_u128_tag * FF(uint256_t{ 0, 0, 1, 0 }))) - - FF(1)))); + auto tmp = (avm_alu_op_not * avm_alu_ff_tag); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -338,7 +426,12 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(19); - auto tmp = (avm_alu_op_eq * (avm_alu_ic * (-avm_alu_ic + FF(1)))); + auto tmp = (avm_alu_op_not * + ((avm_alu_ia + avm_alu_ic) - ((((((avm_alu_u8_tag * FF(256)) + (avm_alu_u16_tag * FF(65536))) + + (avm_alu_u32_tag * FF(4294967296UL))) + + (avm_alu_u64_tag * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + + (avm_alu_u128_tag * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) - + FF(1)))); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -346,13 +439,271 @@ template class avm_aluImpl { { Avm_DECLARE_VIEWS(20); + auto tmp = ((avm_alu_cmp_sel + avm_alu_op_eq) * (avm_alu_ic * (-avm_alu_ic + FF(1)))); + tmp *= scaling_factor; + std::get<20>(evals) += tmp; + } + // Contribution 21 + { + Avm_DECLARE_VIEWS(21); + auto tmp = (avm_alu_op_eq * ((((avm_alu_ia - avm_alu_ib) * ((avm_alu_ic * (-avm_alu_op_eq_diff_inv + FF(1))) + avm_alu_op_eq_diff_inv)) - FF(1)) + avm_alu_ic)); tmp *= scaling_factor; - std::get<20>(evals) += tmp; + std::get<21>(evals) += tmp; + } + // Contribution 22 + { + Avm_DECLARE_VIEWS(22); + + auto tmp = (((avm_alu_op_lt * avm_alu_ib) + (avm_alu_op_lte * avm_alu_ia)) - + ((avm_alu_a_lo + (avm_alu_a_hi * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) * avm_alu_cmp_sel)); + tmp *= scaling_factor; + std::get<22>(evals) += tmp; + } + // Contribution 23 + { + Avm_DECLARE_VIEWS(23); + + auto tmp = (((avm_alu_op_lt * avm_alu_ia) + (avm_alu_op_lte * avm_alu_ib)) - + ((avm_alu_b_lo + (avm_alu_b_hi * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) * avm_alu_cmp_sel)); + tmp *= scaling_factor; + std::get<23>(evals) += tmp; + } + // Contribution 24 + { + Avm_DECLARE_VIEWS(24); + + auto tmp = (avm_alu_p_a_borrow * (-avm_alu_p_a_borrow + FF(1))); + tmp *= scaling_factor; + std::get<24>(evals) += tmp; + } + // Contribution 25 + { + Avm_DECLARE_VIEWS(25); + + auto tmp = ((avm_alu_p_sub_a_lo - + ((-avm_alu_a_lo + FF(uint256_t{ 4891460686036598784UL, 2896914383306846353UL, 0UL, 0UL })) + + (avm_alu_p_a_borrow * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL })))) * + avm_alu_cmp_sel); + tmp *= scaling_factor; + std::get<25>(evals) += tmp; + } + // Contribution 26 + { + Avm_DECLARE_VIEWS(26); + + auto tmp = ((avm_alu_p_sub_a_hi - + ((-avm_alu_a_hi + FF(uint256_t{ 13281191951274694749UL, 3486998266802970665UL, 0UL, 0UL })) - + avm_alu_p_a_borrow)) * + avm_alu_cmp_sel); + tmp *= scaling_factor; + std::get<26>(evals) += tmp; + } + // Contribution 27 + { + Avm_DECLARE_VIEWS(27); + + auto tmp = (avm_alu_p_b_borrow * (-avm_alu_p_b_borrow + FF(1))); + tmp *= scaling_factor; + std::get<27>(evals) += tmp; + } + // Contribution 28 + { + Avm_DECLARE_VIEWS(28); + + auto tmp = ((avm_alu_p_sub_b_lo - + ((-avm_alu_b_lo + FF(uint256_t{ 4891460686036598784UL, 2896914383306846353UL, 0UL, 0UL })) + + (avm_alu_p_b_borrow * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL })))) * + avm_alu_cmp_sel); + tmp *= scaling_factor; + std::get<28>(evals) += tmp; + } + // Contribution 29 + { + Avm_DECLARE_VIEWS(29); + + auto tmp = ((avm_alu_p_sub_b_hi - + ((-avm_alu_b_hi + FF(uint256_t{ 13281191951274694749UL, 3486998266802970665UL, 0UL, 0UL })) - + avm_alu_p_b_borrow)) * + avm_alu_cmp_sel); + tmp *= scaling_factor; + std::get<29>(evals) += tmp; + } + // Contribution 30 + { + Avm_DECLARE_VIEWS(30); + + auto tmp = + ((avm_alu_res_lo - + (((((avm_alu_a_lo - avm_alu_b_lo) - FF(1)) + (avm_alu_borrow * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) * + ((avm_alu_op_lt * avm_alu_ic) + ((-avm_alu_ic + FF(1)) * avm_alu_op_lte))) + + (((avm_alu_b_lo - avm_alu_a_lo) + (avm_alu_borrow * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))) * + (-((avm_alu_op_lt * avm_alu_ic) + ((-avm_alu_ic + FF(1)) * avm_alu_op_lte)) + FF(1))))) * + avm_alu_cmp_sel); + tmp *= scaling_factor; + std::get<30>(evals) += tmp; + } + // Contribution 31 + { + Avm_DECLARE_VIEWS(31); + + auto tmp = ((avm_alu_res_hi - + ((((avm_alu_a_hi - avm_alu_b_hi) - avm_alu_borrow) * + ((avm_alu_op_lt * avm_alu_ic) + ((-avm_alu_ic + FF(1)) * avm_alu_op_lte))) + + (((avm_alu_b_hi - avm_alu_a_hi) - avm_alu_borrow) * + (-((avm_alu_op_lt * avm_alu_ic) + ((-avm_alu_ic + FF(1)) * avm_alu_op_lte)) + FF(1))))) * + avm_alu_cmp_sel); + tmp *= scaling_factor; + std::get<31>(evals) += tmp; + } + // Contribution 32 + { + Avm_DECLARE_VIEWS(32); + + auto tmp = (((avm_alu_cmp_rng_ctr_shift - avm_alu_cmp_rng_ctr) + FF(1)) * avm_alu_cmp_rng_ctr); + tmp *= scaling_factor; + std::get<32>(evals) += tmp; + } + // Contribution 33 + { + Avm_DECLARE_VIEWS(33); + + auto tmp = ((avm_alu_cmp_rng_ctr_shift - FF(4)) * avm_alu_cmp_sel); + tmp *= scaling_factor; + std::get<33>(evals) += tmp; + } + // Contribution 34 + { + Avm_DECLARE_VIEWS(34); + + auto tmp = (avm_alu_rng_chk_sel * (-avm_alu_rng_chk_sel + FF(1))); + tmp *= scaling_factor; + std::get<34>(evals) += tmp; + } + // Contribution 35 + { + Avm_DECLARE_VIEWS(35); + + auto tmp = (avm_alu_rng_chk_sel * avm_alu_cmp_sel); + tmp *= scaling_factor; + std::get<35>(evals) += tmp; + } + // Contribution 36 + { + Avm_DECLARE_VIEWS(36); + + auto tmp = ((avm_alu_cmp_rng_ctr * (((-avm_alu_rng_chk_sel + FF(1)) * (-avm_alu_op_eq_diff_inv + FF(1))) + + avm_alu_op_eq_diff_inv)) - + avm_alu_rng_chk_sel); + tmp *= scaling_factor; + std::get<36>(evals) += tmp; + } + // Contribution 37 + { + Avm_DECLARE_VIEWS(37); + + auto tmp = (avm_alu_rng_chk_lookup_selector - (avm_alu_cmp_sel + avm_alu_rng_chk_sel)); + tmp *= scaling_factor; + std::get<37>(evals) += tmp; + } + // Contribution 38 + { + Avm_DECLARE_VIEWS(38); + + auto tmp = + (avm_alu_a_lo - (((((((((avm_alu_u8_r0 + (avm_alu_u8_r1 * FF(256))) + (avm_alu_u16_r0 * FF(65536))) + + (avm_alu_u16_r1 * FF(4294967296UL))) + + (avm_alu_u16_r2 * FF(281474976710656UL))) + + (avm_alu_u16_r3 * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + + (avm_alu_u16_r4 * FF(uint256_t{ 0UL, 65536UL, 0UL, 0UL }))) + + (avm_alu_u16_r5 * FF(uint256_t{ 0UL, 4294967296UL, 0UL, 0UL }))) + + (avm_alu_u16_r6 * FF(uint256_t{ 0UL, 281474976710656UL, 0UL, 0UL }))) * + (avm_alu_rng_chk_sel + avm_alu_cmp_sel))); + tmp *= scaling_factor; + std::get<38>(evals) += tmp; + } + // Contribution 39 + { + Avm_DECLARE_VIEWS(39); + + auto tmp = (avm_alu_a_hi - + ((((((((avm_alu_u16_r7 + (avm_alu_u16_r8 * FF(65536))) + (avm_alu_u16_r9 * FF(4294967296UL))) + + (avm_alu_u16_r10 * FF(281474976710656UL))) + + (avm_alu_u16_r11 * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + + (avm_alu_u16_r12 * FF(uint256_t{ 0UL, 65536UL, 0UL, 0UL }))) + + (avm_alu_u16_r13 * FF(uint256_t{ 0UL, 4294967296UL, 0UL, 0UL }))) + + (avm_alu_u16_r14 * FF(uint256_t{ 0UL, 281474976710656UL, 0UL, 0UL }))) * + (avm_alu_rng_chk_sel + avm_alu_cmp_sel))); + tmp *= scaling_factor; + std::get<39>(evals) += tmp; + } + // Contribution 40 + { + Avm_DECLARE_VIEWS(40); + + auto tmp = ((avm_alu_a_lo_shift - avm_alu_b_lo) * avm_alu_rng_chk_sel_shift); + tmp *= scaling_factor; + std::get<40>(evals) += tmp; + } + // Contribution 41 + { + Avm_DECLARE_VIEWS(41); + + auto tmp = ((avm_alu_a_hi_shift - avm_alu_b_hi) * avm_alu_rng_chk_sel_shift); + tmp *= scaling_factor; + std::get<41>(evals) += tmp; + } + // Contribution 42 + { + Avm_DECLARE_VIEWS(42); + + auto tmp = ((avm_alu_b_lo_shift - avm_alu_p_sub_a_lo) * avm_alu_rng_chk_sel_shift); + tmp *= scaling_factor; + std::get<42>(evals) += tmp; + } + // Contribution 43 + { + Avm_DECLARE_VIEWS(43); + + auto tmp = ((avm_alu_b_hi_shift - avm_alu_p_sub_a_hi) * avm_alu_rng_chk_sel_shift); + tmp *= scaling_factor; + std::get<43>(evals) += tmp; + } + // Contribution 44 + { + Avm_DECLARE_VIEWS(44); + + auto tmp = ((avm_alu_p_sub_a_lo_shift - avm_alu_p_sub_b_lo) * avm_alu_rng_chk_sel_shift); + tmp *= scaling_factor; + std::get<44>(evals) += tmp; + } + // Contribution 45 + { + Avm_DECLARE_VIEWS(45); + + auto tmp = ((avm_alu_p_sub_a_hi_shift - avm_alu_p_sub_b_hi) * avm_alu_rng_chk_sel_shift); + tmp *= scaling_factor; + std::get<45>(evals) += tmp; + } + // Contribution 46 + { + Avm_DECLARE_VIEWS(46); + + auto tmp = ((avm_alu_p_sub_b_lo_shift - avm_alu_res_lo) * avm_alu_rng_chk_sel_shift); + tmp *= scaling_factor; + std::get<46>(evals) += tmp; + } + // Contribution 47 + { + Avm_DECLARE_VIEWS(47); + + auto tmp = ((avm_alu_p_sub_b_hi_shift - avm_alu_res_hi) * avm_alu_rng_chk_sel_shift); + tmp *= scaling_factor; + std::get<47>(evals) += tmp; } } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp index c6cb110f1f9..b3ae090ccdf 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/avm_main.hpp @@ -41,6 +41,8 @@ template struct Avm_mainRow { FF avm_main_sel_op_and{}; FF avm_main_sel_op_div{}; FF avm_main_sel_op_eq{}; + FF avm_main_sel_op_lt{}; + FF avm_main_sel_op_lte{}; FF avm_main_sel_op_mul{}; FF avm_main_sel_op_not{}; FF avm_main_sel_op_or{}; @@ -53,43 +55,43 @@ template struct Avm_mainRow { inline std::string get_relation_label_avm_main(int index) { switch (index) { - case 25: - return "EQ_OUTPUT_U8"; + case 27: + return "OUTPUT_U8"; - case 26: + case 28: return "SUBOP_DIVISION_FF"; - case 27: + case 29: return "SUBOP_DIVISION_ZERO_ERR1"; - case 28: + case 30: return "SUBOP_DIVISION_ZERO_ERR2"; - case 29: + case 31: return "SUBOP_ERROR_RELEVANT_OP"; - case 31: + case 33: return "RETURN_POINTER_INCREMENT"; - case 37: + case 39: return "RETURN_POINTER_DECREMENT"; - case 42: + case 44: return "PC_INCREMENT"; - case 43: + case 45: return "INTERNAL_RETURN_POINTER_CONSISTENCY"; - case 44: + case 46: return "MOV_SAME_VALUE"; - case 45: + case 47: return "MOV_MAIN_SAME_TAG"; - case 47: + case 49: return "BIN_SEL_1"; - case 48: + case 50: return "BIN_SEL_2"; } return std::to_string(index); @@ -99,9 +101,9 @@ template class avm_mainImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 2, + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 2, }; template @@ -187,7 +189,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(9); - auto tmp = (avm_main_sel_internal_call * (-avm_main_sel_internal_call + FF(1))); + auto tmp = (avm_main_sel_op_lt * (-avm_main_sel_op_lt + FF(1))); tmp *= scaling_factor; std::get<9>(evals) += tmp; } @@ -195,7 +197,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(10); - auto tmp = (avm_main_sel_internal_return * (-avm_main_sel_internal_return + FF(1))); + auto tmp = (avm_main_sel_op_lte * (-avm_main_sel_op_lte + FF(1))); tmp *= scaling_factor; std::get<10>(evals) += tmp; } @@ -203,7 +205,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(11); - auto tmp = (avm_main_sel_jump * (-avm_main_sel_jump + FF(1))); + auto tmp = (avm_main_sel_internal_call * (-avm_main_sel_internal_call + FF(1))); tmp *= scaling_factor; std::get<11>(evals) += tmp; } @@ -211,7 +213,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(12); - auto tmp = (avm_main_sel_halt * (-avm_main_sel_halt + FF(1))); + auto tmp = (avm_main_sel_internal_return * (-avm_main_sel_internal_return + FF(1))); tmp *= scaling_factor; std::get<12>(evals) += tmp; } @@ -219,7 +221,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(13); - auto tmp = (avm_main_sel_mov * (-avm_main_sel_mov + FF(1))); + auto tmp = (avm_main_sel_jump * (-avm_main_sel_jump + FF(1))); tmp *= scaling_factor; std::get<13>(evals) += tmp; } @@ -227,7 +229,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(14); - auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); + auto tmp = (avm_main_sel_halt * (-avm_main_sel_halt + FF(1))); tmp *= scaling_factor; std::get<14>(evals) += tmp; } @@ -235,7 +237,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(15); - auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); + auto tmp = (avm_main_sel_mov * (-avm_main_sel_mov + FF(1))); tmp *= scaling_factor; std::get<15>(evals) += tmp; } @@ -243,7 +245,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(16); - auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); + auto tmp = (avm_main_op_err * (-avm_main_op_err + FF(1))); tmp *= scaling_factor; std::get<16>(evals) += tmp; } @@ -251,7 +253,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(17); - auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); + auto tmp = (avm_main_tag_err * (-avm_main_tag_err + FF(1))); tmp *= scaling_factor; std::get<17>(evals) += tmp; } @@ -259,7 +261,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(18); - auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); + auto tmp = (avm_main_mem_op_a * (-avm_main_mem_op_a + FF(1))); tmp *= scaling_factor; std::get<18>(evals) += tmp; } @@ -267,7 +269,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(19); - auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); + auto tmp = (avm_main_mem_op_b * (-avm_main_mem_op_b + FF(1))); tmp *= scaling_factor; std::get<19>(evals) += tmp; } @@ -275,7 +277,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(20); - auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); + auto tmp = (avm_main_mem_op_c * (-avm_main_mem_op_c + FF(1))); tmp *= scaling_factor; std::get<20>(evals) += tmp; } @@ -283,7 +285,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(21); - auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); + auto tmp = (avm_main_rwa * (-avm_main_rwa + FF(1))); tmp *= scaling_factor; std::get<21>(evals) += tmp; } @@ -291,7 +293,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(22); - auto tmp = (avm_main_ind_op_a * (-avm_main_ind_op_a + FF(1))); + auto tmp = (avm_main_rwb * (-avm_main_rwb + FF(1))); tmp *= scaling_factor; std::get<22>(evals) += tmp; } @@ -299,7 +301,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(23); - auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); + auto tmp = (avm_main_rwc * (-avm_main_rwc + FF(1))); tmp *= scaling_factor; std::get<23>(evals) += tmp; } @@ -307,7 +309,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(24); - auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); + auto tmp = (avm_main_ind_op_a * (-avm_main_ind_op_a + FF(1))); tmp *= scaling_factor; std::get<24>(evals) += tmp; } @@ -315,7 +317,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(25); - auto tmp = (avm_main_sel_op_eq * (avm_main_w_in_tag - FF(1))); + auto tmp = (avm_main_ind_op_b * (-avm_main_ind_op_b + FF(1))); tmp *= scaling_factor; std::get<25>(evals) += tmp; } @@ -323,8 +325,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(26); - auto tmp = - ((avm_main_sel_op_div * (-avm_main_op_err + FF(1))) * ((avm_main_ic * avm_main_ib) - avm_main_ia)); + auto tmp = (avm_main_ind_op_c * (-avm_main_ind_op_c + FF(1))); tmp *= scaling_factor; std::get<26>(evals) += tmp; } @@ -332,7 +333,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(27); - auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); + auto tmp = + (((avm_main_sel_op_eq + avm_main_sel_op_lte) + avm_main_sel_op_lt) * (avm_main_w_in_tag - FF(1))); tmp *= scaling_factor; std::get<27>(evals) += tmp; } @@ -340,7 +342,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(28); - auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); + auto tmp = + ((avm_main_sel_op_div * (-avm_main_op_err + FF(1))) * ((avm_main_ic * avm_main_ib) - avm_main_ia)); tmp *= scaling_factor; std::get<28>(evals) += tmp; } @@ -348,7 +351,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(29); - auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); + auto tmp = (avm_main_sel_op_div * (((avm_main_ib * avm_main_inv) - FF(1)) + avm_main_op_err)); tmp *= scaling_factor; std::get<29>(evals) += tmp; } @@ -356,7 +359,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(30); - auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); + auto tmp = ((avm_main_sel_op_div * avm_main_op_err) * (-avm_main_inv + FF(1))); tmp *= scaling_factor; std::get<30>(evals) += tmp; } @@ -364,8 +367,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(31); - auto tmp = (avm_main_sel_internal_call * - (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr + FF(1)))); + auto tmp = (avm_main_op_err * (avm_main_sel_op_div - FF(1))); tmp *= scaling_factor; std::get<31>(evals) += tmp; } @@ -373,7 +375,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(32); - auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); + auto tmp = (avm_main_sel_jump * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<32>(evals) += tmp; } @@ -381,7 +383,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(33); - auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_internal_call * + (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr + FF(1)))); tmp *= scaling_factor; std::get<33>(evals) += tmp; } @@ -389,7 +392,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(34); - auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); + auto tmp = (avm_main_sel_internal_call * (avm_main_internal_return_ptr - avm_main_mem_idx_b)); tmp *= scaling_factor; std::get<34>(evals) += tmp; } @@ -397,7 +400,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(35); - auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); + auto tmp = (avm_main_sel_internal_call * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<35>(evals) += tmp; } @@ -405,7 +408,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(36); - auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); + auto tmp = (avm_main_sel_internal_call * ((avm_main_pc + FF(1)) - avm_main_ib)); tmp *= scaling_factor; std::get<36>(evals) += tmp; } @@ -413,8 +416,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(37); - auto tmp = (avm_main_sel_internal_return * - (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr - FF(1)))); + auto tmp = (avm_main_sel_internal_call * (avm_main_rwb - FF(1))); tmp *= scaling_factor; std::get<37>(evals) += tmp; } @@ -422,7 +424,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(38); - auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); + auto tmp = (avm_main_sel_internal_call * (avm_main_mem_op_b - FF(1))); tmp *= scaling_factor; std::get<38>(evals) += tmp; } @@ -430,7 +432,8 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(39); - auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); + auto tmp = (avm_main_sel_internal_return * + (avm_main_internal_return_ptr_shift - (avm_main_internal_return_ptr - FF(1)))); tmp *= scaling_factor; std::get<39>(evals) += tmp; } @@ -438,7 +441,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(40); - auto tmp = (avm_main_sel_internal_return * avm_main_rwa); + auto tmp = (avm_main_sel_internal_return * ((avm_main_internal_return_ptr - FF(1)) - avm_main_mem_idx_a)); tmp *= scaling_factor; std::get<40>(evals) += tmp; } @@ -446,7 +449,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(41); - auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); + auto tmp = (avm_main_sel_internal_return * (avm_main_pc_shift - avm_main_ia)); tmp *= scaling_factor; std::get<41>(evals) += tmp; } @@ -454,15 +457,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(42); - auto tmp = - ((((-avm_main_first + FF(1)) * (-avm_main_sel_halt + FF(1))) * - ((((((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_div) + avm_main_sel_op_mul) + - avm_main_sel_op_not) + - avm_main_sel_op_eq) + - avm_main_sel_op_and) + - avm_main_sel_op_or) + - avm_main_sel_op_xor)) * - (avm_main_pc_shift - (avm_main_pc + FF(1)))); + auto tmp = (avm_main_sel_internal_return * avm_main_rwa); tmp *= scaling_factor; std::get<42>(evals) += tmp; } @@ -470,10 +465,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(43); - auto tmp = ((-(((avm_main_first + avm_main_sel_internal_call) + avm_main_sel_internal_return) + - avm_main_sel_halt) + - FF(1)) * - (avm_main_internal_return_ptr_shift - avm_main_internal_return_ptr)); + auto tmp = (avm_main_sel_internal_return * (avm_main_mem_op_a - FF(1))); tmp *= scaling_factor; std::get<43>(evals) += tmp; } @@ -481,7 +473,15 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(44); - auto tmp = (avm_main_sel_mov * (avm_main_ia - avm_main_ic)); + auto tmp = + ((((-avm_main_first + FF(1)) * (-avm_main_sel_halt + FF(1))) * + ((((((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_div) + avm_main_sel_op_mul) + + avm_main_sel_op_not) + + avm_main_sel_op_eq) + + avm_main_sel_op_and) + + avm_main_sel_op_or) + + avm_main_sel_op_xor)) * + (avm_main_pc_shift - (avm_main_pc + FF(1)))); tmp *= scaling_factor; std::get<44>(evals) += tmp; } @@ -489,7 +489,10 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(45); - auto tmp = (avm_main_sel_mov * (avm_main_r_in_tag - avm_main_w_in_tag)); + auto tmp = ((-(((avm_main_first + avm_main_sel_internal_call) + avm_main_sel_internal_return) + + avm_main_sel_halt) + + FF(1)) * + (avm_main_internal_return_ptr_shift - avm_main_internal_return_ptr)); tmp *= scaling_factor; std::get<45>(evals) += tmp; } @@ -497,10 +500,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(46); - auto tmp = (avm_main_alu_sel - - (((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_mul) + avm_main_sel_op_not) + - avm_main_sel_op_eq) * - (-avm_main_tag_err + FF(1)))); + auto tmp = (avm_main_sel_mov * (avm_main_ia - avm_main_ic)); tmp *= scaling_factor; std::get<46>(evals) += tmp; } @@ -508,7 +508,7 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(47); - auto tmp = (avm_main_bin_op_id - (avm_main_sel_op_or + (avm_main_sel_op_xor * FF(2)))); + auto tmp = (avm_main_sel_mov * (avm_main_r_in_tag - avm_main_w_in_tag)); tmp *= scaling_factor; std::get<47>(evals) += tmp; } @@ -516,10 +516,32 @@ template class avm_mainImpl { { Avm_DECLARE_VIEWS(48); - auto tmp = (avm_main_bin_sel - ((avm_main_sel_op_and + avm_main_sel_op_or) + avm_main_sel_op_xor)); + auto tmp = + (avm_main_alu_sel - + (((((((avm_main_sel_op_add + avm_main_sel_op_sub) + avm_main_sel_op_mul) + avm_main_sel_op_not) + + avm_main_sel_op_eq) + + avm_main_sel_op_lt) + + avm_main_sel_op_lte) * + (-avm_main_tag_err + FF(1)))); tmp *= scaling_factor; std::get<48>(evals) += tmp; } + // Contribution 49 + { + Avm_DECLARE_VIEWS(49); + + auto tmp = (avm_main_bin_op_id - (avm_main_sel_op_or + (avm_main_sel_op_xor * FF(2)))); + tmp *= scaling_factor; + std::get<49>(evals) += tmp; + } + // Contribution 50 + { + Avm_DECLARE_VIEWS(50); + + auto tmp = (avm_main_bin_sel - ((avm_main_sel_op_and + avm_main_sel_op_or) + avm_main_sel_op_xor)); + tmp *= scaling_factor; + std::get<50>(evals) += tmp; + } } }; 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 7dc659afa36..8bebe5f792d 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/declare_views.hpp @@ -4,9 +4,16 @@ using View = typename Accumulator::View; \ [[maybe_unused]] auto avm_main_clk = View(new_term.avm_main_clk); \ [[maybe_unused]] auto avm_main_first = View(new_term.avm_main_first); \ + [[maybe_unused]] auto avm_alu_a_hi = View(new_term.avm_alu_a_hi); \ + [[maybe_unused]] auto avm_alu_a_lo = View(new_term.avm_alu_a_lo); \ [[maybe_unused]] auto avm_alu_alu_sel = View(new_term.avm_alu_alu_sel); \ + [[maybe_unused]] auto avm_alu_b_hi = View(new_term.avm_alu_b_hi); \ + [[maybe_unused]] auto avm_alu_b_lo = View(new_term.avm_alu_b_lo); \ + [[maybe_unused]] auto avm_alu_borrow = View(new_term.avm_alu_borrow); \ [[maybe_unused]] auto avm_alu_cf = View(new_term.avm_alu_cf); \ [[maybe_unused]] auto avm_alu_clk = View(new_term.avm_alu_clk); \ + [[maybe_unused]] auto avm_alu_cmp_rng_ctr = View(new_term.avm_alu_cmp_rng_ctr); \ + [[maybe_unused]] auto avm_alu_cmp_sel = View(new_term.avm_alu_cmp_sel); \ [[maybe_unused]] auto avm_alu_ff_tag = View(new_term.avm_alu_ff_tag); \ [[maybe_unused]] auto avm_alu_ia = View(new_term.avm_alu_ia); \ [[maybe_unused]] auto avm_alu_ib = View(new_term.avm_alu_ib); \ @@ -16,9 +23,21 @@ [[maybe_unused]] auto avm_alu_op_div = View(new_term.avm_alu_op_div); \ [[maybe_unused]] auto avm_alu_op_eq = View(new_term.avm_alu_op_eq); \ [[maybe_unused]] auto avm_alu_op_eq_diff_inv = View(new_term.avm_alu_op_eq_diff_inv); \ + [[maybe_unused]] auto avm_alu_op_lt = View(new_term.avm_alu_op_lt); \ + [[maybe_unused]] auto avm_alu_op_lte = View(new_term.avm_alu_op_lte); \ [[maybe_unused]] auto avm_alu_op_mul = View(new_term.avm_alu_op_mul); \ [[maybe_unused]] auto avm_alu_op_not = View(new_term.avm_alu_op_not); \ [[maybe_unused]] auto avm_alu_op_sub = View(new_term.avm_alu_op_sub); \ + [[maybe_unused]] auto avm_alu_p_a_borrow = View(new_term.avm_alu_p_a_borrow); \ + [[maybe_unused]] auto avm_alu_p_b_borrow = View(new_term.avm_alu_p_b_borrow); \ + [[maybe_unused]] auto avm_alu_p_sub_a_hi = View(new_term.avm_alu_p_sub_a_hi); \ + [[maybe_unused]] auto avm_alu_p_sub_a_lo = View(new_term.avm_alu_p_sub_a_lo); \ + [[maybe_unused]] auto avm_alu_p_sub_b_hi = View(new_term.avm_alu_p_sub_b_hi); \ + [[maybe_unused]] auto avm_alu_p_sub_b_lo = View(new_term.avm_alu_p_sub_b_lo); \ + [[maybe_unused]] auto avm_alu_res_hi = View(new_term.avm_alu_res_hi); \ + [[maybe_unused]] auto avm_alu_res_lo = View(new_term.avm_alu_res_lo); \ + [[maybe_unused]] auto avm_alu_rng_chk_lookup_selector = View(new_term.avm_alu_rng_chk_lookup_selector); \ + [[maybe_unused]] auto avm_alu_rng_chk_sel = View(new_term.avm_alu_rng_chk_sel); \ [[maybe_unused]] auto avm_alu_u128_tag = View(new_term.avm_alu_u128_tag); \ [[maybe_unused]] auto avm_alu_u16_r0 = View(new_term.avm_alu_u16_r0); \ [[maybe_unused]] auto avm_alu_u16_r1 = View(new_term.avm_alu_u16_r1); \ @@ -98,6 +117,8 @@ [[maybe_unused]] auto avm_main_sel_op_and = View(new_term.avm_main_sel_op_and); \ [[maybe_unused]] auto avm_main_sel_op_div = View(new_term.avm_main_sel_op_div); \ [[maybe_unused]] auto avm_main_sel_op_eq = View(new_term.avm_main_sel_op_eq); \ + [[maybe_unused]] auto avm_main_sel_op_lt = View(new_term.avm_main_sel_op_lt); \ + [[maybe_unused]] auto avm_main_sel_op_lte = View(new_term.avm_main_sel_op_lte); \ [[maybe_unused]] auto avm_main_sel_op_mul = View(new_term.avm_main_sel_op_mul); \ [[maybe_unused]] auto avm_main_sel_op_not = View(new_term.avm_main_sel_op_not); \ [[maybe_unused]] auto avm_main_sel_op_or = View(new_term.avm_main_sel_op_or); \ @@ -138,10 +159,54 @@ [[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_u8_0 = View(new_term.lookup_u8_0); \ + [[maybe_unused]] auto lookup_u8_1 = View(new_term.lookup_u8_1); \ + [[maybe_unused]] auto lookup_u16_0 = View(new_term.lookup_u16_0); \ + [[maybe_unused]] auto lookup_u16_1 = View(new_term.lookup_u16_1); \ + [[maybe_unused]] auto lookup_u16_2 = View(new_term.lookup_u16_2); \ + [[maybe_unused]] auto lookup_u16_3 = View(new_term.lookup_u16_3); \ + [[maybe_unused]] auto lookup_u16_4 = View(new_term.lookup_u16_4); \ + [[maybe_unused]] auto lookup_u16_5 = View(new_term.lookup_u16_5); \ + [[maybe_unused]] auto lookup_u16_6 = View(new_term.lookup_u16_6); \ + [[maybe_unused]] auto lookup_u16_7 = View(new_term.lookup_u16_7); \ + [[maybe_unused]] auto lookup_u16_8 = View(new_term.lookup_u16_8); \ + [[maybe_unused]] auto lookup_u16_9 = View(new_term.lookup_u16_9); \ + [[maybe_unused]] auto lookup_u16_10 = View(new_term.lookup_u16_10); \ + [[maybe_unused]] auto lookup_u16_11 = View(new_term.lookup_u16_11); \ + [[maybe_unused]] auto lookup_u16_12 = View(new_term.lookup_u16_12); \ + [[maybe_unused]] auto lookup_u16_13 = View(new_term.lookup_u16_13); \ + [[maybe_unused]] auto lookup_u16_14 = View(new_term.lookup_u16_14); \ [[maybe_unused]] auto lookup_byte_lengths_counts = View(new_term.lookup_byte_lengths_counts); \ [[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_u8_0_counts = View(new_term.lookup_u8_0_counts); \ + [[maybe_unused]] auto lookup_u8_1_counts = View(new_term.lookup_u8_1_counts); \ + [[maybe_unused]] auto lookup_u16_0_counts = View(new_term.lookup_u16_0_counts); \ + [[maybe_unused]] auto lookup_u16_1_counts = View(new_term.lookup_u16_1_counts); \ + [[maybe_unused]] auto lookup_u16_2_counts = View(new_term.lookup_u16_2_counts); \ + [[maybe_unused]] auto lookup_u16_3_counts = View(new_term.lookup_u16_3_counts); \ + [[maybe_unused]] auto lookup_u16_4_counts = View(new_term.lookup_u16_4_counts); \ + [[maybe_unused]] auto lookup_u16_5_counts = View(new_term.lookup_u16_5_counts); \ + [[maybe_unused]] auto lookup_u16_6_counts = View(new_term.lookup_u16_6_counts); \ + [[maybe_unused]] auto lookup_u16_7_counts = View(new_term.lookup_u16_7_counts); \ + [[maybe_unused]] auto lookup_u16_8_counts = View(new_term.lookup_u16_8_counts); \ + [[maybe_unused]] auto lookup_u16_9_counts = View(new_term.lookup_u16_9_counts); \ + [[maybe_unused]] auto lookup_u16_10_counts = View(new_term.lookup_u16_10_counts); \ + [[maybe_unused]] auto lookup_u16_11_counts = View(new_term.lookup_u16_11_counts); \ + [[maybe_unused]] auto lookup_u16_12_counts = View(new_term.lookup_u16_12_counts); \ + [[maybe_unused]] auto lookup_u16_13_counts = View(new_term.lookup_u16_13_counts); \ + [[maybe_unused]] auto lookup_u16_14_counts = View(new_term.lookup_u16_14_counts); \ + [[maybe_unused]] auto avm_alu_a_hi_shift = View(new_term.avm_alu_a_hi_shift); \ + [[maybe_unused]] auto avm_alu_a_lo_shift = View(new_term.avm_alu_a_lo_shift); \ + [[maybe_unused]] auto avm_alu_b_hi_shift = View(new_term.avm_alu_b_hi_shift); \ + [[maybe_unused]] auto avm_alu_b_lo_shift = View(new_term.avm_alu_b_lo_shift); \ + [[maybe_unused]] auto avm_alu_cmp_rng_ctr_shift = View(new_term.avm_alu_cmp_rng_ctr_shift); \ + [[maybe_unused]] auto avm_alu_p_sub_a_hi_shift = View(new_term.avm_alu_p_sub_a_hi_shift); \ + [[maybe_unused]] auto avm_alu_p_sub_a_lo_shift = View(new_term.avm_alu_p_sub_a_lo_shift); \ + [[maybe_unused]] auto avm_alu_p_sub_b_hi_shift = View(new_term.avm_alu_p_sub_b_hi_shift); \ + [[maybe_unused]] auto avm_alu_p_sub_b_lo_shift = View(new_term.avm_alu_p_sub_b_lo_shift); \ + [[maybe_unused]] auto avm_alu_rng_chk_sel_shift = View(new_term.avm_alu_rng_chk_sel_shift); \ [[maybe_unused]] auto avm_alu_u16_r0_shift = View(new_term.avm_alu_u16_r0_shift); \ [[maybe_unused]] auto avm_alu_u16_r1_shift = View(new_term.avm_alu_u16_r1_shift); \ [[maybe_unused]] auto avm_alu_u16_r2_shift = View(new_term.avm_alu_u16_r2_shift); \ diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_0.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_0.hpp new file mode 100644 index 00000000000..67c79053609 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_0.hpp @@ -0,0 +1,166 @@ + + +#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_u16_0_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_0, + in.lookup_u16_0_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r0, + 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_u16_0, + in.lookup_u16_0_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r0, + in.avm_main_clk); + } +}; + +template using lookup_u16_0_relation = GenericLookupRelation; +template using lookup_u16_0 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_1.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_1.hpp new file mode 100644 index 00000000000..c5c39dd2f80 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_1.hpp @@ -0,0 +1,166 @@ + + +#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_u16_1_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_1, + in.lookup_u16_1_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r1, + 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_u16_1, + in.lookup_u16_1_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r1, + in.avm_main_clk); + } +}; + +template using lookup_u16_1_relation = GenericLookupRelation; +template using lookup_u16_1 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_10.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_10.hpp new file mode 100644 index 00000000000..275dcb0f824 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_10.hpp @@ -0,0 +1,166 @@ + + +#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_u16_10_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_10, + in.lookup_u16_10_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r10, + 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_u16_10, + in.lookup_u16_10_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r10, + in.avm_main_clk); + } +}; + +template using lookup_u16_10_relation = GenericLookupRelation; +template using lookup_u16_10 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_11.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_11.hpp new file mode 100644 index 00000000000..b94a5f65d84 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_11.hpp @@ -0,0 +1,166 @@ + + +#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_u16_11_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_11, + in.lookup_u16_11_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r11, + 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_u16_11, + in.lookup_u16_11_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r11, + in.avm_main_clk); + } +}; + +template using lookup_u16_11_relation = GenericLookupRelation; +template using lookup_u16_11 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_12.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_12.hpp new file mode 100644 index 00000000000..4fc5cca4ebe --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_12.hpp @@ -0,0 +1,166 @@ + + +#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_u16_12_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_12, + in.lookup_u16_12_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r12, + 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_u16_12, + in.lookup_u16_12_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r12, + in.avm_main_clk); + } +}; + +template using lookup_u16_12_relation = GenericLookupRelation; +template using lookup_u16_12 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_13.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_13.hpp new file mode 100644 index 00000000000..908d478b8ad --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_13.hpp @@ -0,0 +1,166 @@ + + +#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_u16_13_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_13, + in.lookup_u16_13_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r13, + 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_u16_13, + in.lookup_u16_13_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r13, + in.avm_main_clk); + } +}; + +template using lookup_u16_13_relation = GenericLookupRelation; +template using lookup_u16_13 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_14.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_14.hpp new file mode 100644 index 00000000000..735361f8e6c --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_14.hpp @@ -0,0 +1,166 @@ + + +#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_u16_14_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_14, + in.lookup_u16_14_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r14, + 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_u16_14, + in.lookup_u16_14_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r14, + in.avm_main_clk); + } +}; + +template using lookup_u16_14_relation = GenericLookupRelation; +template using lookup_u16_14 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_2.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_2.hpp new file mode 100644 index 00000000000..8aa66dc7a70 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_2.hpp @@ -0,0 +1,166 @@ + + +#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_u16_2_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_2, + in.lookup_u16_2_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r2, + 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_u16_2, + in.lookup_u16_2_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r2, + in.avm_main_clk); + } +}; + +template using lookup_u16_2_relation = GenericLookupRelation; +template using lookup_u16_2 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_3.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_3.hpp new file mode 100644 index 00000000000..b1bda551024 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_3.hpp @@ -0,0 +1,166 @@ + + +#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_u16_3_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_3, + in.lookup_u16_3_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r3, + 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_u16_3, + in.lookup_u16_3_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r3, + in.avm_main_clk); + } +}; + +template using lookup_u16_3_relation = GenericLookupRelation; +template using lookup_u16_3 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_4.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_4.hpp new file mode 100644 index 00000000000..5984e1a6e59 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_4.hpp @@ -0,0 +1,166 @@ + + +#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_u16_4_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_4, + in.lookup_u16_4_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r4, + 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_u16_4, + in.lookup_u16_4_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r4, + in.avm_main_clk); + } +}; + +template using lookup_u16_4_relation = GenericLookupRelation; +template using lookup_u16_4 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_5.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_5.hpp new file mode 100644 index 00000000000..d1bc6db3a29 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_5.hpp @@ -0,0 +1,166 @@ + + +#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_u16_5_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_5, + in.lookup_u16_5_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r5, + 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_u16_5, + in.lookup_u16_5_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r5, + in.avm_main_clk); + } +}; + +template using lookup_u16_5_relation = GenericLookupRelation; +template using lookup_u16_5 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_6.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_6.hpp new file mode 100644 index 00000000000..3838f21e967 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_6.hpp @@ -0,0 +1,166 @@ + + +#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_u16_6_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_6, + in.lookup_u16_6_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r6, + 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_u16_6, + in.lookup_u16_6_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r6, + in.avm_main_clk); + } +}; + +template using lookup_u16_6_relation = GenericLookupRelation; +template using lookup_u16_6 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_7.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_7.hpp new file mode 100644 index 00000000000..84b098172e9 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_7.hpp @@ -0,0 +1,166 @@ + + +#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_u16_7_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_7, + in.lookup_u16_7_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r7, + 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_u16_7, + in.lookup_u16_7_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r7, + in.avm_main_clk); + } +}; + +template using lookup_u16_7_relation = GenericLookupRelation; +template using lookup_u16_7 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_8.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_8.hpp new file mode 100644 index 00000000000..f75f9fa9c28 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_8.hpp @@ -0,0 +1,166 @@ + + +#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_u16_8_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_8, + in.lookup_u16_8_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r8, + 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_u16_8, + in.lookup_u16_8_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r8, + in.avm_main_clk); + } +}; + +template using lookup_u16_8_relation = GenericLookupRelation; +template using lookup_u16_8 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_9.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_9.hpp new file mode 100644 index 00000000000..5e72a369ac4 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u16_9.hpp @@ -0,0 +1,166 @@ + + +#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_u16_9_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_alu_rng_chk_lookup_selector == 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_alu_rng_chk_lookup_selector); + 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_u16_9, + in.lookup_u16_9_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r9, + 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_u16_9, + in.lookup_u16_9_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_16, + in.avm_alu_u16_r9, + in.avm_main_clk); + } +}; + +template using lookup_u16_9_relation = GenericLookupRelation; +template using lookup_u16_9 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u8_0.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u8_0.hpp new file mode 100644 index 00000000000..37b5936f008 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u8_0.hpp @@ -0,0 +1,166 @@ + + +#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_u8_0_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_alu_rng_chk_lookup_selector == 1 || in.avm_main_sel_rng_8 == 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_alu_rng_chk_lookup_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_8); + 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_u8_0, + in.lookup_u8_0_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_8, + in.avm_alu_u8_r0, + 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_u8_0, + in.lookup_u8_0_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_8, + in.avm_alu_u8_r0, + in.avm_main_clk); + } +}; + +template using lookup_u8_0_relation = GenericLookupRelation; +template using lookup_u8_0 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u8_1.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u8_1.hpp new file mode 100644 index 00000000000..7941ecb1aee --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/lookup_u8_1.hpp @@ -0,0 +1,166 @@ + + +#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_u8_1_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_alu_rng_chk_lookup_selector == 1 || in.avm_main_sel_rng_8 == 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_alu_rng_chk_lookup_selector); + const auto is_table_entry = View(in.avm_main_sel_rng_8); + 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_u8_1, + in.lookup_u8_1_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_8, + in.avm_alu_u8_r1, + 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_u8_1, + in.lookup_u8_1_counts, + in.avm_alu_rng_chk_lookup_selector, + in.avm_main_sel_rng_8, + in.avm_alu_u8_r1, + in.avm_main_clk); + } +}; + +template using lookup_u8_1_relation = GenericLookupRelation; +template using lookup_u8_1 = GenericLookup; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp index 8019768c54c..0a45bb920d5 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_alu.hpp @@ -12,7 +12,7 @@ namespace bb { class perm_main_alu_permutation_settings { public: // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 10; + constexpr static size_t COLUMNS_PER_SET = 12; /** * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the @@ -59,6 +59,8 @@ class perm_main_alu_permutation_settings { in.avm_main_sel_op_mul, in.avm_main_sel_op_eq, in.avm_main_sel_op_not, + in.avm_main_sel_op_lt, + in.avm_main_sel_op_lte, in.avm_main_r_in_tag, in.avm_alu_clk, in.avm_alu_ia, @@ -69,6 +71,8 @@ class perm_main_alu_permutation_settings { in.avm_alu_op_mul, in.avm_alu_op_eq, in.avm_alu_op_not, + in.avm_alu_op_lt, + in.avm_alu_op_lte, in.avm_alu_in_tag); } @@ -105,6 +109,8 @@ class perm_main_alu_permutation_settings { in.avm_main_sel_op_mul, in.avm_main_sel_op_eq, in.avm_main_sel_op_not, + in.avm_main_sel_op_lt, + in.avm_main_sel_op_lte, in.avm_main_r_in_tag, in.avm_alu_clk, in.avm_alu_ia, @@ -115,6 +121,8 @@ class perm_main_alu_permutation_settings { in.avm_alu_op_mul, in.avm_alu_op_eq, in.avm_alu_op_not, + in.avm_alu_op_lt, + in.avm_alu_op_lte, in.avm_alu_in_tag); } }; diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp index 842f5812b4f..0e3533051d1 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_bin.hpp @@ -12,7 +12,7 @@ namespace bb { class perm_main_bin_permutation_settings { public: // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 5; + constexpr static size_t COLUMNS_PER_SET = 6; /** * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the @@ -50,11 +50,13 @@ class perm_main_bin_permutation_settings { in.avm_main_bin_sel, in.avm_main_bin_sel, in.avm_binary_start, + in.avm_main_clk, in.avm_main_ia, in.avm_main_ib, in.avm_main_ic, in.avm_main_bin_op_id, in.avm_main_r_in_tag, + in.avm_binary_clk, in.avm_binary_acc_ia, in.avm_binary_acc_ib, in.avm_binary_acc_ic, @@ -86,11 +88,13 @@ class perm_main_bin_permutation_settings { in.avm_main_bin_sel, in.avm_main_bin_sel, in.avm_binary_start, + in.avm_main_clk, in.avm_main_ia, in.avm_main_ib, in.avm_main_ic, in.avm_main_bin_op_id, in.avm_main_r_in_tag, + in.avm_binary_clk, in.avm_binary_acc_ia, in.avm_binary_acc_ib, in.avm_binary_acc_ic, diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_cmp.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_cmp.hpp new file mode 100644 index 00000000000..362f4321566 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/avm/perm_main_cmp.hpp @@ -0,0 +1,102 @@ + + +#pragma once + +#include "barretenberg/relations/generic_permutation/generic_permutation_relation.hpp" + +#include +#include + +namespace bb { + +class perm_main_cmp_permutation_settings { + public: + // This constant defines how many columns are bundled together to form each set. + constexpr static size_t COLUMNS_PER_SET = 4; + + /** + * @brief If this method returns true on a row of values, then the inverse polynomial at this index. Otherwise the + * value needs to be set to zero. + * + * @details If this is true then permutation takes place in this row + */ + + template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) + { + return (in.avm_main_cmp_sel == 1 || in.avm_alu_cmp_sel == 1); + } + + /** + * @brief Get all the entities for the permutation when we don't need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_const_entities(const AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_cmp, + in.avm_main_cmp_sel, + in.avm_main_cmp_sel, + in.avm_alu_cmp_sel, + in.avm_main_clk, + in.avm_main_ia, + in.avm_main_ib, + in.avm_main_ic, + in.avm_alu_clk, + in.avm_alu_ia, + in.avm_alu_ib, + in.avm_alu_ic); + } + + /** + * @brief Get all the entities for the permutation when need to update them + * + * @details The entities are returned as a tuple of references in the following order: + * - The entity/polynomial used to store the product of the inverse values + * - The entity/polynomial that switches on the subrelation of the permutation relation that ensures correctness of + * the inverse polynomial + * - The entity/polynomial that enables adding a tuple-generated value from the first set to the logderivative sum + * subrelation + * - The entity/polynomial that enables adding a tuple-generated value from the second set to the logderivative sum + * subrelation + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the first set (N.B. ORDER IS IMPORTANT!) + * - A sequence of COLUMNS_PER_SET entities/polynomials that represent the second set (N.B. ORDER IS IMPORTANT!) + * + * @return All the entities needed for the permutation + */ + + template static inline auto get_nonconst_entities(AllEntities& in) + { + + return std::forward_as_tuple(in.perm_main_cmp, + in.avm_main_cmp_sel, + in.avm_main_cmp_sel, + in.avm_alu_cmp_sel, + in.avm_main_clk, + in.avm_main_ia, + in.avm_main_ib, + in.avm_main_ic, + in.avm_alu_clk, + in.avm_alu_ia, + in.avm_alu_ib, + in.avm_alu_ic); + } +}; + +template +using perm_main_cmp_relation = GenericPermutationRelation; +template using perm_main_cmp = GenericPermutation; + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/relations/generic_lookup/generic_lookup_relation.hpp b/barretenberg/cpp/src/barretenberg/relations/generic_lookup/generic_lookup_relation.hpp index 18b9c872101..2f388d0ddbd 100644 --- a/barretenberg/cpp/src/barretenberg/relations/generic_lookup/generic_lookup_relation.hpp +++ b/barretenberg/cpp/src/barretenberg/relations/generic_lookup/generic_lookup_relation.hpp @@ -478,4 +478,4 @@ using GenericLookupRelation = Relation>; template using GenericLookup = GenericLookupRelationImpl; -} // namespace bb \ No newline at end of file +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.cpp index 42668cabb8d..8414c411c3c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.cpp @@ -1,4 +1,12 @@ #include "avm_alu_trace.hpp" +#include "barretenberg/common/serialize.hpp" +#include "barretenberg/numeric/uint128/uint128.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" +#include "barretenberg/relations/generated/avm/avm_alu.hpp" +#include +#include +#include +#include namespace bb::avm_trace { @@ -431,4 +439,229 @@ FF AvmAluTraceBuilder::op_eq(FF const& a, FF const& b, AvmMemoryTag in_tag, uint return res; } +/** + * @brief This is a helper function that decomposes the input into the various registers of the ALU. + * This additionally increments the counts for the corresponding range lookups entries. + * @return A triplet of + */ +template +std::tuple> AvmAluTraceBuilder::to_alu_slice_registers(T a) +{ + auto alu_u8_r0 = static_cast(a); + a >>= 8; + auto alu_u8_r1 = static_cast(a); + a >>= 8; + std::vector alu_u16_reg{}; + for (size_t i = 0; i < 15; i++) { + auto alu_u16 = static_cast(a); + u16_range_chk_counters[i][alu_u16]++; + alu_u16_reg.push_back(alu_u16); + a >>= 16; + } + u8_range_chk_counters[0][alu_u8_r0]++; + u8_range_chk_counters[1][alu_u8_r1]++; + return std::make_tuple(alu_u8_r0, alu_u8_r1, alu_u16_reg); +} + +/** + * @brief This is a helper function that is used to generate the range check entries for the comparison operation + * (LT/LTE opcodes). This additionally increments the counts for the corresponding range lookups entries. + * @param row The initial row where the comparison operation was performed + * @param hi_lo_limbs The vector of 128-bit limbs hi and lo pairs of limbs that will be range checked. + * @return A vector of AluTraceEntry rows for the range checks for the comparison operation. + */ +std::vector AvmAluTraceBuilder::cmp_range_check_helper( + AvmAluTraceBuilder::AluTraceEntry row, std::vector hi_lo_limbs) +{ + // Assume each limb is 128 bits and since we can perform 256-bit range check per rows + // we need to have (limbs.size() / 2) range checks rows + size_t num_rows = hi_lo_limbs.size() / 2; + // The first row is the original comparison instruction (LT/LTE) + std::vector rows{ std::move(row) }; + rows.resize(num_rows, {}); + + // We need to ensure that the number of rows is even + ASSERT(hi_lo_limbs.size() % 2 == 0); + // Now for each row, we need to unpack a pair from the hi_lo_limb array into the ALUs 8-bit and 16-bit registers + // The first row unpacks a_lo and a_hi, the second row unpacks b_lo and b_hi, and so on. + for (size_t j = 0; j < num_rows; j++) { + auto& r = rows.at(j); + uint256_t lo_limb = hi_lo_limbs.at(2 * j); + uint256_t hi_limb = hi_lo_limbs.at(2 * j + 1); + uint256_t limb = lo_limb + (hi_limb << 128); + // Unpack lo limb and handle in the 8-bit registers + auto [alu_u8_r0, alu_u8_r1, alu_u16_reg] = AvmAluTraceBuilder::to_alu_slice_registers(limb); + r.alu_u8_r0 = alu_u8_r0; + r.alu_u8_r1 = alu_u8_r1; + std::copy(alu_u16_reg.begin(), alu_u16_reg.end(), r.alu_u16_reg.begin()); + + r.cmp_rng_ctr = j > 0 ? static_cast(num_rows - j) : 0; + r.rng_chk_sel = j > 0; + r.alu_op_eq_diff_inv = j > 0 ? FF(num_rows - j).invert() : 0; + + std::vector limb_arr = { hi_lo_limbs.begin() + static_cast(2 * j), hi_lo_limbs.end() }; + // Resizing here is probably suboptimal for performance, we can probably handle the shorter vectors and + // pad with zero during the finalise + limb_arr.resize(10, FF::zero()); + r.hi_lo_limbs = limb_arr; + } + return rows; +} + +/** + * Helper function to decompose a uint256_t into upper 128-bit and lower 128-bit tuple. + * The outputs are cast to uint256_t so they are easier to use in checks + */ + +std::tuple decompose(uint256_t const& a) +{ + uint256_t upper_bitmask = (uint256_t(1) << uint256_t(128)) - 1; + uint256_t a_lo = a & upper_bitmask; + uint256_t a_hi = a >> 128; + return std::make_tuple(a_lo, a_hi); +} + +// This creates a witness exclusively for the relation a > b +// This is useful when we want to enforce in certain checks that a must be greater than b +std::tuple gt_witness(uint256_t const& a, uint256_t const& b) +{ + uint256_t two_pow_128 = uint256_t(1) << uint256_t(128); + auto [a_lo, a_hi] = decompose(a); + auto [b_lo, b_hi] = decompose(b); + bool borrow = a_lo <= b_lo; + auto borrow_u256 = uint256_t(static_cast(borrow)); + uint256_t r_lo = a_lo - b_lo - 1 + borrow_u256 * two_pow_128; + uint256_t r_hi = a_hi - b_hi - borrow_u256; + return std::make_tuple(r_lo, r_hi, borrow); +} + +// This check is more flexible than gt_witness and is used when we want to generate the witness +// to the relation (a - b - 1) * q + (b - a) * (1 - q) +// where q = 1 if a > b and q = 0 if a <= b +std::tuple gt_or_lte_witness(uint256_t const& a, uint256_t const& b) +{ + uint256_t two_pow_128 = uint256_t(1) << uint256_t(128); + auto [a_lo, a_hi] = decompose(a); + auto [b_lo, b_hi] = decompose(b); + bool isGT = a > b; + if (isGT) { + return gt_witness(a, b); + } + bool borrow = b_lo < a_lo; + auto borrow_u256 = uint256_t(static_cast(borrow)); + uint256_t r_lo = b_lo - a_lo + borrow_u256 * two_pow_128; + uint256_t r_hi = b_hi - a_hi - borrow_u256; + return std::make_tuple(r_lo, r_hi, borrow); +} + +/** + * @brief Build Alu trace and compute the result of a LT operation on two operands. + * The tag type in_tag does not change the result of the operation. But we + * do need it for a relation check in the alu. + * + * @param a Left operand of the LT + * @param b Right operand of the LT + * @param clk Clock referring to the operation in the main trace. + * @param in_tag Instruction tag defining the number of bits for the LT. + * + * @return FF The boolean result of LT casted to a finite field element + */ + +FF AvmAluTraceBuilder::op_lt(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t const clk) +{ + bool c = uint256_t(a) < uint256_t(b); + + // Note: This is counter-intuitive, to show that a < b we actually show that b > a + // The subtlety is here that the circuit is designed as a GT(x,y) circuit, therefore we swap the inputs a & b + // Get the decomposition of b + auto [a_lo, a_hi] = decompose(b); + // Get the decomposition of a + auto [b_lo, b_hi] = decompose(a); + // Get the decomposition of p - a and p - b **remember that we swap the inputs** + // Note that a valid witness here is ONLY that p > a and p > b + auto [p_sub_a_lo, p_sub_a_hi, p_a_borrow] = gt_witness(FF::modulus, b); + auto [p_sub_b_lo, p_sub_b_hi, p_b_borrow] = gt_witness(FF::modulus, a); + // We either generate a witness that a <= b or a > b (its validity depends on the value of c) + auto [r_lo, r_hi, borrow] = gt_or_lte_witness(b, a); + + // The vector of limbs that are used in the GT circuit and that are range checked + std::vector hi_lo_limbs = { a_lo, a_hi, b_lo, b_hi, p_sub_a_lo, + p_sub_a_hi, p_sub_b_lo, p_sub_b_hi, r_lo, r_hi }; + + AvmAluTraceBuilder::AluTraceEntry row{ + .alu_clk = clk, + .alu_op_lt = true, + .alu_ff_tag = in_tag == AvmMemoryTag::FF, + .alu_u8_tag = in_tag == AvmMemoryTag::U8, + .alu_u16_tag = in_tag == AvmMemoryTag::U16, + .alu_u32_tag = in_tag == AvmMemoryTag::U32, + .alu_u64_tag = in_tag == AvmMemoryTag::U64, + .alu_u128_tag = in_tag == AvmMemoryTag::U128, + .alu_ia = a, + .alu_ib = b, + .alu_ic = FF(static_cast(c)), + .borrow = borrow, + .p_a_borrow = p_a_borrow, + .p_b_borrow = p_b_borrow, + }; + // Update the row and add new rows with the correct hi_lo limbs + std::vector rows = cmp_range_check_helper(row, hi_lo_limbs); + // Append the rows to the alu_trace + alu_trace.insert(alu_trace.end(), rows.begin(), rows.end()); + return { static_cast(c) }; +} + +/** + * @brief Build Alu trace and compute the result of a LTE operation on two operands. + * The tag type in_tag does not change the result of the operation. But we + * do need it for a relation check in the alu. + * + * @param a Left operand of the LTE + * @param b Right operand of the LTE + * @param clk Clock referring to the operation in the main trace. + * @param in_tag Instruction tag defining the number of bits for the LT. + * + * @return FF The boolean result of LTE casted to a finite field element + */ +FF AvmAluTraceBuilder::op_lte(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t const clk) +{ + bool c = uint256_t(a) <= uint256_t(b); + + // Get the decomposition of a + auto [a_lo, a_hi] = decompose(a); + // Get the decomposition of b + auto [b_lo, b_hi] = decompose(b); + // Get the decomposition of p - a and p - b + // Note that a valid witness here is that p > a and p > b + auto [p_sub_a_lo, p_sub_a_hi, p_a_borrow] = gt_witness(FF::modulus, a); + auto [p_sub_b_lo, p_sub_b_hi, p_b_borrow] = gt_witness(FF::modulus, b); + // We either generate a witness that a <= b or a > b (its validity depends on the value of c) + auto [r_lo, r_hi, borrow] = gt_or_lte_witness(a, b); + + // The vector of limbs that are used in the GT circuit and that are range checked + std::vector hi_lo_limbs = { a_lo, a_hi, b_lo, b_hi, p_sub_a_lo, + p_sub_a_hi, p_sub_b_lo, p_sub_b_hi, r_lo, r_hi }; + + // Construct the row that performs the lte check + AvmAluTraceBuilder::AluTraceEntry row{ + .alu_clk = clk, + .alu_op_lte = true, + .alu_ff_tag = in_tag == AvmMemoryTag::FF, + .alu_u8_tag = in_tag == AvmMemoryTag::U8, + .alu_u16_tag = in_tag == AvmMemoryTag::U16, + .alu_u32_tag = in_tag == AvmMemoryTag::U32, + .alu_u64_tag = in_tag == AvmMemoryTag::U64, + .alu_u128_tag = in_tag == AvmMemoryTag::U128, + .alu_ia = a, + .alu_ib = b, + .alu_ic = FF(static_cast(c)), + .borrow = borrow, + .p_a_borrow = p_a_borrow, + .p_b_borrow = p_b_borrow, + }; + // Update the row and add new rows with the correct hi_lo limbs + std::vector rows = cmp_range_check_helper(row, hi_lo_limbs); + alu_trace.insert(alu_trace.end(), rows.begin(), rows.end()); + return { static_cast(c) }; +} } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.hpp index 736a1896c1d..7d15c2f70df 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_alu_trace.hpp @@ -1,6 +1,10 @@ #pragma once #include "avm_common.hpp" +#include "barretenberg/numeric/uint128/uint128.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" +#include +#include namespace bb::avm_trace { @@ -15,6 +19,8 @@ class AvmAluTraceBuilder { bool alu_op_mul = false; bool alu_op_not = false; bool alu_op_eq = false; + bool alu_op_lt = false; + bool alu_op_lte = false; bool alu_ff_tag = false; bool alu_u8_tag = false; @@ -37,8 +43,20 @@ class AvmAluTraceBuilder { uint64_t alu_u64_r0{}; FF alu_op_eq_diff_inv{}; + + // Comparison Operation + bool borrow = false; + + std::vector hi_lo_limbs{}; + bool p_a_borrow = false; + bool p_b_borrow = false; + uint8_t cmp_rng_ctr = 0; + bool rng_chk_sel = false; }; + std::array, 2> u8_range_chk_counters; + std::array, 15> u16_range_chk_counters; + AvmAluTraceBuilder(); void reset(); std::vector finalize(); @@ -48,8 +66,13 @@ class AvmAluTraceBuilder { FF op_mul(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); FF op_not(FF const& a, AvmMemoryTag in_tag, uint32_t clk); FF op_eq(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); + FF op_lt(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); + FF op_lte(FF const& a, FF const& b, AvmMemoryTag in_tag, uint32_t clk); private: std::vector alu_trace; + template std::tuple> to_alu_slice_registers(T a); + std::vector cmp_range_check_helper(AluTraceEntry row, std::vector hi_lo_limbs); + void count_range_checks(AluTraceEntry const& entry); }; } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp index 549f68dd408..03d4091ddef 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_deserialization.cpp @@ -28,6 +28,8 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = { OpCode::DIV, three_operand_format }, // Compute - Comparators { OpCode::EQ, three_operand_format }, + { OpCode::LT, three_operand_format }, + { OpCode::LTE, three_operand_format }, // Compute - Bitwise { OpCode::NOT, { OperandType::INDIRECT, OperandType::TAG, OperandType::UINT32, OperandType::UINT32 } }, { OpCode::AND, three_operand_format }, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp index 10e2ce6b15b..753ce9eca13 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_execution.cpp @@ -136,6 +136,20 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(4)), std::get(inst.operands.at(1))); break; + case OpCode::LT: + trace_builder.op_lt(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; + case OpCode::LTE: + trace_builder.op_lte(std::get(inst.operands.at(0)), + std::get(inst.operands.at(2)), + std::get(inst.operands.at(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(1))); + break; // Compute - Bitwise case OpCode::NOT: trace_builder.op_not(std::get(inst.operands.at(0)), 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 a66fcb4edf9..4a31987c2b1 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.cpp @@ -629,6 +629,108 @@ void AvmTraceBuilder::op_xor( }); } +void AvmTraceBuilder::op_lt( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) +{ + auto clk = static_cast(main_trace.size()); + + auto const res = resolve_ind_three(clk, indirect, a_offset, b_offset, dst_offset); + bool tag_match = res.tag_match; + + // Reading from memory and loading into ia resp. ib. + auto read_a = mem_trace_builder.read_and_load_from_memory( + clk, IntermRegister::IA, res.direct_a_offset, in_tag, AvmMemoryTag::U8); + auto read_b = mem_trace_builder.read_and_load_from_memory( + clk, IntermRegister::IB, res.direct_b_offset, in_tag, AvmMemoryTag::U8); + tag_match = read_a.tag_match && read_b.tag_match; + + FF a = tag_match ? read_a.val : FF(0); + FF b = tag_match ? read_b.val : FF(0); + + FF c = tag_match ? alu_trace_builder.op_lt(a, b, in_tag, clk) : FF(0); + + range_checked_required = true; + // Write into memory value c from intermediate register ic. + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, AvmMemoryTag::U8); + + main_trace.push_back(Row{ + .avm_main_clk = clk, + .avm_main_ia = a, + .avm_main_ib = b, + .avm_main_ic = c, + .avm_main_ind_a = res.indirect_flag_a ? FF(a_offset) : FF(0), + .avm_main_ind_b = res.indirect_flag_b ? FF(b_offset) : FF(0), + .avm_main_ind_c = res.indirect_flag_c ? FF(dst_offset) : FF(0), + .avm_main_ind_op_a = FF(static_cast(res.indirect_flag_a)), + .avm_main_ind_op_b = FF(static_cast(res.indirect_flag_b)), + .avm_main_ind_op_c = FF(static_cast(res.indirect_flag_c)), + .avm_main_internal_return_ptr = FF(internal_return_ptr), + .avm_main_mem_idx_a = FF(res.direct_a_offset), + .avm_main_mem_idx_b = FF(res.direct_b_offset), + .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_op_a = FF(1), + .avm_main_mem_op_b = FF(1), + .avm_main_mem_op_c = FF(1), + .avm_main_pc = FF(pc++), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_rwc = FF(1), + .avm_main_sel_op_lt = FF(1), + .avm_main_tag_err = FF(static_cast(!tag_match)), + .avm_main_w_in_tag = FF(static_cast(AvmMemoryTag::U8)), + }); +} + +void AvmTraceBuilder::op_lte( + uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag) +{ + auto clk = static_cast(main_trace.size()); + + auto const res = resolve_ind_three(clk, indirect, a_offset, b_offset, dst_offset); + bool tag_match = res.tag_match; + + // Reading from memory and loading into ia resp. ib. + auto read_a = mem_trace_builder.read_and_load_from_memory( + clk, IntermRegister::IA, res.direct_a_offset, in_tag, AvmMemoryTag::U8); + auto read_b = mem_trace_builder.read_and_load_from_memory( + clk, IntermRegister::IB, res.direct_b_offset, in_tag, AvmMemoryTag::U8); + tag_match = read_a.tag_match && read_b.tag_match; + + FF a = tag_match ? read_a.val : FF(0); + FF b = tag_match ? read_b.val : FF(0); + + FF c = tag_match ? alu_trace_builder.op_lte(a, b, in_tag, clk) : FF(0); + + range_checked_required = true; + // Write into memory value c from intermediate register ic. + mem_trace_builder.write_into_memory(clk, IntermRegister::IC, res.direct_dst_offset, c, in_tag, AvmMemoryTag::U8); + + main_trace.push_back(Row{ + .avm_main_clk = clk, + .avm_main_ia = a, + .avm_main_ib = b, + .avm_main_ic = c, + .avm_main_ind_a = res.indirect_flag_a ? FF(a_offset) : FF(0), + .avm_main_ind_b = res.indirect_flag_b ? FF(b_offset) : FF(0), + .avm_main_ind_c = res.indirect_flag_c ? FF(dst_offset) : FF(0), + .avm_main_ind_op_a = FF(static_cast(res.indirect_flag_a)), + .avm_main_ind_op_b = FF(static_cast(res.indirect_flag_b)), + .avm_main_ind_op_c = FF(static_cast(res.indirect_flag_c)), + .avm_main_internal_return_ptr = FF(internal_return_ptr), + .avm_main_mem_idx_a = FF(res.direct_a_offset), + .avm_main_mem_idx_b = FF(res.direct_b_offset), + .avm_main_mem_idx_c = FF(res.direct_dst_offset), + .avm_main_mem_op_a = FF(1), + .avm_main_mem_op_b = FF(1), + .avm_main_mem_op_c = FF(1), + .avm_main_pc = FF(pc++), + .avm_main_r_in_tag = FF(static_cast(in_tag)), + .avm_main_rwc = FF(1), + .avm_main_sel_op_lte = FF(1), + .avm_main_tag_err = FF(static_cast(!tag_match)), + .avm_main_w_in_tag = FF(static_cast(AvmMemoryTag::U8)), + }); +} + // TODO: Ensure that the bytecode validation and/or deserialization is // enforcing that val complies to the tag. /** @@ -1136,7 +1238,7 @@ std::vector AvmTraceBuilder::finalize() // 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) size_t const lookup_table_size = bin_trace_size > 0 ? 3 * (1 << 16) : 0; - size_t const range_check_size = range_checked_required ? UINT16_MAX : 0; + size_t const range_check_size = range_checked_required ? UINT16_MAX + 1 : 0; std::vector trace_sizes = { mem_trace_size, main_trace_size, alu_trace_size, lookup_table_size, range_check_size }; @@ -1145,9 +1247,10 @@ std::vector AvmTraceBuilder::finalize() // We only need to pad with zeroes to the size to the largest trace here, pow_2 padding is handled in the // subgroup_size check in bb // Resize the main_trace to accomodate a potential lookup, filling with default empty rows. + main_trace_size = *trace_size; main_trace.resize(*trace_size, {}); - main_trace.at(main_trace_size - 1).avm_main_last = FF(1); + main_trace.at(*trace_size - 1).avm_main_last = FF(1); // Memory trace inclusion for (size_t i = 0; i < mem_trace_size; i++) { @@ -1215,6 +1318,10 @@ std::vector AvmTraceBuilder::finalize() dest.avm_alu_op_mul = FF(static_cast(src.alu_op_mul)); dest.avm_alu_op_not = FF(static_cast(src.alu_op_not)); dest.avm_alu_op_eq = FF(static_cast(src.alu_op_eq)); + dest.avm_alu_op_lt = FF(static_cast(src.alu_op_lt)); + dest.avm_alu_op_lte = FF(static_cast(src.alu_op_lte)); + dest.avm_alu_cmp_sel = FF(static_cast(src.alu_op_lt) + static_cast(src.alu_op_lte)); + dest.avm_alu_rng_chk_sel = FF(static_cast(src.rng_chk_sel)); dest.avm_alu_ff_tag = FF(static_cast(src.alu_ff_tag)); dest.avm_alu_u8_tag = FF(static_cast(src.alu_u8_tag)); @@ -1258,25 +1365,66 @@ std::vector AvmTraceBuilder::finalize() // Not all rows in ALU are enabled with a selector. For instance, // multiplication over u128 is taking two lines. if (dest.avm_alu_op_add == FF(1) || dest.avm_alu_op_sub == FF(1) || dest.avm_alu_op_mul == FF(1) || - dest.avm_alu_op_eq == FF(1) || dest.avm_alu_op_not == FF(1)) { + dest.avm_alu_op_eq == FF(1) || dest.avm_alu_op_not == FF(1) || dest.avm_alu_op_lt == FF(1) || + dest.avm_alu_op_lte == FF(1)) { dest.avm_alu_alu_sel = FF(1); } + if (dest.avm_alu_cmp_sel == FF(1) || dest.avm_alu_rng_chk_sel == FF(1)) { + dest.avm_alu_a_lo = FF(src.hi_lo_limbs.at(0)); + dest.avm_alu_a_hi = FF(src.hi_lo_limbs.at(1)); + dest.avm_alu_b_lo = FF(src.hi_lo_limbs.at(2)); + dest.avm_alu_b_hi = FF(src.hi_lo_limbs.at(3)); + dest.avm_alu_p_sub_a_lo = FF(src.hi_lo_limbs.at(4)); + dest.avm_alu_p_sub_a_hi = FF(src.hi_lo_limbs.at(5)); + dest.avm_alu_p_sub_b_lo = FF(src.hi_lo_limbs.at(6)); + dest.avm_alu_p_sub_b_hi = FF(src.hi_lo_limbs.at(7)); + dest.avm_alu_res_lo = FF(src.hi_lo_limbs.at(8)); + dest.avm_alu_res_hi = FF(src.hi_lo_limbs.at(9)); + dest.avm_alu_p_a_borrow = FF(static_cast(src.p_a_borrow)); + dest.avm_alu_p_b_borrow = FF(static_cast(src.p_b_borrow)); + dest.avm_alu_borrow = FF(static_cast(src.borrow)); + dest.avm_alu_rng_chk_sel = FF(static_cast(src.rng_chk_sel)); + dest.avm_alu_cmp_rng_ctr = FF(static_cast(src.cmp_rng_ctr)); + dest.avm_alu_rng_chk_lookup_selector = FF(1); + } } for (size_t i = 0; i < main_trace_size; i++) { auto& r = main_trace.at(i); if ((r.avm_main_sel_op_add == FF(1) || r.avm_main_sel_op_sub == FF(1) || r.avm_main_sel_op_mul == FF(1) || - r.avm_main_sel_op_eq == FF(1) || r.avm_main_sel_op_not == FF(1)) && + r.avm_main_sel_op_eq == FF(1) || r.avm_main_sel_op_not == FF(1) || r.avm_main_sel_op_lt || + r.avm_main_sel_op_lte) && r.avm_main_tag_err == FF(0)) { r.avm_main_alu_sel = FF(1); } if (i <= UINT8_MAX) { + r.lookup_u8_0_counts = alu_trace_builder.u8_range_chk_counters[0][static_cast(i)]; + r.lookup_u8_1_counts = alu_trace_builder.u8_range_chk_counters[1][static_cast(i)]; r.avm_main_sel_rng_8 = FF(1); } if (i <= UINT16_MAX) { + // We add to the clk here in case our trace is smaller than our range checks + // There might be a cleaner way to do this in the future as this only applies + // when our trace (excluding range checks) is < 2**16 + r.lookup_u16_0_counts = alu_trace_builder.u16_range_chk_counters[0][static_cast(i)]; + r.lookup_u16_1_counts = alu_trace_builder.u16_range_chk_counters[1][static_cast(i)]; + r.lookup_u16_2_counts = alu_trace_builder.u16_range_chk_counters[2][static_cast(i)]; + r.lookup_u16_3_counts = alu_trace_builder.u16_range_chk_counters[3][static_cast(i)]; + r.lookup_u16_4_counts = alu_trace_builder.u16_range_chk_counters[4][static_cast(i)]; + r.lookup_u16_5_counts = alu_trace_builder.u16_range_chk_counters[5][static_cast(i)]; + r.lookup_u16_6_counts = alu_trace_builder.u16_range_chk_counters[6][static_cast(i)]; + r.lookup_u16_7_counts = alu_trace_builder.u16_range_chk_counters[7][static_cast(i)]; + r.lookup_u16_8_counts = alu_trace_builder.u16_range_chk_counters[8][static_cast(i)]; + r.lookup_u16_9_counts = alu_trace_builder.u16_range_chk_counters[9][static_cast(i)]; + r.lookup_u16_10_counts = alu_trace_builder.u16_range_chk_counters[10][static_cast(i)]; + r.lookup_u16_11_counts = alu_trace_builder.u16_range_chk_counters[11][static_cast(i)]; + 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.avm_main_clk = FF(static_cast(i)); r.avm_main_sel_rng_16 = FF(1); } } @@ -1284,7 +1432,8 @@ std::vector AvmTraceBuilder::finalize() // Deriving redundant selectors/tags for the main trace. for (Row& r : main_trace) { if ((r.avm_main_sel_op_add == FF(1) || r.avm_main_sel_op_sub == FF(1) || r.avm_main_sel_op_mul == FF(1) || - r.avm_main_sel_op_eq == FF(1) || r.avm_main_sel_op_not == FF(1)) && + r.avm_main_sel_op_eq == FF(1) || r.avm_main_sel_op_not == FF(1) || r.avm_main_sel_op_lt || + r.avm_main_sel_op_lte) && r.avm_main_tag_err == FF(0)) { r.avm_main_alu_sel = FF(1); } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp index a68439da21a..4d65afdc45c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm_trace/avm_trace.hpp @@ -56,6 +56,12 @@ class AvmTraceBuilder { // Bitwise xor with direct or indirect memory access. void op_xor(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Less Than with direct or indirect memory access. + void op_lt(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + + // Less Than or Equal to with direct or indirect memory access. + void op_lte(uint8_t indirect, uint32_t a_offset, uint32_t b_offset, uint32_t dst_offset, AvmMemoryTag in_tag); + // Set a constant from bytecode with direct or indirect memory access. void op_set(uint8_t indirect, uint128_t val, uint32_t dst_offset, AvmMemoryTag in_tag); 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 2498a690654..42e931cbdf3 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,23 @@ #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_u16_0.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_1.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_10.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_11.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_12.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_13.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_14.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_2.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_3.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_4.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_5.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_6.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_7.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_8.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_9.hpp" +#include "barretenberg/relations/generated/avm/lookup_u8_0.hpp" +#include "barretenberg/relations/generated/avm/lookup_u8_1.hpp" #include "barretenberg/relations/generated/avm/perm_main_alu.hpp" #include "barretenberg/relations/generated/avm/perm_main_bin.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_a.hpp" @@ -34,9 +51,16 @@ namespace bb { template struct AvmFullRow { FF avm_main_clk{}; FF avm_main_first{}; + FF avm_alu_a_hi{}; + FF avm_alu_a_lo{}; FF avm_alu_alu_sel{}; + FF avm_alu_b_hi{}; + FF avm_alu_b_lo{}; + FF avm_alu_borrow{}; FF avm_alu_cf{}; FF avm_alu_clk{}; + FF avm_alu_cmp_rng_ctr{}; + FF avm_alu_cmp_sel{}; FF avm_alu_ff_tag{}; FF avm_alu_ia{}; FF avm_alu_ib{}; @@ -46,9 +70,21 @@ template struct AvmFullRow { FF avm_alu_op_div{}; FF avm_alu_op_eq{}; FF avm_alu_op_eq_diff_inv{}; + FF avm_alu_op_lt{}; + FF avm_alu_op_lte{}; FF avm_alu_op_mul{}; FF avm_alu_op_not{}; FF avm_alu_op_sub{}; + FF avm_alu_p_a_borrow{}; + FF avm_alu_p_b_borrow{}; + FF avm_alu_p_sub_a_hi{}; + FF avm_alu_p_sub_a_lo{}; + FF avm_alu_p_sub_b_hi{}; + FF avm_alu_p_sub_b_lo{}; + FF avm_alu_res_hi{}; + FF avm_alu_res_lo{}; + FF avm_alu_rng_chk_lookup_selector{}; + FF avm_alu_rng_chk_sel{}; FF avm_alu_u128_tag{}; FF avm_alu_u16_r0{}; FF avm_alu_u16_r1{}; @@ -128,6 +164,8 @@ template struct AvmFullRow { FF avm_main_sel_op_and{}; FF avm_main_sel_op_div{}; FF avm_main_sel_op_eq{}; + FF avm_main_sel_op_lt{}; + FF avm_main_sel_op_lte{}; FF avm_main_sel_op_mul{}; FF avm_main_sel_op_not{}; FF avm_main_sel_op_or{}; @@ -168,10 +206,54 @@ template struct AvmFullRow { FF lookup_byte_operations{}; FF incl_main_tag_err{}; FF incl_mem_tag_err{}; + FF lookup_u8_0{}; + FF lookup_u8_1{}; + FF lookup_u16_0{}; + FF lookup_u16_1{}; + FF lookup_u16_2{}; + FF lookup_u16_3{}; + FF lookup_u16_4{}; + FF lookup_u16_5{}; + FF lookup_u16_6{}; + FF lookup_u16_7{}; + FF lookup_u16_8{}; + FF lookup_u16_9{}; + FF lookup_u16_10{}; + FF lookup_u16_11{}; + FF lookup_u16_12{}; + FF lookup_u16_13{}; + FF lookup_u16_14{}; FF lookup_byte_lengths_counts{}; FF lookup_byte_operations_counts{}; FF incl_main_tag_err_counts{}; FF incl_mem_tag_err_counts{}; + FF lookup_u8_0_counts{}; + FF lookup_u8_1_counts{}; + FF lookup_u16_0_counts{}; + FF lookup_u16_1_counts{}; + FF lookup_u16_2_counts{}; + FF lookup_u16_3_counts{}; + FF lookup_u16_4_counts{}; + FF lookup_u16_5_counts{}; + FF lookup_u16_6_counts{}; + FF lookup_u16_7_counts{}; + FF lookup_u16_8_counts{}; + FF lookup_u16_9_counts{}; + FF lookup_u16_10_counts{}; + FF lookup_u16_11_counts{}; + FF lookup_u16_12_counts{}; + FF lookup_u16_13_counts{}; + FF lookup_u16_14_counts{}; + FF avm_alu_a_hi_shift{}; + FF avm_alu_a_lo_shift{}; + FF avm_alu_b_hi_shift{}; + FF avm_alu_b_lo_shift{}; + FF avm_alu_cmp_rng_ctr_shift{}; + FF avm_alu_p_sub_a_hi_shift{}; + FF avm_alu_p_sub_a_lo_shift{}; + FF avm_alu_p_sub_b_hi_shift{}; + FF avm_alu_p_sub_b_lo_shift{}; + FF avm_alu_rng_chk_sel_shift{}; FF avm_alu_u16_r0_shift{}; FF avm_alu_u16_r1_shift{}; FF avm_alu_u16_r2_shift{}; @@ -203,8 +285,8 @@ class AvmCircuitBuilder { using Polynomial = Flavor::Polynomial; using ProverPolynomials = Flavor::ProverPolynomials; - static constexpr size_t num_fixed_columns = 159; - static constexpr size_t num_polys = 140; + static constexpr size_t num_fixed_columns = 224; + static constexpr size_t num_polys = 195; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -222,9 +304,16 @@ class AvmCircuitBuilder { for (size_t i = 0; i < rows.size(); i++) { polys.avm_main_clk[i] = rows[i].avm_main_clk; polys.avm_main_first[i] = rows[i].avm_main_first; + polys.avm_alu_a_hi[i] = rows[i].avm_alu_a_hi; + polys.avm_alu_a_lo[i] = rows[i].avm_alu_a_lo; polys.avm_alu_alu_sel[i] = rows[i].avm_alu_alu_sel; + polys.avm_alu_b_hi[i] = rows[i].avm_alu_b_hi; + polys.avm_alu_b_lo[i] = rows[i].avm_alu_b_lo; + polys.avm_alu_borrow[i] = rows[i].avm_alu_borrow; polys.avm_alu_cf[i] = rows[i].avm_alu_cf; polys.avm_alu_clk[i] = rows[i].avm_alu_clk; + polys.avm_alu_cmp_rng_ctr[i] = rows[i].avm_alu_cmp_rng_ctr; + polys.avm_alu_cmp_sel[i] = rows[i].avm_alu_cmp_sel; polys.avm_alu_ff_tag[i] = rows[i].avm_alu_ff_tag; polys.avm_alu_ia[i] = rows[i].avm_alu_ia; polys.avm_alu_ib[i] = rows[i].avm_alu_ib; @@ -234,9 +323,21 @@ class AvmCircuitBuilder { polys.avm_alu_op_div[i] = rows[i].avm_alu_op_div; polys.avm_alu_op_eq[i] = rows[i].avm_alu_op_eq; polys.avm_alu_op_eq_diff_inv[i] = rows[i].avm_alu_op_eq_diff_inv; + polys.avm_alu_op_lt[i] = rows[i].avm_alu_op_lt; + polys.avm_alu_op_lte[i] = rows[i].avm_alu_op_lte; polys.avm_alu_op_mul[i] = rows[i].avm_alu_op_mul; polys.avm_alu_op_not[i] = rows[i].avm_alu_op_not; polys.avm_alu_op_sub[i] = rows[i].avm_alu_op_sub; + polys.avm_alu_p_a_borrow[i] = rows[i].avm_alu_p_a_borrow; + polys.avm_alu_p_b_borrow[i] = rows[i].avm_alu_p_b_borrow; + polys.avm_alu_p_sub_a_hi[i] = rows[i].avm_alu_p_sub_a_hi; + polys.avm_alu_p_sub_a_lo[i] = rows[i].avm_alu_p_sub_a_lo; + polys.avm_alu_p_sub_b_hi[i] = rows[i].avm_alu_p_sub_b_hi; + polys.avm_alu_p_sub_b_lo[i] = rows[i].avm_alu_p_sub_b_lo; + polys.avm_alu_res_hi[i] = rows[i].avm_alu_res_hi; + polys.avm_alu_res_lo[i] = rows[i].avm_alu_res_lo; + polys.avm_alu_rng_chk_lookup_selector[i] = rows[i].avm_alu_rng_chk_lookup_selector; + polys.avm_alu_rng_chk_sel[i] = rows[i].avm_alu_rng_chk_sel; polys.avm_alu_u128_tag[i] = rows[i].avm_alu_u128_tag; polys.avm_alu_u16_r0[i] = rows[i].avm_alu_u16_r0; polys.avm_alu_u16_r1[i] = rows[i].avm_alu_u16_r1; @@ -316,6 +417,8 @@ class AvmCircuitBuilder { polys.avm_main_sel_op_and[i] = rows[i].avm_main_sel_op_and; polys.avm_main_sel_op_div[i] = rows[i].avm_main_sel_op_div; polys.avm_main_sel_op_eq[i] = rows[i].avm_main_sel_op_eq; + polys.avm_main_sel_op_lt[i] = rows[i].avm_main_sel_op_lt; + polys.avm_main_sel_op_lte[i] = rows[i].avm_main_sel_op_lte; polys.avm_main_sel_op_mul[i] = rows[i].avm_main_sel_op_mul; polys.avm_main_sel_op_not[i] = rows[i].avm_main_sel_op_not; polys.avm_main_sel_op_or[i] = rows[i].avm_main_sel_op_or; @@ -344,14 +447,39 @@ class AvmCircuitBuilder { polys.avm_mem_tag_err[i] = rows[i].avm_mem_tag_err; 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.perm_main_alu[i] = rows[i].perm_main_alu; - 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_u8_0_counts[i] = rows[i].lookup_u8_0_counts; + polys.lookup_u8_1_counts[i] = rows[i].lookup_u8_1_counts; + polys.lookup_u16_0_counts[i] = rows[i].lookup_u16_0_counts; + polys.lookup_u16_1_counts[i] = rows[i].lookup_u16_1_counts; + polys.lookup_u16_2_counts[i] = rows[i].lookup_u16_2_counts; + polys.lookup_u16_3_counts[i] = rows[i].lookup_u16_3_counts; + polys.lookup_u16_4_counts[i] = rows[i].lookup_u16_4_counts; + polys.lookup_u16_5_counts[i] = rows[i].lookup_u16_5_counts; + polys.lookup_u16_6_counts[i] = rows[i].lookup_u16_6_counts; + polys.lookup_u16_7_counts[i] = rows[i].lookup_u16_7_counts; + polys.lookup_u16_8_counts[i] = rows[i].lookup_u16_8_counts; + polys.lookup_u16_9_counts[i] = rows[i].lookup_u16_9_counts; + polys.lookup_u16_10_counts[i] = rows[i].lookup_u16_10_counts; + polys.lookup_u16_11_counts[i] = rows[i].lookup_u16_11_counts; + polys.lookup_u16_12_counts[i] = rows[i].lookup_u16_12_counts; + polys.lookup_u16_13_counts[i] = rows[i].lookup_u16_13_counts; + polys.lookup_u16_14_counts[i] = rows[i].lookup_u16_14_counts; } + polys.avm_alu_a_hi_shift = Polynomial(polys.avm_alu_a_hi.shifted()); + polys.avm_alu_a_lo_shift = Polynomial(polys.avm_alu_a_lo.shifted()); + polys.avm_alu_b_hi_shift = Polynomial(polys.avm_alu_b_hi.shifted()); + polys.avm_alu_b_lo_shift = Polynomial(polys.avm_alu_b_lo.shifted()); + polys.avm_alu_cmp_rng_ctr_shift = Polynomial(polys.avm_alu_cmp_rng_ctr.shifted()); + polys.avm_alu_p_sub_a_hi_shift = Polynomial(polys.avm_alu_p_sub_a_hi.shifted()); + polys.avm_alu_p_sub_a_lo_shift = Polynomial(polys.avm_alu_p_sub_a_lo.shifted()); + polys.avm_alu_p_sub_b_hi_shift = Polynomial(polys.avm_alu_p_sub_b_hi.shifted()); + polys.avm_alu_p_sub_b_lo_shift = Polynomial(polys.avm_alu_p_sub_b_lo.shifted()); + polys.avm_alu_rng_chk_sel_shift = Polynomial(polys.avm_alu_rng_chk_sel.shifted()); polys.avm_alu_u16_r0_shift = Polynomial(polys.avm_alu_u16_r0.shifted()); polys.avm_alu_u16_r1_shift = Polynomial(polys.avm_alu_u16_r1.shifted()); polys.avm_alu_u16_r2_shift = Polynomial(polys.avm_alu_u16_r2.shifted()); @@ -496,6 +624,57 @@ class AvmCircuitBuilder { if (!evaluate_logderivative.template operator()>("INCL_MEM_TAG_ERR")) { return false; } + if (!evaluate_logderivative.template operator()>("LOOKUP_U8_0")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U8_1")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_0")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_1")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_2")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_3")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_4")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_5")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_6")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_7")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_8")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_9")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_10")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_11")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_12")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_13")) { + return false; + } + if (!evaluate_logderivative.template operator()>("LOOKUP_U16_14")) { + return false; + } return true; } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp index c2c664e1b4a..353ee278c6f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp @@ -21,6 +21,23 @@ #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_u16_0.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_1.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_10.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_11.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_12.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_13.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_14.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_2.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_3.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_4.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_5.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_6.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_7.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_8.hpp" +#include "barretenberg/relations/generated/avm/lookup_u16_9.hpp" +#include "barretenberg/relations/generated/avm/lookup_u8_0.hpp" +#include "barretenberg/relations/generated/avm/lookup_u8_1.hpp" #include "barretenberg/relations/generated/avm/perm_main_alu.hpp" #include "barretenberg/relations/generated/avm/perm_main_bin.hpp" #include "barretenberg/relations/generated/avm/perm_main_mem_a.hpp" @@ -50,11 +67,11 @@ class AvmFlavor { using RelationSeparator = FF; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; - static constexpr size_t NUM_WITNESS_ENTITIES = 138; + static constexpr size_t NUM_WITNESS_ENTITIES = 193; 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 = 159; + static constexpr size_t NUM_ALL_ENTITIES = 224; using GrandProductRelations = std::tuple, perm_main_bin_relation, @@ -64,10 +81,27 @@ class AvmFlavor { perm_main_mem_ind_a_relation, perm_main_mem_ind_b_relation, perm_main_mem_ind_c_relation, + lookup_byte_lengths_relation, + lookup_byte_operations_relation, incl_main_tag_err_relation, incl_mem_tag_err_relation, - lookup_byte_lengths_relation, - lookup_byte_operations_relation>; + lookup_u8_0_relation, + lookup_u8_1_relation, + lookup_u16_0_relation, + lookup_u16_1_relation, + lookup_u16_2_relation, + lookup_u16_3_relation, + lookup_u16_4_relation, + lookup_u16_5_relation, + lookup_u16_6_relation, + lookup_u16_7_relation, + lookup_u16_8_relation, + lookup_u16_9_relation, + lookup_u16_10_relation, + lookup_u16_11_relation, + lookup_u16_12_relation, + lookup_u16_13_relation, + lookup_u16_14_relation>; using Relations = std::tuple, Avm_vm::avm_binary, @@ -81,10 +115,27 @@ class AvmFlavor { perm_main_mem_ind_a_relation, perm_main_mem_ind_b_relation, perm_main_mem_ind_c_relation, + lookup_byte_lengths_relation, + lookup_byte_operations_relation, incl_main_tag_err_relation, incl_mem_tag_err_relation, - lookup_byte_lengths_relation, - lookup_byte_operations_relation>; + lookup_u8_0_relation, + lookup_u8_1_relation, + lookup_u16_0_relation, + lookup_u16_1_relation, + lookup_u16_2_relation, + lookup_u16_3_relation, + lookup_u16_4_relation, + lookup_u16_5_relation, + lookup_u16_6_relation, + lookup_u16_7_relation, + lookup_u16_8_relation, + lookup_u16_9_relation, + lookup_u16_10_relation, + lookup_u16_11_relation, + lookup_u16_12_relation, + lookup_u16_13_relation, + lookup_u16_14_relation>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -118,9 +169,16 @@ class AvmFlavor { template class WitnessEntities { public: DEFINE_FLAVOR_MEMBERS(DataType, + avm_alu_a_hi, + avm_alu_a_lo, avm_alu_alu_sel, + avm_alu_b_hi, + avm_alu_b_lo, + avm_alu_borrow, avm_alu_cf, avm_alu_clk, + avm_alu_cmp_rng_ctr, + avm_alu_cmp_sel, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -130,9 +188,21 @@ class AvmFlavor { avm_alu_op_div, avm_alu_op_eq, avm_alu_op_eq_diff_inv, + avm_alu_op_lt, + avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, avm_alu_op_sub, + avm_alu_p_a_borrow, + avm_alu_p_b_borrow, + avm_alu_p_sub_a_hi, + avm_alu_p_sub_a_lo, + avm_alu_p_sub_b_hi, + avm_alu_p_sub_b_lo, + avm_alu_res_hi, + avm_alu_res_lo, + avm_alu_rng_chk_lookup_selector, + avm_alu_rng_chk_sel, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -212,6 +282,8 @@ class AvmFlavor { avm_main_sel_op_and, avm_main_sel_op_div, avm_main_sel_op_eq, + avm_main_sel_op_lt, + avm_main_sel_op_lte, avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, @@ -252,16 +324,57 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_u8_0, + lookup_u8_1, + lookup_u16_0, + lookup_u16_1, + lookup_u16_2, + lookup_u16_3, + lookup_u16_4, + lookup_u16_5, + lookup_u16_6, + lookup_u16_7, + lookup_u16_8, + lookup_u16_9, + lookup_u16_10, + lookup_u16_11, + lookup_u16_12, + lookup_u16_13, + lookup_u16_14, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, - incl_mem_tag_err_counts) + incl_mem_tag_err_counts, + lookup_u8_0_counts, + lookup_u8_1_counts, + lookup_u16_0_counts, + lookup_u16_1_counts, + lookup_u16_2_counts, + lookup_u16_3_counts, + lookup_u16_4_counts, + lookup_u16_5_counts, + lookup_u16_6_counts, + lookup_u16_7_counts, + lookup_u16_8_counts, + lookup_u16_9_counts, + lookup_u16_10_counts, + lookup_u16_11_counts, + lookup_u16_12_counts, + lookup_u16_13_counts, + lookup_u16_14_counts) RefVector get_wires() { - return { avm_alu_alu_sel, + return { avm_alu_a_hi, + avm_alu_a_lo, + avm_alu_alu_sel, + avm_alu_b_hi, + avm_alu_b_lo, + avm_alu_borrow, avm_alu_cf, avm_alu_clk, + avm_alu_cmp_rng_ctr, + avm_alu_cmp_sel, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -271,9 +384,21 @@ class AvmFlavor { avm_alu_op_div, avm_alu_op_eq, avm_alu_op_eq_diff_inv, + avm_alu_op_lt, + avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, avm_alu_op_sub, + avm_alu_p_a_borrow, + avm_alu_p_b_borrow, + avm_alu_p_sub_a_hi, + avm_alu_p_sub_a_lo, + avm_alu_p_sub_b_hi, + avm_alu_p_sub_b_lo, + avm_alu_res_hi, + avm_alu_res_lo, + avm_alu_rng_chk_lookup_selector, + avm_alu_rng_chk_sel, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -353,6 +478,8 @@ class AvmFlavor { avm_main_sel_op_and, avm_main_sel_op_div, avm_main_sel_op_eq, + avm_main_sel_op_lt, + avm_main_sel_op_lte, avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, @@ -393,10 +520,44 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_u8_0, + lookup_u8_1, + lookup_u16_0, + lookup_u16_1, + lookup_u16_2, + lookup_u16_3, + lookup_u16_4, + lookup_u16_5, + lookup_u16_6, + lookup_u16_7, + lookup_u16_8, + lookup_u16_9, + lookup_u16_10, + lookup_u16_11, + lookup_u16_12, + lookup_u16_13, + lookup_u16_14, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, - incl_mem_tag_err_counts }; + incl_mem_tag_err_counts, + lookup_u8_0_counts, + lookup_u8_1_counts, + lookup_u16_0_counts, + lookup_u16_1_counts, + lookup_u16_2_counts, + lookup_u16_3_counts, + lookup_u16_4_counts, + lookup_u16_5_counts, + lookup_u16_6_counts, + lookup_u16_7_counts, + lookup_u16_8_counts, + lookup_u16_9_counts, + lookup_u16_10_counts, + lookup_u16_11_counts, + lookup_u16_12_counts, + lookup_u16_13_counts, + lookup_u16_14_counts }; }; }; @@ -405,9 +566,16 @@ class AvmFlavor { DEFINE_FLAVOR_MEMBERS(DataType, avm_main_clk, avm_main_first, + avm_alu_a_hi, + avm_alu_a_lo, avm_alu_alu_sel, + avm_alu_b_hi, + avm_alu_b_lo, + avm_alu_borrow, avm_alu_cf, avm_alu_clk, + avm_alu_cmp_rng_ctr, + avm_alu_cmp_sel, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -417,9 +585,21 @@ class AvmFlavor { avm_alu_op_div, avm_alu_op_eq, avm_alu_op_eq_diff_inv, + avm_alu_op_lt, + avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, avm_alu_op_sub, + avm_alu_p_a_borrow, + avm_alu_p_b_borrow, + avm_alu_p_sub_a_hi, + avm_alu_p_sub_a_lo, + avm_alu_p_sub_b_hi, + avm_alu_p_sub_b_lo, + avm_alu_res_hi, + avm_alu_res_lo, + avm_alu_rng_chk_lookup_selector, + avm_alu_rng_chk_sel, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -499,6 +679,8 @@ class AvmFlavor { avm_main_sel_op_and, avm_main_sel_op_div, avm_main_sel_op_eq, + avm_main_sel_op_lt, + avm_main_sel_op_lte, avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, @@ -539,10 +721,54 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_u8_0, + lookup_u8_1, + lookup_u16_0, + lookup_u16_1, + lookup_u16_2, + lookup_u16_3, + lookup_u16_4, + lookup_u16_5, + lookup_u16_6, + lookup_u16_7, + lookup_u16_8, + lookup_u16_9, + lookup_u16_10, + lookup_u16_11, + lookup_u16_12, + lookup_u16_13, + lookup_u16_14, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_u8_0_counts, + lookup_u8_1_counts, + lookup_u16_0_counts, + lookup_u16_1_counts, + lookup_u16_2_counts, + lookup_u16_3_counts, + lookup_u16_4_counts, + lookup_u16_5_counts, + lookup_u16_6_counts, + lookup_u16_7_counts, + lookup_u16_8_counts, + lookup_u16_9_counts, + lookup_u16_10_counts, + lookup_u16_11_counts, + lookup_u16_12_counts, + lookup_u16_13_counts, + lookup_u16_14_counts, + avm_alu_a_hi_shift, + avm_alu_a_lo_shift, + avm_alu_b_hi_shift, + avm_alu_b_lo_shift, + avm_alu_cmp_rng_ctr_shift, + avm_alu_p_sub_a_hi_shift, + avm_alu_p_sub_a_lo_shift, + avm_alu_p_sub_b_hi_shift, + avm_alu_p_sub_b_lo_shift, + avm_alu_rng_chk_sel_shift, avm_alu_u16_r0_shift, avm_alu_u16_r1_shift, avm_alu_u16_r2_shift, @@ -567,9 +793,16 @@ class AvmFlavor { { return { avm_main_clk, avm_main_first, + avm_alu_a_hi, + avm_alu_a_lo, avm_alu_alu_sel, + avm_alu_b_hi, + avm_alu_b_lo, + avm_alu_borrow, avm_alu_cf, avm_alu_clk, + avm_alu_cmp_rng_ctr, + avm_alu_cmp_sel, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -579,9 +812,21 @@ class AvmFlavor { avm_alu_op_div, avm_alu_op_eq, avm_alu_op_eq_diff_inv, + avm_alu_op_lt, + avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, avm_alu_op_sub, + avm_alu_p_a_borrow, + avm_alu_p_b_borrow, + avm_alu_p_sub_a_hi, + avm_alu_p_sub_a_lo, + avm_alu_p_sub_b_hi, + avm_alu_p_sub_b_lo, + avm_alu_res_hi, + avm_alu_res_lo, + avm_alu_rng_chk_lookup_selector, + avm_alu_rng_chk_sel, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -661,6 +906,8 @@ class AvmFlavor { avm_main_sel_op_and, avm_main_sel_op_div, avm_main_sel_op_eq, + avm_main_sel_op_lt, + avm_main_sel_op_lte, avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, @@ -701,10 +948,54 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_u8_0, + lookup_u8_1, + lookup_u16_0, + lookup_u16_1, + lookup_u16_2, + lookup_u16_3, + lookup_u16_4, + lookup_u16_5, + lookup_u16_6, + lookup_u16_7, + lookup_u16_8, + lookup_u16_9, + lookup_u16_10, + lookup_u16_11, + lookup_u16_12, + lookup_u16_13, + lookup_u16_14, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts, + lookup_u8_0_counts, + lookup_u8_1_counts, + lookup_u16_0_counts, + lookup_u16_1_counts, + lookup_u16_2_counts, + lookup_u16_3_counts, + lookup_u16_4_counts, + lookup_u16_5_counts, + lookup_u16_6_counts, + lookup_u16_7_counts, + lookup_u16_8_counts, + lookup_u16_9_counts, + lookup_u16_10_counts, + lookup_u16_11_counts, + lookup_u16_12_counts, + lookup_u16_13_counts, + lookup_u16_14_counts, + avm_alu_a_hi_shift, + avm_alu_a_lo_shift, + avm_alu_b_hi_shift, + avm_alu_b_lo_shift, + avm_alu_cmp_rng_ctr_shift, + avm_alu_p_sub_a_hi_shift, + avm_alu_p_sub_a_lo_shift, + avm_alu_p_sub_b_hi_shift, + avm_alu_p_sub_b_lo_shift, + avm_alu_rng_chk_sel_shift, avm_alu_u16_r0_shift, avm_alu_u16_r1_shift, avm_alu_u16_r2_shift, @@ -729,9 +1020,16 @@ class AvmFlavor { { return { avm_main_clk, avm_main_first, + avm_alu_a_hi, + avm_alu_a_lo, avm_alu_alu_sel, + avm_alu_b_hi, + avm_alu_b_lo, + avm_alu_borrow, avm_alu_cf, avm_alu_clk, + avm_alu_cmp_rng_ctr, + avm_alu_cmp_sel, avm_alu_ff_tag, avm_alu_ia, avm_alu_ib, @@ -741,9 +1039,21 @@ class AvmFlavor { avm_alu_op_div, avm_alu_op_eq, avm_alu_op_eq_diff_inv, + avm_alu_op_lt, + avm_alu_op_lte, avm_alu_op_mul, avm_alu_op_not, avm_alu_op_sub, + avm_alu_p_a_borrow, + avm_alu_p_b_borrow, + avm_alu_p_sub_a_hi, + avm_alu_p_sub_a_lo, + avm_alu_p_sub_b_hi, + avm_alu_p_sub_b_lo, + avm_alu_res_hi, + avm_alu_res_lo, + avm_alu_rng_chk_lookup_selector, + avm_alu_rng_chk_sel, avm_alu_u128_tag, avm_alu_u16_r0, avm_alu_u16_r1, @@ -823,6 +1133,8 @@ class AvmFlavor { avm_main_sel_op_and, avm_main_sel_op_div, avm_main_sel_op_eq, + avm_main_sel_op_lt, + avm_main_sel_op_lte, avm_main_sel_op_mul, avm_main_sel_op_not, avm_main_sel_op_or, @@ -863,35 +1175,72 @@ class AvmFlavor { lookup_byte_operations, incl_main_tag_err, incl_mem_tag_err, + lookup_u8_0, + lookup_u8_1, + lookup_u16_0, + lookup_u16_1, + lookup_u16_2, + lookup_u16_3, + lookup_u16_4, + lookup_u16_5, + lookup_u16_6, + lookup_u16_7, + lookup_u16_8, + lookup_u16_9, + lookup_u16_10, + lookup_u16_11, + lookup_u16_12, + lookup_u16_13, + lookup_u16_14, lookup_byte_lengths_counts, lookup_byte_operations_counts, incl_main_tag_err_counts, - incl_mem_tag_err_counts }; + incl_mem_tag_err_counts, + lookup_u8_0_counts, + lookup_u8_1_counts, + lookup_u16_0_counts, + lookup_u16_1_counts, + lookup_u16_2_counts, + lookup_u16_3_counts, + lookup_u16_4_counts, + lookup_u16_5_counts, + lookup_u16_6_counts, + lookup_u16_7_counts, + lookup_u16_8_counts, + lookup_u16_9_counts, + lookup_u16_10_counts, + lookup_u16_11_counts, + lookup_u16_12_counts, + lookup_u16_13_counts, + lookup_u16_14_counts }; }; RefVector get_to_be_shifted() { - return { avm_alu_u16_r0, avm_alu_u16_r1, - avm_alu_u16_r2, avm_alu_u16_r3, - avm_alu_u16_r4, avm_alu_u16_r5, - avm_alu_u16_r6, avm_alu_u16_r7, - avm_binary_acc_ia, avm_binary_acc_ib, - avm_binary_acc_ic, avm_binary_mem_tag_ctr, - avm_binary_op_id, avm_main_internal_return_ptr, - avm_main_pc, avm_mem_addr, - avm_mem_rw, avm_mem_tag, + return { avm_alu_a_hi, avm_alu_a_lo, avm_alu_b_hi, avm_alu_b_lo, + avm_alu_cmp_rng_ctr, avm_alu_p_sub_a_hi, avm_alu_p_sub_a_lo, avm_alu_p_sub_b_hi, + avm_alu_p_sub_b_lo, avm_alu_rng_chk_sel, avm_alu_u16_r0, avm_alu_u16_r1, + avm_alu_u16_r2, avm_alu_u16_r3, avm_alu_u16_r4, avm_alu_u16_r5, + avm_alu_u16_r6, avm_alu_u16_r7, avm_binary_acc_ia, avm_binary_acc_ib, + avm_binary_acc_ic, avm_binary_mem_tag_ctr, avm_binary_op_id, avm_main_internal_return_ptr, + avm_main_pc, avm_mem_addr, avm_mem_rw, avm_mem_tag, avm_mem_val }; }; RefVector get_shifted() { - return { avm_alu_u16_r0_shift, avm_alu_u16_r1_shift, - avm_alu_u16_r2_shift, avm_alu_u16_r3_shift, - avm_alu_u16_r4_shift, avm_alu_u16_r5_shift, - avm_alu_u16_r6_shift, avm_alu_u16_r7_shift, - avm_binary_acc_ia_shift, avm_binary_acc_ib_shift, - avm_binary_acc_ic_shift, avm_binary_mem_tag_ctr_shift, - avm_binary_op_id_shift, avm_main_internal_return_ptr_shift, - avm_main_pc_shift, avm_mem_addr_shift, - avm_mem_rw_shift, avm_mem_tag_shift, + return { avm_alu_a_hi_shift, avm_alu_a_lo_shift, + avm_alu_b_hi_shift, avm_alu_b_lo_shift, + avm_alu_cmp_rng_ctr_shift, avm_alu_p_sub_a_hi_shift, + avm_alu_p_sub_a_lo_shift, avm_alu_p_sub_b_hi_shift, + avm_alu_p_sub_b_lo_shift, avm_alu_rng_chk_sel_shift, + avm_alu_u16_r0_shift, avm_alu_u16_r1_shift, + avm_alu_u16_r2_shift, avm_alu_u16_r3_shift, + avm_alu_u16_r4_shift, avm_alu_u16_r5_shift, + avm_alu_u16_r6_shift, avm_alu_u16_r7_shift, + avm_binary_acc_ia_shift, avm_binary_acc_ib_shift, + avm_binary_acc_ic_shift, avm_binary_mem_tag_ctr_shift, + avm_binary_op_id_shift, avm_main_internal_return_ptr_shift, + avm_main_pc_shift, avm_mem_addr_shift, + avm_mem_rw_shift, avm_mem_tag_shift, avm_mem_val_shift }; }; }; @@ -905,21 +1254,16 @@ class AvmFlavor { RefVector get_to_be_shifted() { - return { avm_alu_u16_r0, avm_alu_u16_r1, - avm_alu_u16_r2, avm_alu_u16_r3, - avm_alu_u16_r4, avm_alu_u16_r5, - avm_alu_u16_r6, avm_alu_u16_r7, - avm_binary_acc_ia, avm_binary_acc_ib, - avm_binary_acc_ic, avm_binary_mem_tag_ctr, - avm_binary_op_id, avm_main_internal_return_ptr, - avm_main_pc, avm_mem_addr, - avm_mem_rw, avm_mem_tag, + return { avm_alu_a_hi, avm_alu_a_lo, avm_alu_b_hi, avm_alu_b_lo, + avm_alu_cmp_rng_ctr, avm_alu_p_sub_a_hi, avm_alu_p_sub_a_lo, avm_alu_p_sub_b_hi, + avm_alu_p_sub_b_lo, avm_alu_rng_chk_sel, avm_alu_u16_r0, avm_alu_u16_r1, + avm_alu_u16_r2, avm_alu_u16_r3, avm_alu_u16_r4, avm_alu_u16_r5, + avm_alu_u16_r6, avm_alu_u16_r7, avm_binary_acc_ia, avm_binary_acc_ib, + avm_binary_acc_ic, avm_binary_mem_tag_ctr, avm_binary_op_id, avm_main_internal_return_ptr, + avm_main_pc, avm_mem_addr, avm_mem_rw, avm_mem_tag, avm_mem_val }; }; - // The plookup wires that store plookup read data. - std::array get_table_column_wires() { return {}; }; - void compute_logderivative_inverses(const RelationParameters& relation_parameters) { ProverPolynomials prover_polynomials = ProverPolynomials(*this); @@ -940,35 +1284,52 @@ class AvmFlavor { prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); - bb::compute_logderivative_inverse>( + bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); - bb::compute_logderivative_inverse>( + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( + prover_polynomials, relation_parameters, this->circuit_size); + bb::compute_logderivative_inverse>( prover_polynomials, relation_parameters, this->circuit_size); } }; - class VerificationKey : public VerificationKey_, VerifierCommitmentKey> { - public: - VerificationKey() = default; - VerificationKey(const size_t circuit_size, const size_t num_public_inputs) - : VerificationKey_(circuit_size, num_public_inputs) - {} - - VerificationKey(ProvingKey& proving_key) - { - this->pcs_verification_key = std::make_shared(); - this->circuit_size = proving_key.circuit_size; - this->log_circuit_size = numeric::get_msb(this->circuit_size); - - for (auto [polynomial, commitment] : zip_view(proving_key.get_precomputed_polynomials(), this->get_all())) { - commitment = proving_key.commitment_key->commit(polynomial); - } - } - }; + using VerificationKey = VerificationKey_, VerifierCommitmentKey>; using FoldedPolynomials = AllEntities>; @@ -991,7 +1352,6 @@ class AvmFlavor { ProverPolynomials& operator=(ProverPolynomials&& o) noexcept = default; ~ProverPolynomials() = default; - // NOTE: copied from goblin ultra ProverPolynomials(ProvingKey& proving_key) { for (auto [prover_poly, key_poly] : zip_view(this->get_unshifted(), proving_key.get_all())) { @@ -1004,7 +1364,7 @@ class AvmFlavor { } } - [[nodiscard]] size_t get_polynomial_size() const { return avm_alu_alu_sel.size(); } + [[nodiscard]] size_t get_polynomial_size() const { return avm_alu_a_hi.size(); } /** * @brief Returns the evaluations of all prover polynomials at one point on the boolean hypercube, which * represents one row in the execution trace. @@ -1060,9 +1420,16 @@ class AvmFlavor { { Base::avm_main_clk = "AVM_MAIN_CLK"; Base::avm_main_first = "AVM_MAIN_FIRST"; + Base::avm_alu_a_hi = "AVM_ALU_A_HI"; + Base::avm_alu_a_lo = "AVM_ALU_A_LO"; Base::avm_alu_alu_sel = "AVM_ALU_ALU_SEL"; + Base::avm_alu_b_hi = "AVM_ALU_B_HI"; + Base::avm_alu_b_lo = "AVM_ALU_B_LO"; + Base::avm_alu_borrow = "AVM_ALU_BORROW"; Base::avm_alu_cf = "AVM_ALU_CF"; Base::avm_alu_clk = "AVM_ALU_CLK"; + Base::avm_alu_cmp_rng_ctr = "AVM_ALU_CMP_RNG_CTR"; + Base::avm_alu_cmp_sel = "AVM_ALU_CMP_SEL"; Base::avm_alu_ff_tag = "AVM_ALU_FF_TAG"; Base::avm_alu_ia = "AVM_ALU_IA"; Base::avm_alu_ib = "AVM_ALU_IB"; @@ -1072,9 +1439,21 @@ class AvmFlavor { Base::avm_alu_op_div = "AVM_ALU_OP_DIV"; Base::avm_alu_op_eq = "AVM_ALU_OP_EQ"; Base::avm_alu_op_eq_diff_inv = "AVM_ALU_OP_EQ_DIFF_INV"; + Base::avm_alu_op_lt = "AVM_ALU_OP_LT"; + Base::avm_alu_op_lte = "AVM_ALU_OP_LTE"; Base::avm_alu_op_mul = "AVM_ALU_OP_MUL"; Base::avm_alu_op_not = "AVM_ALU_OP_NOT"; Base::avm_alu_op_sub = "AVM_ALU_OP_SUB"; + Base::avm_alu_p_a_borrow = "AVM_ALU_P_A_BORROW"; + Base::avm_alu_p_b_borrow = "AVM_ALU_P_B_BORROW"; + Base::avm_alu_p_sub_a_hi = "AVM_ALU_P_SUB_A_HI"; + Base::avm_alu_p_sub_a_lo = "AVM_ALU_P_SUB_A_LO"; + Base::avm_alu_p_sub_b_hi = "AVM_ALU_P_SUB_B_HI"; + Base::avm_alu_p_sub_b_lo = "AVM_ALU_P_SUB_B_LO"; + Base::avm_alu_res_hi = "AVM_ALU_RES_HI"; + Base::avm_alu_res_lo = "AVM_ALU_RES_LO"; + Base::avm_alu_rng_chk_lookup_selector = "AVM_ALU_RNG_CHK_LOOKUP_SELECTOR"; + Base::avm_alu_rng_chk_sel = "AVM_ALU_RNG_CHK_SEL"; Base::avm_alu_u128_tag = "AVM_ALU_U128_TAG"; Base::avm_alu_u16_r0 = "AVM_ALU_U16_R0"; Base::avm_alu_u16_r1 = "AVM_ALU_U16_R1"; @@ -1154,6 +1533,8 @@ class AvmFlavor { Base::avm_main_sel_op_and = "AVM_MAIN_SEL_OP_AND"; Base::avm_main_sel_op_div = "AVM_MAIN_SEL_OP_DIV"; Base::avm_main_sel_op_eq = "AVM_MAIN_SEL_OP_EQ"; + Base::avm_main_sel_op_lt = "AVM_MAIN_SEL_OP_LT"; + Base::avm_main_sel_op_lte = "AVM_MAIN_SEL_OP_LTE"; Base::avm_main_sel_op_mul = "AVM_MAIN_SEL_OP_MUL"; Base::avm_main_sel_op_not = "AVM_MAIN_SEL_OP_NOT"; Base::avm_main_sel_op_or = "AVM_MAIN_SEL_OP_OR"; @@ -1194,10 +1575,44 @@ 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_u8_0 = "LOOKUP_U8_0"; + Base::lookup_u8_1 = "LOOKUP_U8_1"; + Base::lookup_u16_0 = "LOOKUP_U16_0"; + Base::lookup_u16_1 = "LOOKUP_U16_1"; + Base::lookup_u16_2 = "LOOKUP_U16_2"; + Base::lookup_u16_3 = "LOOKUP_U16_3"; + Base::lookup_u16_4 = "LOOKUP_U16_4"; + Base::lookup_u16_5 = "LOOKUP_U16_5"; + Base::lookup_u16_6 = "LOOKUP_U16_6"; + Base::lookup_u16_7 = "LOOKUP_U16_7"; + Base::lookup_u16_8 = "LOOKUP_U16_8"; + Base::lookup_u16_9 = "LOOKUP_U16_9"; + Base::lookup_u16_10 = "LOOKUP_U16_10"; + Base::lookup_u16_11 = "LOOKUP_U16_11"; + Base::lookup_u16_12 = "LOOKUP_U16_12"; + Base::lookup_u16_13 = "LOOKUP_U16_13"; + Base::lookup_u16_14 = "LOOKUP_U16_14"; Base::lookup_byte_lengths_counts = "LOOKUP_BYTE_LENGTHS_COUNTS"; 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_u8_0_counts = "LOOKUP_U8_0_COUNTS"; + Base::lookup_u8_1_counts = "LOOKUP_U8_1_COUNTS"; + Base::lookup_u16_0_counts = "LOOKUP_U16_0_COUNTS"; + Base::lookup_u16_1_counts = "LOOKUP_U16_1_COUNTS"; + Base::lookup_u16_2_counts = "LOOKUP_U16_2_COUNTS"; + Base::lookup_u16_3_counts = "LOOKUP_U16_3_COUNTS"; + Base::lookup_u16_4_counts = "LOOKUP_U16_4_COUNTS"; + Base::lookup_u16_5_counts = "LOOKUP_U16_5_COUNTS"; + Base::lookup_u16_6_counts = "LOOKUP_U16_6_COUNTS"; + Base::lookup_u16_7_counts = "LOOKUP_U16_7_COUNTS"; + Base::lookup_u16_8_counts = "LOOKUP_U16_8_COUNTS"; + Base::lookup_u16_9_counts = "LOOKUP_U16_9_COUNTS"; + Base::lookup_u16_10_counts = "LOOKUP_U16_10_COUNTS"; + Base::lookup_u16_11_counts = "LOOKUP_U16_11_COUNTS"; + Base::lookup_u16_12_counts = "LOOKUP_U16_12_COUNTS"; + Base::lookup_u16_13_counts = "LOOKUP_U16_13_COUNTS"; + Base::lookup_u16_14_counts = "LOOKUP_U16_14_COUNTS"; }; }; @@ -1217,9 +1632,16 @@ class AvmFlavor { public: uint32_t circuit_size; + Commitment avm_alu_a_hi; + Commitment avm_alu_a_lo; Commitment avm_alu_alu_sel; + Commitment avm_alu_b_hi; + Commitment avm_alu_b_lo; + Commitment avm_alu_borrow; Commitment avm_alu_cf; Commitment avm_alu_clk; + Commitment avm_alu_cmp_rng_ctr; + Commitment avm_alu_cmp_sel; Commitment avm_alu_ff_tag; Commitment avm_alu_ia; Commitment avm_alu_ib; @@ -1229,9 +1651,21 @@ class AvmFlavor { Commitment avm_alu_op_div; Commitment avm_alu_op_eq; Commitment avm_alu_op_eq_diff_inv; + Commitment avm_alu_op_lt; + Commitment avm_alu_op_lte; Commitment avm_alu_op_mul; Commitment avm_alu_op_not; Commitment avm_alu_op_sub; + Commitment avm_alu_p_a_borrow; + Commitment avm_alu_p_b_borrow; + Commitment avm_alu_p_sub_a_hi; + Commitment avm_alu_p_sub_a_lo; + Commitment avm_alu_p_sub_b_hi; + Commitment avm_alu_p_sub_b_lo; + Commitment avm_alu_res_hi; + Commitment avm_alu_res_lo; + Commitment avm_alu_rng_chk_lookup_selector; + Commitment avm_alu_rng_chk_sel; Commitment avm_alu_u128_tag; Commitment avm_alu_u16_r0; Commitment avm_alu_u16_r1; @@ -1311,6 +1745,8 @@ class AvmFlavor { Commitment avm_main_sel_op_and; Commitment avm_main_sel_op_div; Commitment avm_main_sel_op_eq; + Commitment avm_main_sel_op_lt; + Commitment avm_main_sel_op_lte; Commitment avm_main_sel_op_mul; Commitment avm_main_sel_op_not; Commitment avm_main_sel_op_or; @@ -1339,8 +1775,6 @@ class AvmFlavor { Commitment avm_mem_tag_err; Commitment avm_mem_val; Commitment avm_mem_w_in_tag; - - // Perm inverses Commitment perm_main_alu; Commitment perm_main_bin; Commitment perm_main_mem_a; @@ -1349,17 +1783,48 @@ class AvmFlavor { Commitment perm_main_mem_ind_a; Commitment perm_main_mem_ind_b; Commitment perm_main_mem_ind_c; - // Lookup inverses Commitment lookup_byte_lengths; Commitment lookup_byte_operations; Commitment incl_main_tag_err; Commitment incl_mem_tag_err; - - // Lookup counts + Commitment lookup_u8_0; + Commitment lookup_u8_1; + Commitment lookup_u16_0; + Commitment lookup_u16_1; + Commitment lookup_u16_2; + Commitment lookup_u16_3; + Commitment lookup_u16_4; + Commitment lookup_u16_5; + Commitment lookup_u16_6; + Commitment lookup_u16_7; + Commitment lookup_u16_8; + Commitment lookup_u16_9; + Commitment lookup_u16_10; + Commitment lookup_u16_11; + Commitment lookup_u16_12; + Commitment lookup_u16_13; + Commitment lookup_u16_14; Commitment lookup_byte_lengths_counts; Commitment lookup_byte_operations_counts; Commitment incl_main_tag_err_counts; Commitment incl_mem_tag_err_counts; + Commitment lookup_u8_0_counts; + Commitment lookup_u8_1_counts; + Commitment lookup_u16_0_counts; + Commitment lookup_u16_1_counts; + Commitment lookup_u16_2_counts; + Commitment lookup_u16_3_counts; + Commitment lookup_u16_4_counts; + Commitment lookup_u16_5_counts; + Commitment lookup_u16_6_counts; + Commitment lookup_u16_7_counts; + Commitment lookup_u16_8_counts; + Commitment lookup_u16_9_counts; + Commitment lookup_u16_10_counts; + Commitment lookup_u16_11_counts; + Commitment lookup_u16_12_counts; + Commitment lookup_u16_13_counts; + Commitment lookup_u16_14_counts; std::vector> sumcheck_univariates; std::array sumcheck_evaluations; @@ -1379,9 +1844,16 @@ class AvmFlavor { circuit_size = deserialize_from_buffer(proof_data, num_frs_read); size_t log_n = numeric::get_msb(circuit_size); + avm_alu_a_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_a_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_alu_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_b_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_b_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_borrow = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_cf = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_clk = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_cmp_rng_ctr = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_cmp_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_ff_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_ia = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_ib = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1391,9 +1863,21 @@ class AvmFlavor { avm_alu_op_div = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_eq = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_eq_diff_inv = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_op_lt = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_op_lte = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_mul = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_not = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_op_sub = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_p_a_borrow = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_p_b_borrow = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_p_sub_a_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_p_sub_a_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_p_sub_b_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_p_sub_b_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_res_hi = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_res_lo = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_rng_chk_lookup_selector = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_alu_rng_chk_sel = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_u128_tag = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_u16_r0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_alu_u16_r1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1474,6 +1958,8 @@ class AvmFlavor { avm_main_sel_op_and = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_div = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_eq = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_op_lt = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + avm_main_sel_op_lte = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_mul = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_not = deserialize_from_buffer(Transcript::proof_data, num_frs_read); avm_main_sel_op_or = deserialize_from_buffer(Transcript::proof_data, num_frs_read); @@ -1514,10 +2000,44 @@ 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_u8_0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u8_1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_0 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_1 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_2 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_3 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_4 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_5 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_6 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_7 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_8 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_9 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_10 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_11 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_12 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_13 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_14 = deserialize_from_buffer(Transcript::proof_data, num_frs_read); lookup_byte_lengths_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); 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_u8_0_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u8_1_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_0_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_1_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_2_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_3_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_4_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_5_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_6_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_7_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_8_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_9_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_10_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_11_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_12_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_13_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); + lookup_u16_14_counts = deserialize_from_buffer(Transcript::proof_data, num_frs_read); for (size_t i = 0; i < log_n; ++i) { sumcheck_univariates.emplace_back( @@ -1541,9 +2061,16 @@ class AvmFlavor { serialize_to_buffer(circuit_size, Transcript::proof_data); + serialize_to_buffer(avm_alu_a_hi, Transcript::proof_data); + serialize_to_buffer(avm_alu_a_lo, Transcript::proof_data); serialize_to_buffer(avm_alu_alu_sel, Transcript::proof_data); + serialize_to_buffer(avm_alu_b_hi, Transcript::proof_data); + serialize_to_buffer(avm_alu_b_lo, Transcript::proof_data); + serialize_to_buffer(avm_alu_borrow, Transcript::proof_data); serialize_to_buffer(avm_alu_cf, Transcript::proof_data); serialize_to_buffer(avm_alu_clk, Transcript::proof_data); + serialize_to_buffer(avm_alu_cmp_rng_ctr, Transcript::proof_data); + serialize_to_buffer(avm_alu_cmp_sel, Transcript::proof_data); serialize_to_buffer(avm_alu_ff_tag, Transcript::proof_data); serialize_to_buffer(avm_alu_ia, Transcript::proof_data); serialize_to_buffer(avm_alu_ib, Transcript::proof_data); @@ -1553,9 +2080,21 @@ class AvmFlavor { serialize_to_buffer(avm_alu_op_div, Transcript::proof_data); serialize_to_buffer(avm_alu_op_eq, Transcript::proof_data); serialize_to_buffer(avm_alu_op_eq_diff_inv, Transcript::proof_data); + serialize_to_buffer(avm_alu_op_lt, Transcript::proof_data); + serialize_to_buffer(avm_alu_op_lte, Transcript::proof_data); serialize_to_buffer(avm_alu_op_mul, Transcript::proof_data); serialize_to_buffer(avm_alu_op_not, Transcript::proof_data); serialize_to_buffer(avm_alu_op_sub, Transcript::proof_data); + serialize_to_buffer(avm_alu_p_a_borrow, Transcript::proof_data); + serialize_to_buffer(avm_alu_p_b_borrow, Transcript::proof_data); + serialize_to_buffer(avm_alu_p_sub_a_hi, Transcript::proof_data); + serialize_to_buffer(avm_alu_p_sub_a_lo, Transcript::proof_data); + serialize_to_buffer(avm_alu_p_sub_b_hi, Transcript::proof_data); + serialize_to_buffer(avm_alu_p_sub_b_lo, Transcript::proof_data); + serialize_to_buffer(avm_alu_res_hi, Transcript::proof_data); + serialize_to_buffer(avm_alu_res_lo, Transcript::proof_data); + serialize_to_buffer(avm_alu_rng_chk_lookup_selector, Transcript::proof_data); + serialize_to_buffer(avm_alu_rng_chk_sel, Transcript::proof_data); serialize_to_buffer(avm_alu_u128_tag, Transcript::proof_data); serialize_to_buffer(avm_alu_u16_r0, Transcript::proof_data); serialize_to_buffer(avm_alu_u16_r1, Transcript::proof_data); @@ -1635,6 +2174,8 @@ class AvmFlavor { serialize_to_buffer(avm_main_sel_op_and, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_div, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_eq, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_op_lt, Transcript::proof_data); + serialize_to_buffer(avm_main_sel_op_lte, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_mul, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_not, Transcript::proof_data); serialize_to_buffer(avm_main_sel_op_or, Transcript::proof_data); @@ -1675,10 +2216,44 @@ 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_u8_0, Transcript::proof_data); + serialize_to_buffer(lookup_u8_1, Transcript::proof_data); + serialize_to_buffer(lookup_u16_0, Transcript::proof_data); + serialize_to_buffer(lookup_u16_1, Transcript::proof_data); + serialize_to_buffer(lookup_u16_2, Transcript::proof_data); + serialize_to_buffer(lookup_u16_3, Transcript::proof_data); + serialize_to_buffer(lookup_u16_4, Transcript::proof_data); + serialize_to_buffer(lookup_u16_5, Transcript::proof_data); + serialize_to_buffer(lookup_u16_6, Transcript::proof_data); + serialize_to_buffer(lookup_u16_7, Transcript::proof_data); + serialize_to_buffer(lookup_u16_8, Transcript::proof_data); + serialize_to_buffer(lookup_u16_9, Transcript::proof_data); + serialize_to_buffer(lookup_u16_10, Transcript::proof_data); + serialize_to_buffer(lookup_u16_11, Transcript::proof_data); + serialize_to_buffer(lookup_u16_12, Transcript::proof_data); + serialize_to_buffer(lookup_u16_13, Transcript::proof_data); + serialize_to_buffer(lookup_u16_14, Transcript::proof_data); serialize_to_buffer(lookup_byte_lengths_counts, Transcript::proof_data); 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_u8_0_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u8_1_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_0_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_1_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_2_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_3_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_4_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_5_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_6_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_7_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_8_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_9_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_10_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_11_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_12_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_13_counts, Transcript::proof_data); + serialize_to_buffer(lookup_u16_14_counts, Transcript::proof_data); for (size_t i = 0; i < log_n; ++i) { serialize_to_buffer(sumcheck_univariates[i], 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 0bd67e09fa3..6d1bacc8d97 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_prover.cpp @@ -51,17 +51,24 @@ void AvmProver::execute_preamble_round() } /** - * @brief Compute commitments to the first three wires + * @brief Compute commitments to all of the witness wires (apart from the logderivative inverse wires) * */ void AvmProver::execute_wire_commitments_round() { - auto labels = commitment_labels; - + // Commit to all polynomials (apart from logderivative inverse polynomials, which are committed to in the later + // logderivative phase) + witness_commitments.avm_alu_a_hi = commitment_key->commit(key->avm_alu_a_hi); + witness_commitments.avm_alu_a_lo = commitment_key->commit(key->avm_alu_a_lo); witness_commitments.avm_alu_alu_sel = commitment_key->commit(key->avm_alu_alu_sel); + witness_commitments.avm_alu_b_hi = commitment_key->commit(key->avm_alu_b_hi); + witness_commitments.avm_alu_b_lo = commitment_key->commit(key->avm_alu_b_lo); + witness_commitments.avm_alu_borrow = commitment_key->commit(key->avm_alu_borrow); witness_commitments.avm_alu_cf = commitment_key->commit(key->avm_alu_cf); witness_commitments.avm_alu_clk = commitment_key->commit(key->avm_alu_clk); + witness_commitments.avm_alu_cmp_rng_ctr = commitment_key->commit(key->avm_alu_cmp_rng_ctr); + witness_commitments.avm_alu_cmp_sel = commitment_key->commit(key->avm_alu_cmp_sel); witness_commitments.avm_alu_ff_tag = commitment_key->commit(key->avm_alu_ff_tag); witness_commitments.avm_alu_ia = commitment_key->commit(key->avm_alu_ia); witness_commitments.avm_alu_ib = commitment_key->commit(key->avm_alu_ib); @@ -71,9 +78,21 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_alu_op_div = commitment_key->commit(key->avm_alu_op_div); witness_commitments.avm_alu_op_eq = commitment_key->commit(key->avm_alu_op_eq); witness_commitments.avm_alu_op_eq_diff_inv = commitment_key->commit(key->avm_alu_op_eq_diff_inv); + witness_commitments.avm_alu_op_lt = commitment_key->commit(key->avm_alu_op_lt); + witness_commitments.avm_alu_op_lte = commitment_key->commit(key->avm_alu_op_lte); witness_commitments.avm_alu_op_mul = commitment_key->commit(key->avm_alu_op_mul); witness_commitments.avm_alu_op_not = commitment_key->commit(key->avm_alu_op_not); witness_commitments.avm_alu_op_sub = commitment_key->commit(key->avm_alu_op_sub); + witness_commitments.avm_alu_p_a_borrow = commitment_key->commit(key->avm_alu_p_a_borrow); + witness_commitments.avm_alu_p_b_borrow = commitment_key->commit(key->avm_alu_p_b_borrow); + witness_commitments.avm_alu_p_sub_a_hi = commitment_key->commit(key->avm_alu_p_sub_a_hi); + witness_commitments.avm_alu_p_sub_a_lo = commitment_key->commit(key->avm_alu_p_sub_a_lo); + witness_commitments.avm_alu_p_sub_b_hi = commitment_key->commit(key->avm_alu_p_sub_b_hi); + witness_commitments.avm_alu_p_sub_b_lo = commitment_key->commit(key->avm_alu_p_sub_b_lo); + witness_commitments.avm_alu_res_hi = commitment_key->commit(key->avm_alu_res_hi); + witness_commitments.avm_alu_res_lo = commitment_key->commit(key->avm_alu_res_lo); + witness_commitments.avm_alu_rng_chk_lookup_selector = commitment_key->commit(key->avm_alu_rng_chk_lookup_selector); + witness_commitments.avm_alu_rng_chk_sel = commitment_key->commit(key->avm_alu_rng_chk_sel); witness_commitments.avm_alu_u128_tag = commitment_key->commit(key->avm_alu_u128_tag); witness_commitments.avm_alu_u16_r0 = commitment_key->commit(key->avm_alu_u16_r0); witness_commitments.avm_alu_u16_r1 = commitment_key->commit(key->avm_alu_u16_r1); @@ -154,6 +173,8 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_main_sel_op_and = commitment_key->commit(key->avm_main_sel_op_and); witness_commitments.avm_main_sel_op_div = commitment_key->commit(key->avm_main_sel_op_div); witness_commitments.avm_main_sel_op_eq = commitment_key->commit(key->avm_main_sel_op_eq); + witness_commitments.avm_main_sel_op_lt = commitment_key->commit(key->avm_main_sel_op_lt); + witness_commitments.avm_main_sel_op_lte = commitment_key->commit(key->avm_main_sel_op_lte); witness_commitments.avm_main_sel_op_mul = commitment_key->commit(key->avm_main_sel_op_mul); witness_commitments.avm_main_sel_op_not = commitment_key->commit(key->avm_main_sel_op_not); witness_commitments.avm_main_sel_op_or = commitment_key->commit(key->avm_main_sel_op_or); @@ -182,161 +203,221 @@ void AvmProver::execute_wire_commitments_round() witness_commitments.avm_mem_tag_err = commitment_key->commit(key->avm_mem_tag_err); 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); - - // Lookup counts 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); - - // print some of the commitments to check they have values - - // Send all witness commitments to the verifier - transcript->send_to_verifier(labels.avm_alu_alu_sel, witness_commitments.avm_alu_alu_sel); - transcript->send_to_verifier(labels.avm_alu_cf, witness_commitments.avm_alu_cf); - transcript->send_to_verifier(labels.avm_alu_clk, witness_commitments.avm_alu_clk); - transcript->send_to_verifier(labels.avm_alu_ff_tag, witness_commitments.avm_alu_ff_tag); - transcript->send_to_verifier(labels.avm_alu_ia, witness_commitments.avm_alu_ia); - transcript->send_to_verifier(labels.avm_alu_ib, witness_commitments.avm_alu_ib); - transcript->send_to_verifier(labels.avm_alu_ic, witness_commitments.avm_alu_ic); - transcript->send_to_verifier(labels.avm_alu_in_tag, witness_commitments.avm_alu_in_tag); - transcript->send_to_verifier(labels.avm_alu_op_add, witness_commitments.avm_alu_op_add); - transcript->send_to_verifier(labels.avm_alu_op_div, witness_commitments.avm_alu_op_div); - transcript->send_to_verifier(labels.avm_alu_op_eq, witness_commitments.avm_alu_op_eq); - transcript->send_to_verifier(labels.avm_alu_op_eq_diff_inv, witness_commitments.avm_alu_op_eq_diff_inv); - transcript->send_to_verifier(labels.avm_alu_op_mul, witness_commitments.avm_alu_op_mul); - transcript->send_to_verifier(labels.avm_alu_op_not, witness_commitments.avm_alu_op_not); - transcript->send_to_verifier(labels.avm_alu_op_sub, witness_commitments.avm_alu_op_sub); - transcript->send_to_verifier(labels.avm_alu_u128_tag, witness_commitments.avm_alu_u128_tag); - transcript->send_to_verifier(labels.avm_alu_u16_r0, witness_commitments.avm_alu_u16_r0); - transcript->send_to_verifier(labels.avm_alu_u16_r1, witness_commitments.avm_alu_u16_r1); - transcript->send_to_verifier(labels.avm_alu_u16_r10, witness_commitments.avm_alu_u16_r10); - transcript->send_to_verifier(labels.avm_alu_u16_r11, witness_commitments.avm_alu_u16_r11); - transcript->send_to_verifier(labels.avm_alu_u16_r12, witness_commitments.avm_alu_u16_r12); - transcript->send_to_verifier(labels.avm_alu_u16_r13, witness_commitments.avm_alu_u16_r13); - transcript->send_to_verifier(labels.avm_alu_u16_r14, witness_commitments.avm_alu_u16_r14); - transcript->send_to_verifier(labels.avm_alu_u16_r2, witness_commitments.avm_alu_u16_r2); - transcript->send_to_verifier(labels.avm_alu_u16_r3, witness_commitments.avm_alu_u16_r3); - transcript->send_to_verifier(labels.avm_alu_u16_r4, witness_commitments.avm_alu_u16_r4); - transcript->send_to_verifier(labels.avm_alu_u16_r5, witness_commitments.avm_alu_u16_r5); - transcript->send_to_verifier(labels.avm_alu_u16_r6, witness_commitments.avm_alu_u16_r6); - transcript->send_to_verifier(labels.avm_alu_u16_r7, witness_commitments.avm_alu_u16_r7); - transcript->send_to_verifier(labels.avm_alu_u16_r8, witness_commitments.avm_alu_u16_r8); - transcript->send_to_verifier(labels.avm_alu_u16_r9, witness_commitments.avm_alu_u16_r9); - transcript->send_to_verifier(labels.avm_alu_u16_tag, witness_commitments.avm_alu_u16_tag); - transcript->send_to_verifier(labels.avm_alu_u32_tag, witness_commitments.avm_alu_u32_tag); - transcript->send_to_verifier(labels.avm_alu_u64_r0, witness_commitments.avm_alu_u64_r0); - transcript->send_to_verifier(labels.avm_alu_u64_tag, witness_commitments.avm_alu_u64_tag); - transcript->send_to_verifier(labels.avm_alu_u8_r0, witness_commitments.avm_alu_u8_r0); - transcript->send_to_verifier(labels.avm_alu_u8_r1, witness_commitments.avm_alu_u8_r1); - transcript->send_to_verifier(labels.avm_alu_u8_tag, witness_commitments.avm_alu_u8_tag); - transcript->send_to_verifier(labels.avm_binary_acc_ia, witness_commitments.avm_binary_acc_ia); - transcript->send_to_verifier(labels.avm_binary_acc_ib, witness_commitments.avm_binary_acc_ib); - transcript->send_to_verifier(labels.avm_binary_acc_ic, witness_commitments.avm_binary_acc_ic); - transcript->send_to_verifier(labels.avm_binary_bin_sel, witness_commitments.avm_binary_bin_sel); - transcript->send_to_verifier(labels.avm_binary_clk, witness_commitments.avm_binary_clk); - transcript->send_to_verifier(labels.avm_binary_ia_bytes, witness_commitments.avm_binary_ia_bytes); - transcript->send_to_verifier(labels.avm_binary_ib_bytes, witness_commitments.avm_binary_ib_bytes); - transcript->send_to_verifier(labels.avm_binary_ic_bytes, witness_commitments.avm_binary_ic_bytes); - transcript->send_to_verifier(labels.avm_binary_in_tag, witness_commitments.avm_binary_in_tag); - transcript->send_to_verifier(labels.avm_binary_mem_tag_ctr, witness_commitments.avm_binary_mem_tag_ctr); - transcript->send_to_verifier(labels.avm_binary_mem_tag_ctr_inv, witness_commitments.avm_binary_mem_tag_ctr_inv); - transcript->send_to_verifier(labels.avm_binary_op_id, witness_commitments.avm_binary_op_id); - transcript->send_to_verifier(labels.avm_binary_start, witness_commitments.avm_binary_start); - transcript->send_to_verifier(labels.avm_byte_lookup_bin_sel, witness_commitments.avm_byte_lookup_bin_sel); - transcript->send_to_verifier(labels.avm_byte_lookup_table_byte_lengths, + witness_commitments.lookup_u8_0_counts = commitment_key->commit(key->lookup_u8_0_counts); + witness_commitments.lookup_u8_1_counts = commitment_key->commit(key->lookup_u8_1_counts); + witness_commitments.lookup_u16_0_counts = commitment_key->commit(key->lookup_u16_0_counts); + witness_commitments.lookup_u16_1_counts = commitment_key->commit(key->lookup_u16_1_counts); + witness_commitments.lookup_u16_2_counts = commitment_key->commit(key->lookup_u16_2_counts); + witness_commitments.lookup_u16_3_counts = commitment_key->commit(key->lookup_u16_3_counts); + witness_commitments.lookup_u16_4_counts = commitment_key->commit(key->lookup_u16_4_counts); + witness_commitments.lookup_u16_5_counts = commitment_key->commit(key->lookup_u16_5_counts); + witness_commitments.lookup_u16_6_counts = commitment_key->commit(key->lookup_u16_6_counts); + witness_commitments.lookup_u16_7_counts = commitment_key->commit(key->lookup_u16_7_counts); + witness_commitments.lookup_u16_8_counts = commitment_key->commit(key->lookup_u16_8_counts); + witness_commitments.lookup_u16_9_counts = commitment_key->commit(key->lookup_u16_9_counts); + witness_commitments.lookup_u16_10_counts = commitment_key->commit(key->lookup_u16_10_counts); + witness_commitments.lookup_u16_11_counts = commitment_key->commit(key->lookup_u16_11_counts); + witness_commitments.lookup_u16_12_counts = commitment_key->commit(key->lookup_u16_12_counts); + witness_commitments.lookup_u16_13_counts = commitment_key->commit(key->lookup_u16_13_counts); + witness_commitments.lookup_u16_14_counts = commitment_key->commit(key->lookup_u16_14_counts); + + // Send all commitments to the verifier + transcript->send_to_verifier(commitment_labels.avm_alu_a_hi, witness_commitments.avm_alu_a_hi); + transcript->send_to_verifier(commitment_labels.avm_alu_a_lo, witness_commitments.avm_alu_a_lo); + transcript->send_to_verifier(commitment_labels.avm_alu_alu_sel, witness_commitments.avm_alu_alu_sel); + transcript->send_to_verifier(commitment_labels.avm_alu_b_hi, witness_commitments.avm_alu_b_hi); + transcript->send_to_verifier(commitment_labels.avm_alu_b_lo, witness_commitments.avm_alu_b_lo); + transcript->send_to_verifier(commitment_labels.avm_alu_borrow, witness_commitments.avm_alu_borrow); + transcript->send_to_verifier(commitment_labels.avm_alu_cf, witness_commitments.avm_alu_cf); + transcript->send_to_verifier(commitment_labels.avm_alu_clk, witness_commitments.avm_alu_clk); + transcript->send_to_verifier(commitment_labels.avm_alu_cmp_rng_ctr, witness_commitments.avm_alu_cmp_rng_ctr); + transcript->send_to_verifier(commitment_labels.avm_alu_cmp_sel, witness_commitments.avm_alu_cmp_sel); + transcript->send_to_verifier(commitment_labels.avm_alu_ff_tag, witness_commitments.avm_alu_ff_tag); + transcript->send_to_verifier(commitment_labels.avm_alu_ia, witness_commitments.avm_alu_ia); + transcript->send_to_verifier(commitment_labels.avm_alu_ib, witness_commitments.avm_alu_ib); + transcript->send_to_verifier(commitment_labels.avm_alu_ic, witness_commitments.avm_alu_ic); + transcript->send_to_verifier(commitment_labels.avm_alu_in_tag, witness_commitments.avm_alu_in_tag); + transcript->send_to_verifier(commitment_labels.avm_alu_op_add, witness_commitments.avm_alu_op_add); + transcript->send_to_verifier(commitment_labels.avm_alu_op_div, witness_commitments.avm_alu_op_div); + transcript->send_to_verifier(commitment_labels.avm_alu_op_eq, witness_commitments.avm_alu_op_eq); + transcript->send_to_verifier(commitment_labels.avm_alu_op_eq_diff_inv, witness_commitments.avm_alu_op_eq_diff_inv); + transcript->send_to_verifier(commitment_labels.avm_alu_op_lt, witness_commitments.avm_alu_op_lt); + transcript->send_to_verifier(commitment_labels.avm_alu_op_lte, witness_commitments.avm_alu_op_lte); + transcript->send_to_verifier(commitment_labels.avm_alu_op_mul, witness_commitments.avm_alu_op_mul); + transcript->send_to_verifier(commitment_labels.avm_alu_op_not, witness_commitments.avm_alu_op_not); + transcript->send_to_verifier(commitment_labels.avm_alu_op_sub, witness_commitments.avm_alu_op_sub); + transcript->send_to_verifier(commitment_labels.avm_alu_p_a_borrow, witness_commitments.avm_alu_p_a_borrow); + transcript->send_to_verifier(commitment_labels.avm_alu_p_b_borrow, witness_commitments.avm_alu_p_b_borrow); + transcript->send_to_verifier(commitment_labels.avm_alu_p_sub_a_hi, witness_commitments.avm_alu_p_sub_a_hi); + transcript->send_to_verifier(commitment_labels.avm_alu_p_sub_a_lo, witness_commitments.avm_alu_p_sub_a_lo); + transcript->send_to_verifier(commitment_labels.avm_alu_p_sub_b_hi, witness_commitments.avm_alu_p_sub_b_hi); + transcript->send_to_verifier(commitment_labels.avm_alu_p_sub_b_lo, witness_commitments.avm_alu_p_sub_b_lo); + transcript->send_to_verifier(commitment_labels.avm_alu_res_hi, witness_commitments.avm_alu_res_hi); + transcript->send_to_verifier(commitment_labels.avm_alu_res_lo, witness_commitments.avm_alu_res_lo); + transcript->send_to_verifier(commitment_labels.avm_alu_rng_chk_lookup_selector, + witness_commitments.avm_alu_rng_chk_lookup_selector); + transcript->send_to_verifier(commitment_labels.avm_alu_rng_chk_sel, witness_commitments.avm_alu_rng_chk_sel); + transcript->send_to_verifier(commitment_labels.avm_alu_u128_tag, witness_commitments.avm_alu_u128_tag); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r0, witness_commitments.avm_alu_u16_r0); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r1, witness_commitments.avm_alu_u16_r1); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r10, witness_commitments.avm_alu_u16_r10); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r11, witness_commitments.avm_alu_u16_r11); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r12, witness_commitments.avm_alu_u16_r12); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r13, witness_commitments.avm_alu_u16_r13); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r14, witness_commitments.avm_alu_u16_r14); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r2, witness_commitments.avm_alu_u16_r2); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r3, witness_commitments.avm_alu_u16_r3); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r4, witness_commitments.avm_alu_u16_r4); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r5, witness_commitments.avm_alu_u16_r5); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r6, witness_commitments.avm_alu_u16_r6); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r7, witness_commitments.avm_alu_u16_r7); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r8, witness_commitments.avm_alu_u16_r8); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_r9, witness_commitments.avm_alu_u16_r9); + transcript->send_to_verifier(commitment_labels.avm_alu_u16_tag, witness_commitments.avm_alu_u16_tag); + transcript->send_to_verifier(commitment_labels.avm_alu_u32_tag, witness_commitments.avm_alu_u32_tag); + transcript->send_to_verifier(commitment_labels.avm_alu_u64_r0, witness_commitments.avm_alu_u64_r0); + transcript->send_to_verifier(commitment_labels.avm_alu_u64_tag, witness_commitments.avm_alu_u64_tag); + transcript->send_to_verifier(commitment_labels.avm_alu_u8_r0, witness_commitments.avm_alu_u8_r0); + transcript->send_to_verifier(commitment_labels.avm_alu_u8_r1, witness_commitments.avm_alu_u8_r1); + transcript->send_to_verifier(commitment_labels.avm_alu_u8_tag, witness_commitments.avm_alu_u8_tag); + transcript->send_to_verifier(commitment_labels.avm_binary_acc_ia, witness_commitments.avm_binary_acc_ia); + transcript->send_to_verifier(commitment_labels.avm_binary_acc_ib, witness_commitments.avm_binary_acc_ib); + transcript->send_to_verifier(commitment_labels.avm_binary_acc_ic, witness_commitments.avm_binary_acc_ic); + transcript->send_to_verifier(commitment_labels.avm_binary_bin_sel, witness_commitments.avm_binary_bin_sel); + transcript->send_to_verifier(commitment_labels.avm_binary_clk, witness_commitments.avm_binary_clk); + transcript->send_to_verifier(commitment_labels.avm_binary_ia_bytes, witness_commitments.avm_binary_ia_bytes); + transcript->send_to_verifier(commitment_labels.avm_binary_ib_bytes, witness_commitments.avm_binary_ib_bytes); + transcript->send_to_verifier(commitment_labels.avm_binary_ic_bytes, witness_commitments.avm_binary_ic_bytes); + transcript->send_to_verifier(commitment_labels.avm_binary_in_tag, witness_commitments.avm_binary_in_tag); + transcript->send_to_verifier(commitment_labels.avm_binary_mem_tag_ctr, witness_commitments.avm_binary_mem_tag_ctr); + transcript->send_to_verifier(commitment_labels.avm_binary_mem_tag_ctr_inv, + witness_commitments.avm_binary_mem_tag_ctr_inv); + transcript->send_to_verifier(commitment_labels.avm_binary_op_id, witness_commitments.avm_binary_op_id); + transcript->send_to_verifier(commitment_labels.avm_binary_start, witness_commitments.avm_binary_start); + transcript->send_to_verifier(commitment_labels.avm_byte_lookup_bin_sel, + witness_commitments.avm_byte_lookup_bin_sel); + transcript->send_to_verifier(commitment_labels.avm_byte_lookup_table_byte_lengths, witness_commitments.avm_byte_lookup_table_byte_lengths); - transcript->send_to_verifier(labels.avm_byte_lookup_table_in_tags, + transcript->send_to_verifier(commitment_labels.avm_byte_lookup_table_in_tags, witness_commitments.avm_byte_lookup_table_in_tags); - transcript->send_to_verifier(labels.avm_byte_lookup_table_input_a, + transcript->send_to_verifier(commitment_labels.avm_byte_lookup_table_input_a, witness_commitments.avm_byte_lookup_table_input_a); - transcript->send_to_verifier(labels.avm_byte_lookup_table_input_b, + transcript->send_to_verifier(commitment_labels.avm_byte_lookup_table_input_b, witness_commitments.avm_byte_lookup_table_input_b); - transcript->send_to_verifier(labels.avm_byte_lookup_table_op_id, witness_commitments.avm_byte_lookup_table_op_id); - transcript->send_to_verifier(labels.avm_byte_lookup_table_output, witness_commitments.avm_byte_lookup_table_output); - transcript->send_to_verifier(labels.avm_main_alu_sel, witness_commitments.avm_main_alu_sel); - transcript->send_to_verifier(labels.avm_main_bin_op_id, witness_commitments.avm_main_bin_op_id); - transcript->send_to_verifier(labels.avm_main_bin_sel, witness_commitments.avm_main_bin_sel); - transcript->send_to_verifier(labels.avm_main_ia, witness_commitments.avm_main_ia); - transcript->send_to_verifier(labels.avm_main_ib, witness_commitments.avm_main_ib); - transcript->send_to_verifier(labels.avm_main_ic, witness_commitments.avm_main_ic); - transcript->send_to_verifier(labels.avm_main_ind_a, witness_commitments.avm_main_ind_a); - transcript->send_to_verifier(labels.avm_main_ind_b, witness_commitments.avm_main_ind_b); - transcript->send_to_verifier(labels.avm_main_ind_c, witness_commitments.avm_main_ind_c); - transcript->send_to_verifier(labels.avm_main_ind_op_a, witness_commitments.avm_main_ind_op_a); - transcript->send_to_verifier(labels.avm_main_ind_op_b, witness_commitments.avm_main_ind_op_b); - transcript->send_to_verifier(labels.avm_main_ind_op_c, witness_commitments.avm_main_ind_op_c); - transcript->send_to_verifier(labels.avm_main_internal_return_ptr, witness_commitments.avm_main_internal_return_ptr); - transcript->send_to_verifier(labels.avm_main_inv, witness_commitments.avm_main_inv); - transcript->send_to_verifier(labels.avm_main_last, witness_commitments.avm_main_last); - transcript->send_to_verifier(labels.avm_main_mem_idx_a, witness_commitments.avm_main_mem_idx_a); - transcript->send_to_verifier(labels.avm_main_mem_idx_b, witness_commitments.avm_main_mem_idx_b); - transcript->send_to_verifier(labels.avm_main_mem_idx_c, witness_commitments.avm_main_mem_idx_c); - transcript->send_to_verifier(labels.avm_main_mem_op_a, witness_commitments.avm_main_mem_op_a); - transcript->send_to_verifier(labels.avm_main_mem_op_b, witness_commitments.avm_main_mem_op_b); - transcript->send_to_verifier(labels.avm_main_mem_op_c, witness_commitments.avm_main_mem_op_c); - transcript->send_to_verifier(labels.avm_main_op_err, witness_commitments.avm_main_op_err); - transcript->send_to_verifier(labels.avm_main_pc, witness_commitments.avm_main_pc); - transcript->send_to_verifier(labels.avm_main_r_in_tag, witness_commitments.avm_main_r_in_tag); - transcript->send_to_verifier(labels.avm_main_rwa, witness_commitments.avm_main_rwa); - transcript->send_to_verifier(labels.avm_main_rwb, witness_commitments.avm_main_rwb); - transcript->send_to_verifier(labels.avm_main_rwc, witness_commitments.avm_main_rwc); - transcript->send_to_verifier(labels.avm_main_sel_halt, witness_commitments.avm_main_sel_halt); - transcript->send_to_verifier(labels.avm_main_sel_internal_call, witness_commitments.avm_main_sel_internal_call); - transcript->send_to_verifier(labels.avm_main_sel_internal_return, witness_commitments.avm_main_sel_internal_return); - transcript->send_to_verifier(labels.avm_main_sel_jump, witness_commitments.avm_main_sel_jump); - transcript->send_to_verifier(labels.avm_main_sel_mov, witness_commitments.avm_main_sel_mov); - transcript->send_to_verifier(labels.avm_main_sel_op_add, witness_commitments.avm_main_sel_op_add); - transcript->send_to_verifier(labels.avm_main_sel_op_and, witness_commitments.avm_main_sel_op_and); - transcript->send_to_verifier(labels.avm_main_sel_op_div, witness_commitments.avm_main_sel_op_div); - transcript->send_to_verifier(labels.avm_main_sel_op_eq, witness_commitments.avm_main_sel_op_eq); - transcript->send_to_verifier(labels.avm_main_sel_op_mul, witness_commitments.avm_main_sel_op_mul); - transcript->send_to_verifier(labels.avm_main_sel_op_not, witness_commitments.avm_main_sel_op_not); - transcript->send_to_verifier(labels.avm_main_sel_op_or, witness_commitments.avm_main_sel_op_or); - transcript->send_to_verifier(labels.avm_main_sel_op_sub, witness_commitments.avm_main_sel_op_sub); - transcript->send_to_verifier(labels.avm_main_sel_op_xor, witness_commitments.avm_main_sel_op_xor); - transcript->send_to_verifier(labels.avm_main_sel_rng_16, witness_commitments.avm_main_sel_rng_16); - transcript->send_to_verifier(labels.avm_main_sel_rng_8, witness_commitments.avm_main_sel_rng_8); - transcript->send_to_verifier(labels.avm_main_tag_err, witness_commitments.avm_main_tag_err); - transcript->send_to_verifier(labels.avm_main_w_in_tag, witness_commitments.avm_main_w_in_tag); - transcript->send_to_verifier(labels.avm_mem_addr, witness_commitments.avm_mem_addr); - transcript->send_to_verifier(labels.avm_mem_clk, witness_commitments.avm_mem_clk); - transcript->send_to_verifier(labels.avm_mem_ind_op_a, witness_commitments.avm_mem_ind_op_a); - transcript->send_to_verifier(labels.avm_mem_ind_op_b, witness_commitments.avm_mem_ind_op_b); - transcript->send_to_verifier(labels.avm_mem_ind_op_c, witness_commitments.avm_mem_ind_op_c); - transcript->send_to_verifier(labels.avm_mem_last, witness_commitments.avm_mem_last); - transcript->send_to_verifier(labels.avm_mem_lastAccess, witness_commitments.avm_mem_lastAccess); - transcript->send_to_verifier(labels.avm_mem_one_min_inv, witness_commitments.avm_mem_one_min_inv); - transcript->send_to_verifier(labels.avm_mem_op_a, witness_commitments.avm_mem_op_a); - transcript->send_to_verifier(labels.avm_mem_op_b, witness_commitments.avm_mem_op_b); - transcript->send_to_verifier(labels.avm_mem_op_c, witness_commitments.avm_mem_op_c); - transcript->send_to_verifier(labels.avm_mem_r_in_tag, witness_commitments.avm_mem_r_in_tag); - transcript->send_to_verifier(labels.avm_mem_rw, witness_commitments.avm_mem_rw); - transcript->send_to_verifier(labels.avm_mem_sel_mov, witness_commitments.avm_mem_sel_mov); - transcript->send_to_verifier(labels.avm_mem_sub_clk, witness_commitments.avm_mem_sub_clk); - transcript->send_to_verifier(labels.avm_mem_tag, witness_commitments.avm_mem_tag); - transcript->send_to_verifier(labels.avm_mem_tag_err, witness_commitments.avm_mem_tag_err); - transcript->send_to_verifier(labels.avm_mem_val, witness_commitments.avm_mem_val); - transcript->send_to_verifier(labels.avm_mem_w_in_tag, witness_commitments.avm_mem_w_in_tag); - - // Lookup counts - transcript->send_to_verifier(labels.lookup_byte_lengths_counts, witness_commitments.lookup_byte_lengths_counts); - transcript->send_to_verifier(labels.lookup_byte_operations_counts, + transcript->send_to_verifier(commitment_labels.avm_byte_lookup_table_op_id, + witness_commitments.avm_byte_lookup_table_op_id); + transcript->send_to_verifier(commitment_labels.avm_byte_lookup_table_output, + witness_commitments.avm_byte_lookup_table_output); + transcript->send_to_verifier(commitment_labels.avm_main_alu_sel, witness_commitments.avm_main_alu_sel); + transcript->send_to_verifier(commitment_labels.avm_main_bin_op_id, witness_commitments.avm_main_bin_op_id); + transcript->send_to_verifier(commitment_labels.avm_main_bin_sel, witness_commitments.avm_main_bin_sel); + transcript->send_to_verifier(commitment_labels.avm_main_ia, witness_commitments.avm_main_ia); + transcript->send_to_verifier(commitment_labels.avm_main_ib, witness_commitments.avm_main_ib); + transcript->send_to_verifier(commitment_labels.avm_main_ic, witness_commitments.avm_main_ic); + transcript->send_to_verifier(commitment_labels.avm_main_ind_a, witness_commitments.avm_main_ind_a); + transcript->send_to_verifier(commitment_labels.avm_main_ind_b, witness_commitments.avm_main_ind_b); + transcript->send_to_verifier(commitment_labels.avm_main_ind_c, witness_commitments.avm_main_ind_c); + transcript->send_to_verifier(commitment_labels.avm_main_ind_op_a, witness_commitments.avm_main_ind_op_a); + transcript->send_to_verifier(commitment_labels.avm_main_ind_op_b, witness_commitments.avm_main_ind_op_b); + transcript->send_to_verifier(commitment_labels.avm_main_ind_op_c, witness_commitments.avm_main_ind_op_c); + transcript->send_to_verifier(commitment_labels.avm_main_internal_return_ptr, + witness_commitments.avm_main_internal_return_ptr); + transcript->send_to_verifier(commitment_labels.avm_main_inv, witness_commitments.avm_main_inv); + transcript->send_to_verifier(commitment_labels.avm_main_last, witness_commitments.avm_main_last); + transcript->send_to_verifier(commitment_labels.avm_main_mem_idx_a, witness_commitments.avm_main_mem_idx_a); + transcript->send_to_verifier(commitment_labels.avm_main_mem_idx_b, witness_commitments.avm_main_mem_idx_b); + transcript->send_to_verifier(commitment_labels.avm_main_mem_idx_c, witness_commitments.avm_main_mem_idx_c); + transcript->send_to_verifier(commitment_labels.avm_main_mem_op_a, witness_commitments.avm_main_mem_op_a); + transcript->send_to_verifier(commitment_labels.avm_main_mem_op_b, witness_commitments.avm_main_mem_op_b); + transcript->send_to_verifier(commitment_labels.avm_main_mem_op_c, witness_commitments.avm_main_mem_op_c); + transcript->send_to_verifier(commitment_labels.avm_main_op_err, witness_commitments.avm_main_op_err); + transcript->send_to_verifier(commitment_labels.avm_main_pc, witness_commitments.avm_main_pc); + transcript->send_to_verifier(commitment_labels.avm_main_r_in_tag, witness_commitments.avm_main_r_in_tag); + transcript->send_to_verifier(commitment_labels.avm_main_rwa, witness_commitments.avm_main_rwa); + transcript->send_to_verifier(commitment_labels.avm_main_rwb, witness_commitments.avm_main_rwb); + transcript->send_to_verifier(commitment_labels.avm_main_rwc, witness_commitments.avm_main_rwc); + transcript->send_to_verifier(commitment_labels.avm_main_sel_halt, witness_commitments.avm_main_sel_halt); + transcript->send_to_verifier(commitment_labels.avm_main_sel_internal_call, + witness_commitments.avm_main_sel_internal_call); + transcript->send_to_verifier(commitment_labels.avm_main_sel_internal_return, + witness_commitments.avm_main_sel_internal_return); + transcript->send_to_verifier(commitment_labels.avm_main_sel_jump, witness_commitments.avm_main_sel_jump); + transcript->send_to_verifier(commitment_labels.avm_main_sel_mov, witness_commitments.avm_main_sel_mov); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_add, witness_commitments.avm_main_sel_op_add); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_and, witness_commitments.avm_main_sel_op_and); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_div, witness_commitments.avm_main_sel_op_div); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_eq, witness_commitments.avm_main_sel_op_eq); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_lt, witness_commitments.avm_main_sel_op_lt); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_lte, witness_commitments.avm_main_sel_op_lte); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_mul, witness_commitments.avm_main_sel_op_mul); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_not, witness_commitments.avm_main_sel_op_not); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_or, witness_commitments.avm_main_sel_op_or); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_sub, witness_commitments.avm_main_sel_op_sub); + transcript->send_to_verifier(commitment_labels.avm_main_sel_op_xor, witness_commitments.avm_main_sel_op_xor); + transcript->send_to_verifier(commitment_labels.avm_main_sel_rng_16, witness_commitments.avm_main_sel_rng_16); + transcript->send_to_verifier(commitment_labels.avm_main_sel_rng_8, witness_commitments.avm_main_sel_rng_8); + transcript->send_to_verifier(commitment_labels.avm_main_tag_err, witness_commitments.avm_main_tag_err); + 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_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_last, witness_commitments.avm_mem_last); + transcript->send_to_verifier(commitment_labels.avm_mem_lastAccess, witness_commitments.avm_mem_lastAccess); + transcript->send_to_verifier(commitment_labels.avm_mem_one_min_inv, witness_commitments.avm_mem_one_min_inv); + transcript->send_to_verifier(commitment_labels.avm_mem_op_a, witness_commitments.avm_mem_op_a); + transcript->send_to_verifier(commitment_labels.avm_mem_op_b, witness_commitments.avm_mem_op_b); + transcript->send_to_verifier(commitment_labels.avm_mem_op_c, witness_commitments.avm_mem_op_c); + transcript->send_to_verifier(commitment_labels.avm_mem_r_in_tag, witness_commitments.avm_mem_r_in_tag); + transcript->send_to_verifier(commitment_labels.avm_mem_rw, witness_commitments.avm_mem_rw); + transcript->send_to_verifier(commitment_labels.avm_mem_sel_mov, witness_commitments.avm_mem_sel_mov); + transcript->send_to_verifier(commitment_labels.avm_mem_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_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, + witness_commitments.lookup_byte_lengths_counts); + transcript->send_to_verifier(commitment_labels.lookup_byte_operations_counts, witness_commitments.lookup_byte_operations_counts); - transcript->send_to_verifier(labels.incl_main_tag_err_counts, witness_commitments.incl_main_tag_err_counts); - transcript->send_to_verifier(labels.incl_mem_tag_err_counts, witness_commitments.incl_mem_tag_err_counts); + transcript->send_to_verifier(commitment_labels.incl_main_tag_err_counts, + 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_u8_0_counts, witness_commitments.lookup_u8_0_counts); + transcript->send_to_verifier(commitment_labels.lookup_u8_1_counts, witness_commitments.lookup_u8_1_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_0_counts, witness_commitments.lookup_u16_0_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_1_counts, witness_commitments.lookup_u16_1_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_2_counts, witness_commitments.lookup_u16_2_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_3_counts, witness_commitments.lookup_u16_3_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_4_counts, witness_commitments.lookup_u16_4_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_5_counts, witness_commitments.lookup_u16_5_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_6_counts, witness_commitments.lookup_u16_6_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_7_counts, witness_commitments.lookup_u16_7_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_8_counts, witness_commitments.lookup_u16_8_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_9_counts, witness_commitments.lookup_u16_9_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_10_counts, witness_commitments.lookup_u16_10_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_11_counts, witness_commitments.lookup_u16_11_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_12_counts, witness_commitments.lookup_u16_12_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_13_counts, witness_commitments.lookup_u16_13_counts); + transcript->send_to_verifier(commitment_labels.lookup_u16_14_counts, witness_commitments.lookup_u16_14_counts); } void AvmProver::execute_log_derivative_inverse_round() { - auto [beta, gamma] = transcript->template get_challenges("beta", "gamma"); + auto [beta, gamm] = transcript->template get_challenges("beta", "gamma"); relation_parameters.beta = beta; - relation_parameters.gamma = gamma; + relation_parameters.gamma = gamm; key->compute_logderivative_inverses(relation_parameters); - // Permutations + // Commit to all logderivative inverse polynomials witness_commitments.perm_main_alu = commitment_key->commit(key->perm_main_alu); witness_commitments.perm_main_bin = commitment_key->commit(key->perm_main_bin); witness_commitments.perm_main_mem_a = commitment_key->commit(key->perm_main_mem_a); @@ -345,26 +426,58 @@ void AvmProver::execute_log_derivative_inverse_round() witness_commitments.perm_main_mem_ind_a = commitment_key->commit(key->perm_main_mem_ind_a); witness_commitments.perm_main_mem_ind_b = commitment_key->commit(key->perm_main_mem_ind_b); witness_commitments.perm_main_mem_ind_c = commitment_key->commit(key->perm_main_mem_ind_c); - // Lookups - 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_byte_lengths = commitment_key->commit(key->lookup_byte_lengths); witness_commitments.lookup_byte_operations = commitment_key->commit(key->lookup_byte_operations); - - // Perms + 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_u8_0 = commitment_key->commit(key->lookup_u8_0); + witness_commitments.lookup_u8_1 = commitment_key->commit(key->lookup_u8_1); + witness_commitments.lookup_u16_0 = commitment_key->commit(key->lookup_u16_0); + witness_commitments.lookup_u16_1 = commitment_key->commit(key->lookup_u16_1); + witness_commitments.lookup_u16_2 = commitment_key->commit(key->lookup_u16_2); + witness_commitments.lookup_u16_3 = commitment_key->commit(key->lookup_u16_3); + witness_commitments.lookup_u16_4 = commitment_key->commit(key->lookup_u16_4); + witness_commitments.lookup_u16_5 = commitment_key->commit(key->lookup_u16_5); + witness_commitments.lookup_u16_6 = commitment_key->commit(key->lookup_u16_6); + witness_commitments.lookup_u16_7 = commitment_key->commit(key->lookup_u16_7); + witness_commitments.lookup_u16_8 = commitment_key->commit(key->lookup_u16_8); + witness_commitments.lookup_u16_9 = commitment_key->commit(key->lookup_u16_9); + witness_commitments.lookup_u16_10 = commitment_key->commit(key->lookup_u16_10); + witness_commitments.lookup_u16_11 = commitment_key->commit(key->lookup_u16_11); + witness_commitments.lookup_u16_12 = commitment_key->commit(key->lookup_u16_12); + witness_commitments.lookup_u16_13 = commitment_key->commit(key->lookup_u16_13); + witness_commitments.lookup_u16_14 = commitment_key->commit(key->lookup_u16_14); + + // Send all commitments to the verifier transcript->send_to_verifier(commitment_labels.perm_main_alu, witness_commitments.perm_main_alu); transcript->send_to_verifier(commitment_labels.perm_main_bin, witness_commitments.perm_main_bin); transcript->send_to_verifier(commitment_labels.perm_main_mem_a, witness_commitments.perm_main_mem_a); transcript->send_to_verifier(commitment_labels.perm_main_mem_b, witness_commitments.perm_main_mem_b); - transcript->send_to_verifier(commitment_labels.perm_main_mem_c, witness_commitments.perm_main_mem_b); + transcript->send_to_verifier(commitment_labels.perm_main_mem_c, witness_commitments.perm_main_mem_c); transcript->send_to_verifier(commitment_labels.perm_main_mem_ind_a, witness_commitments.perm_main_mem_ind_a); transcript->send_to_verifier(commitment_labels.perm_main_mem_ind_b, witness_commitments.perm_main_mem_ind_b); transcript->send_to_verifier(commitment_labels.perm_main_mem_ind_c, witness_commitments.perm_main_mem_ind_c); - // Lookups - 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_byte_lengths, witness_commitments.lookup_byte_lengths); transcript->send_to_verifier(commitment_labels.lookup_byte_operations, witness_commitments.lookup_byte_operations); + transcript->send_to_verifier(commitment_labels.incl_main_tag_err, witness_commitments.incl_main_tag_err); + transcript->send_to_verifier(commitment_labels.incl_mem_tag_err, witness_commitments.incl_mem_tag_err); + transcript->send_to_verifier(commitment_labels.lookup_u8_0, witness_commitments.lookup_u8_0); + transcript->send_to_verifier(commitment_labels.lookup_u8_1, witness_commitments.lookup_u8_1); + transcript->send_to_verifier(commitment_labels.lookup_u16_0, witness_commitments.lookup_u16_0); + transcript->send_to_verifier(commitment_labels.lookup_u16_1, witness_commitments.lookup_u16_1); + transcript->send_to_verifier(commitment_labels.lookup_u16_2, witness_commitments.lookup_u16_2); + transcript->send_to_verifier(commitment_labels.lookup_u16_3, witness_commitments.lookup_u16_3); + transcript->send_to_verifier(commitment_labels.lookup_u16_4, witness_commitments.lookup_u16_4); + transcript->send_to_verifier(commitment_labels.lookup_u16_5, witness_commitments.lookup_u16_5); + transcript->send_to_verifier(commitment_labels.lookup_u16_6, witness_commitments.lookup_u16_6); + transcript->send_to_verifier(commitment_labels.lookup_u16_7, witness_commitments.lookup_u16_7); + transcript->send_to_verifier(commitment_labels.lookup_u16_8, witness_commitments.lookup_u16_8); + transcript->send_to_verifier(commitment_labels.lookup_u16_9, witness_commitments.lookup_u16_9); + transcript->send_to_verifier(commitment_labels.lookup_u16_10, witness_commitments.lookup_u16_10); + transcript->send_to_verifier(commitment_labels.lookup_u16_11, witness_commitments.lookup_u16_11); + transcript->send_to_verifier(commitment_labels.lookup_u16_12, witness_commitments.lookup_u16_12); + transcript->send_to_verifier(commitment_labels.lookup_u16_13, witness_commitments.lookup_u16_13); + transcript->send_to_verifier(commitment_labels.lookup_u16_14, witness_commitments.lookup_u16_14); } /** @@ -417,7 +530,6 @@ HonkProof& AvmProver::construct_proof() execute_wire_commitments_round(); // Compute sorted list accumulator and commitment - // Fiat-Shamir: bbeta & gamma execute_log_derivative_inverse_round(); // Fiat-Shamir: alpha diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp index 75b85125615..aabdf2c2d6b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/avm_verifier.cpp @@ -51,10 +51,19 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) } // Get commitments to VM wires + commitments.avm_alu_a_hi = transcript->template receive_from_prover(commitment_labels.avm_alu_a_hi); + commitments.avm_alu_a_lo = transcript->template receive_from_prover(commitment_labels.avm_alu_a_lo); commitments.avm_alu_alu_sel = transcript->template receive_from_prover(commitment_labels.avm_alu_alu_sel); + commitments.avm_alu_b_hi = transcript->template receive_from_prover(commitment_labels.avm_alu_b_hi); + commitments.avm_alu_b_lo = transcript->template receive_from_prover(commitment_labels.avm_alu_b_lo); + commitments.avm_alu_borrow = transcript->template receive_from_prover(commitment_labels.avm_alu_borrow); commitments.avm_alu_cf = transcript->template receive_from_prover(commitment_labels.avm_alu_cf); commitments.avm_alu_clk = transcript->template receive_from_prover(commitment_labels.avm_alu_clk); + commitments.avm_alu_cmp_rng_ctr = + transcript->template receive_from_prover(commitment_labels.avm_alu_cmp_rng_ctr); + commitments.avm_alu_cmp_sel = + transcript->template receive_from_prover(commitment_labels.avm_alu_cmp_sel); commitments.avm_alu_ff_tag = transcript->template receive_from_prover(commitment_labels.avm_alu_ff_tag); commitments.avm_alu_ia = transcript->template receive_from_prover(commitment_labels.avm_alu_ia); commitments.avm_alu_ib = transcript->template receive_from_prover(commitment_labels.avm_alu_ib); @@ -65,9 +74,29 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) commitments.avm_alu_op_eq = transcript->template receive_from_prover(commitment_labels.avm_alu_op_eq); commitments.avm_alu_op_eq_diff_inv = transcript->template receive_from_prover(commitment_labels.avm_alu_op_eq_diff_inv); + commitments.avm_alu_op_lt = transcript->template receive_from_prover(commitment_labels.avm_alu_op_lt); + commitments.avm_alu_op_lte = transcript->template receive_from_prover(commitment_labels.avm_alu_op_lte); commitments.avm_alu_op_mul = transcript->template receive_from_prover(commitment_labels.avm_alu_op_mul); commitments.avm_alu_op_not = transcript->template receive_from_prover(commitment_labels.avm_alu_op_not); commitments.avm_alu_op_sub = transcript->template receive_from_prover(commitment_labels.avm_alu_op_sub); + commitments.avm_alu_p_a_borrow = + transcript->template receive_from_prover(commitment_labels.avm_alu_p_a_borrow); + commitments.avm_alu_p_b_borrow = + transcript->template receive_from_prover(commitment_labels.avm_alu_p_b_borrow); + commitments.avm_alu_p_sub_a_hi = + transcript->template receive_from_prover(commitment_labels.avm_alu_p_sub_a_hi); + commitments.avm_alu_p_sub_a_lo = + transcript->template receive_from_prover(commitment_labels.avm_alu_p_sub_a_lo); + commitments.avm_alu_p_sub_b_hi = + transcript->template receive_from_prover(commitment_labels.avm_alu_p_sub_b_hi); + commitments.avm_alu_p_sub_b_lo = + transcript->template receive_from_prover(commitment_labels.avm_alu_p_sub_b_lo); + commitments.avm_alu_res_hi = transcript->template receive_from_prover(commitment_labels.avm_alu_res_hi); + commitments.avm_alu_res_lo = transcript->template receive_from_prover(commitment_labels.avm_alu_res_lo); + commitments.avm_alu_rng_chk_lookup_selector = + transcript->template receive_from_prover(commitment_labels.avm_alu_rng_chk_lookup_selector); + commitments.avm_alu_rng_chk_sel = + transcript->template receive_from_prover(commitment_labels.avm_alu_rng_chk_sel); commitments.avm_alu_u128_tag = transcript->template receive_from_prover(commitment_labels.avm_alu_u128_tag); commitments.avm_alu_u16_r0 = transcript->template receive_from_prover(commitment_labels.avm_alu_u16_r0); @@ -199,6 +228,10 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_div); commitments.avm_main_sel_op_eq = transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_eq); + commitments.avm_main_sel_op_lt = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_lt); + commitments.avm_main_sel_op_lte = + transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_lte); commitments.avm_main_sel_op_mul = transcript->template receive_from_prover(commitment_labels.avm_main_sel_op_mul); commitments.avm_main_sel_op_not = @@ -246,8 +279,6 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) 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); - - // Lookup counts commitments.lookup_byte_lengths_counts = transcript->template receive_from_prover(commitment_labels.lookup_byte_lengths_counts); commitments.lookup_byte_operations_counts = @@ -256,13 +287,46 @@ 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_u8_0_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u8_0_counts); + commitments.lookup_u8_1_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u8_1_counts); + commitments.lookup_u16_0_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_0_counts); + commitments.lookup_u16_1_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_1_counts); + commitments.lookup_u16_2_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_2_counts); + commitments.lookup_u16_3_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_3_counts); + commitments.lookup_u16_4_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_4_counts); + commitments.lookup_u16_5_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_5_counts); + commitments.lookup_u16_6_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_6_counts); + commitments.lookup_u16_7_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_7_counts); + commitments.lookup_u16_8_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_8_counts); + commitments.lookup_u16_9_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_9_counts); + commitments.lookup_u16_10_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_10_counts); + commitments.lookup_u16_11_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_11_counts); + commitments.lookup_u16_12_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_12_counts); + commitments.lookup_u16_13_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_13_counts); + commitments.lookup_u16_14_counts = + transcript->template receive_from_prover(commitment_labels.lookup_u16_14_counts); - // Calculate the alpha and beta challenges - log derivative inverse round auto [beta, gamm] = transcript->template get_challenges("beta", "gamma"); relation_parameters.beta = beta; relation_parameters.gamma = gamm; - // Permutations + // Get commitments to inverses commitments.perm_main_alu = transcript->template receive_from_prover(commitment_labels.perm_main_alu); commitments.perm_main_bin = transcript->template receive_from_prover(commitment_labels.perm_main_bin); commitments.perm_main_mem_a = @@ -277,8 +341,6 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) transcript->template receive_from_prover(commitment_labels.perm_main_mem_ind_b); commitments.perm_main_mem_ind_c = transcript->template receive_from_prover(commitment_labels.perm_main_mem_ind_c); - - // Lookups commitments.lookup_byte_lengths = transcript->template receive_from_prover(commitment_labels.lookup_byte_lengths); commitments.lookup_byte_operations = @@ -287,6 +349,23 @@ 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_u8_0 = transcript->template receive_from_prover(commitment_labels.lookup_u8_0); + commitments.lookup_u8_1 = transcript->template receive_from_prover(commitment_labels.lookup_u8_1); + commitments.lookup_u16_0 = transcript->template receive_from_prover(commitment_labels.lookup_u16_0); + commitments.lookup_u16_1 = transcript->template receive_from_prover(commitment_labels.lookup_u16_1); + commitments.lookup_u16_2 = transcript->template receive_from_prover(commitment_labels.lookup_u16_2); + commitments.lookup_u16_3 = transcript->template receive_from_prover(commitment_labels.lookup_u16_3); + commitments.lookup_u16_4 = transcript->template receive_from_prover(commitment_labels.lookup_u16_4); + commitments.lookup_u16_5 = transcript->template receive_from_prover(commitment_labels.lookup_u16_5); + commitments.lookup_u16_6 = transcript->template receive_from_prover(commitment_labels.lookup_u16_6); + commitments.lookup_u16_7 = transcript->template receive_from_prover(commitment_labels.lookup_u16_7); + commitments.lookup_u16_8 = transcript->template receive_from_prover(commitment_labels.lookup_u16_8); + commitments.lookup_u16_9 = transcript->template receive_from_prover(commitment_labels.lookup_u16_9); + commitments.lookup_u16_10 = transcript->template receive_from_prover(commitment_labels.lookup_u16_10); + commitments.lookup_u16_11 = transcript->template receive_from_prover(commitment_labels.lookup_u16_11); + commitments.lookup_u16_12 = transcript->template receive_from_prover(commitment_labels.lookup_u16_12); + commitments.lookup_u16_13 = transcript->template receive_from_prover(commitment_labels.lookup_u16_13); + commitments.lookup_u16_14 = transcript->template receive_from_prover(commitment_labels.lookup_u16_14); // Execute Sumcheck Verifier const size_t log_circuit_size = numeric::get_msb(circuit_size); @@ -304,7 +383,6 @@ bool AvmVerifier::verify_proof(const HonkProof& proof) // If Sumcheck did not verify, return false if (sumcheck_verified.has_value() && !sumcheck_verified.value()) { - info("Sumcheck did not verify"); return false; } 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 3c51f5b7199..d0dceddcb1a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_arithmetic.test.cpp @@ -1828,7 +1828,7 @@ TEST_F(AvmArithmeticNegativeTestsFF, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->avm_main_w_in_tag = FF(4); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "EQ_OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); } // Tests a situation for field elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -1896,7 +1896,7 @@ TEST_F(AvmArithmeticNegativeTestsU8, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->avm_main_w_in_tag = FF(3); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "EQ_OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); } // Tests a situation for U8 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -1963,7 +1963,7 @@ TEST_F(AvmArithmeticNegativeTestsU16, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->avm_main_w_in_tag = FF(5); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "EQ_OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); } // Tests a situation for U16 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -2030,7 +2030,7 @@ TEST_F(AvmArithmeticNegativeTestsU32, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->avm_main_w_in_tag = FF(6); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "EQ_OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); } // Tests a situation for U32 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -2104,7 +2104,7 @@ TEST_F(AvmArithmeticNegativeTestsU64, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->avm_main_w_in_tag = FF(2); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "EQ_OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); } // Tests a situation for U64 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -2203,7 +2203,7 @@ TEST_F(AvmArithmeticNegativeTestsU128, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->avm_main_w_in_tag = FF(4); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "EQ_OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); } // Tests a situation for U128 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/avm_comparison.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/avm_comparison.test.cpp new file mode 100644 index 00000000000..ea50cc468a0 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/vm/tests/avm_comparison.test.cpp @@ -0,0 +1,346 @@ +#include "avm_common.test.hpp" +#include "barretenberg/common/zip_view.hpp" +#include "barretenberg/numeric/uint128/uint128.hpp" +#include "barretenberg/vm/avm_trace/avm_common.hpp" +#include "barretenberg/vm/tests/helpers.test.hpp" +#include "gtest/gtest.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace tests_avm { +using namespace bb::avm_trace; +namespace { + +void common_validate_cmp(Row const& row, + Row const& alu_row, + FF const& a, + FF const& b, + FF const& c, + FF const& addr_a, + FF const& addr_b, + FF const& addr_c, + avm_trace::AvmMemoryTag const tag) +{ + + // Use the row in the main trace to find the same operation in the alu trace. + // Check that the correct result is stored at the expected memory location. + EXPECT_EQ(row.avm_main_ic, c); + EXPECT_EQ(row.avm_main_mem_idx_c, addr_c); + EXPECT_EQ(row.avm_main_mem_op_c, FF(1)); + EXPECT_EQ(row.avm_main_rwc, FF(1)); + + // Check that ia register is correctly set with memory load operations. + EXPECT_EQ(row.avm_main_ia, a); + EXPECT_EQ(row.avm_main_mem_idx_a, addr_a); + EXPECT_EQ(row.avm_main_mem_op_a, FF(1)); + EXPECT_EQ(row.avm_main_rwa, FF(0)); + + // Check that ib register is correctly set with memory load operations. + EXPECT_EQ(row.avm_main_ib, b); + EXPECT_EQ(row.avm_main_mem_idx_b, addr_b); + EXPECT_EQ(row.avm_main_mem_op_b, FF(1)); + EXPECT_EQ(row.avm_main_rwb, FF(0)); + + // Check the instruction tags + EXPECT_EQ(row.avm_main_r_in_tag, FF(static_cast(tag))); + EXPECT_EQ(row.avm_main_w_in_tag, FF(static_cast(AvmMemoryTag::U8))); + + // Check that intermediate registers are correctly copied in Alu trace + EXPECT_EQ(alu_row.avm_alu_ia, a); + EXPECT_EQ(alu_row.avm_alu_ib, b); + EXPECT_EQ(alu_row.avm_alu_ic, c); +} +} // namespace +using ThreeOpParam = std::array; +using ThreeOpParamRow = std::tuple; +std::vector positive_op_lt_test_values = { { { FF(1), FF(1), FF(0) }, + { FF(5323), FF(321), FF(0) }, + { FF(13793), FF(10590617LLU), FF(1) }, + { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), FF(0) }, + { FF(uint256_t{ 0xb900000000000001 }), + FF(uint256_t{ 0x1006021301080000 } << 64) + + uint256_t{ 0x000000000000001080876844827 }, + 1 } } }; +std::vector positive_op_lte_test_values = { + { { FF(1), FF(1), FF(1) }, + { FF(5323), FF(321), FF(0) }, + { FF(13793), FF(10590617LLU), FF(1) }, + { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), FF(0) }, + { FF(uint256_t{ 0x1006021301080000 } << 64) + uint256_t{ 0x000000000000001080876844827 }, + FF(uint256_t{ 0x1006021301080000 } << 64) + uint256_t{ 0x000000000000001080876844827 }, + FF(1) } } +}; + +std::vector gen_three_op_params(std::vector operands, + std::vector mem_tag_arr) +{ + std::vector params; + for (size_t i = 0; i < 5; i++) { + params.emplace_back(operands[i], mem_tag_arr[i]); + } + return params; +} +std::vector mem_tag_arr{ + { AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } +}; +class AvmCmpTests : public ::testing::Test { + public: + AvmTraceBuilder trace_builder; + + protected: + // TODO(640): The Standard Honk on Grumpkin test suite fails unless the SRS is initialised for every test. + void SetUp() override { srs::init_crs_factory("../srs_db/ignition"); }; +}; +class AvmCmpTestsLT : public AvmCmpTests, public testing::WithParamInterface {}; +class AvmCmpTestsLTE : public AvmCmpTests, public testing::WithParamInterface {}; + +/****************************************************************************** + * + * POSITIVE TESTS + * + ******************************************************************************/ +TEST_P(AvmCmpTestsLT, ParamTest) +{ + const auto [params, mem_tag] = GetParam(); + const auto [a, b, c] = params; + if (mem_tag == AvmMemoryTag::FF) { + trace_builder.calldata_copy(0, 0, 2, 0, std::vector{ a, b }); + } else { + trace_builder.op_set(0, uint128_t(a), 0, mem_tag); + trace_builder.op_set(0, uint128_t(b), 1, mem_tag); + } + trace_builder.op_lt(0, 0, 1, 2, mem_tag); + trace_builder.return_op(0, 0, 0); + auto trace = trace_builder.finalize(); + + // Get the row in the avm with the LT selector set + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_lt == FF(1); }); + + // Use the row in the main trace to find the same operation in the alu trace. + FF clk = row->avm_main_clk; + auto alu_row = std::ranges::find_if( + trace.begin(), trace.end(), [clk](Row r) { return r.avm_alu_clk == clk && r.avm_alu_op_lt == FF(1); }); + // Check that both rows were found + ASSERT_TRUE(row != trace.end()); + ASSERT_TRUE(alu_row != trace.end()); + common_validate_cmp(*row, *alu_row, a, b, c, FF(0), FF(1), FF(2), mem_tag); + + validate_trace_proof(std::move(trace)); +} +INSTANTIATE_TEST_SUITE_P(AvmCmpTests, + AvmCmpTestsLT, + testing::ValuesIn(gen_three_op_params(positive_op_lt_test_values, mem_tag_arr))); + +TEST_P(AvmCmpTestsLTE, ParamTest) +{ + const auto [params, mem_tag] = GetParam(); + const auto [a, b, c] = params; + if (mem_tag == AvmMemoryTag::FF) { + trace_builder.calldata_copy(0, 0, 2, 0, std::vector{ a, b }); + } else { + trace_builder.op_set(0, uint128_t(a), 0, mem_tag); + trace_builder.op_set(0, uint128_t(b), 1, mem_tag); + } + trace_builder.op_lte(0, 0, 1, 2, mem_tag); + trace_builder.return_op(0, 0, 0); + auto trace = trace_builder.finalize(); + auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_main_sel_op_lte == FF(1); }); + + // Use the row in the main trace to find the same operation in the alu trace. + FF clk = row->avm_main_clk; + auto alu_row = std::ranges::find_if( + trace.begin(), trace.end(), [clk](Row r) { return r.avm_alu_clk == clk && r.avm_alu_op_lte; }); + // Check that both rows were found + ASSERT_TRUE(row != trace.end()); + ASSERT_TRUE(alu_row != trace.end()); + common_validate_cmp(*row, *alu_row, a, b, c, FF(0), FF(1), FF(2), mem_tag); + validate_trace_proof(std::move(trace)); +} +INSTANTIATE_TEST_SUITE_P(AvmCmpTests, + AvmCmpTestsLTE, + testing::ValuesIn(gen_three_op_params(positive_op_lte_test_values, mem_tag_arr))); + +/****************************************************************************** + * + * NEGATIVE TESTS + * + ******************************************************************************/ +enum CMP_FAILURES { + IncorrectInputDecomposition, + SubLoCheckFailed, + ResLoCheckFailed, + ResHiCheckFailed, + CounterRelationFailed, + CounterNonZeroCheckFailed, + ShiftRelationFailed, + RangeCheckFailed, +}; +std::vector> cmp_failures = { + { "INPUT_DECOMP_1", CMP_FAILURES::IncorrectInputDecomposition }, + { "SUB_LO_1", CMP_FAILURES::SubLoCheckFailed }, + { "RES_LO", CMP_FAILURES::ResLoCheckFailed }, + { "RES_HI", CMP_FAILURES::ResHiCheckFailed }, + { "CMP_CTR_REL_2", CMP_FAILURES::CounterRelationFailed }, + { "CTR_NON_ZERO_REL", CMP_FAILURES::CounterNonZeroCheckFailed }, + { "SHIFT_RELS_0", CMP_FAILURES::ShiftRelationFailed }, + { "LOOKUP_U16_0", CMP_FAILURES::RangeCheckFailed }, + +}; +std::vector neg_test_lt = { { FF::modulus - 1, FF::modulus_minus_two, 0 } }; +std::vector neg_test_lte = { { FF::modulus - 1, FF::modulus - 1, 0 } }; + +using EXPECTED_ERRORS = std::tuple; + +std::vector gen_mutated_trace_cmp( + std::vector trace, std::function select_row, FF c_mutated, CMP_FAILURES fail_mode, bool is_lte) +{ + auto main_trace_row = std::ranges::find_if(trace.begin(), trace.end(), select_row); + auto main_clk = main_trace_row->avm_main_clk; + // The corresponding row in the alu trace as well as the row where start = 1 + auto alu_row = + std::ranges::find_if(trace.begin(), trace.end(), [main_clk](Row r) { return r.avm_alu_clk == main_clk; }); + // The corresponding row in the alu trace where the computation ends. + auto range_check_row = + std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avm_alu_cmp_rng_ctr > FF(0); }); + switch (fail_mode) { + case IncorrectInputDecomposition: + alu_row->avm_alu_a_lo = alu_row->avm_alu_a_lo + FF(1); + break; + case SubLoCheckFailed: + alu_row->avm_alu_p_a_borrow = FF::one() - alu_row->avm_alu_p_a_borrow; + break; + case ResLoCheckFailed: + alu_row->avm_alu_res_lo = alu_row->avm_alu_res_lo - FF(1); + break; + case ResHiCheckFailed: + alu_row->avm_alu_res_hi = FF(1); + break; + case CounterRelationFailed: + range_check_row->avm_alu_cmp_rng_ctr = FF(0); + break; + case CounterNonZeroCheckFailed: + range_check_row->avm_alu_rng_chk_sel = FF(0); + break; + case ShiftRelationFailed: + range_check_row->avm_alu_a_lo = range_check_row->avm_alu_res_lo; + range_check_row->avm_alu_a_hi = range_check_row->avm_alu_res_hi; + break; + case RangeCheckFailed: // Canonicalisation check failure + // TODO: We can probably refactor this to another function later as it is a bit verbose + // and we'll probably use it repeatedly for other range check test. + + // The range check fails in the context of the cmp operation if we set the boolean + // result in ic to be incorrect. + // Here we falsely claim LT(12,023, 439,321, 0). i.e. 12023 < 439321 is false. + mutate_ic_in_trace(trace, std::move(select_row), c_mutated, true); + + // Now we have to also update the value of res_lo = (A_SUB_B_LO * IS_GT + B_SUB_A_LO * (1 - IS_GT)) + alu_row->avm_alu_borrow = FF(0); + FF mutated_res_lo = + alu_row->avm_alu_b_lo - alu_row->avm_alu_a_lo + alu_row->avm_alu_borrow * (uint256_t(1) << 128); + FF mutated_res_hi = alu_row->avm_alu_b_hi - alu_row->avm_alu_a_hi - alu_row->avm_alu_borrow; + + if (is_lte) { + mutated_res_lo = alu_row->avm_alu_a_lo - alu_row->avm_alu_b_lo - FF::one() + + alu_row->avm_alu_borrow * (uint256_t(1) << 128); + mutated_res_hi = alu_row->avm_alu_a_hi - alu_row->avm_alu_b_hi - alu_row->avm_alu_borrow; + } + alu_row->avm_alu_res_lo = mutated_res_lo; + alu_row->avm_alu_res_hi = mutated_res_hi; + // For each subsequent row that involve the range check, we need to update the shifted values + auto next_row = alu_row + 1; + next_row->avm_alu_p_sub_b_lo = mutated_res_lo; + next_row->avm_alu_p_sub_b_hi = mutated_res_hi; + + next_row = alu_row + 2; + next_row->avm_alu_p_sub_a_lo = mutated_res_lo; + next_row->avm_alu_p_sub_a_hi = mutated_res_hi; + next_row = alu_row + 3; + + next_row->avm_alu_b_lo = mutated_res_lo; + next_row->avm_alu_b_hi = mutated_res_hi; + + // The final row contains the mutated res_x values at the a_x slots that will be range check. + auto final_row = alu_row + 4; + // To prevent a trivial range check failure, we need to clear the lookup counters for the + // current value of res_lo stored in a_lo + clear_range_check_counters(trace, final_row->avm_alu_a_lo); + final_row->avm_alu_a_lo = mutated_res_lo; + final_row->avm_alu_a_hi = mutated_res_hi; + + uint256_t mutated_res_lo_u256 = mutated_res_lo; + // We update range check lookup counters and the registers here + + // Assign the new u8 value that goes into the first slice register. + final_row->avm_alu_u8_r0 = static_cast(mutated_res_lo_u256); + // Find the main row where the new u8 value in the first register WILL be looked up + auto new_lookup_row = std::ranges::find_if(trace.begin(), trace.end(), [final_row](Row r) { + return r.avm_main_clk == final_row->avm_alu_u8_r0 && r.avm_main_sel_rng_8 == FF(1); + }); + // Increment the counter + new_lookup_row->lookup_u8_0_counts = new_lookup_row->lookup_u8_0_counts + 1; + mutated_res_lo_u256 >>= 8; + + // Assign the new u8 value that goes into the second slice register. + final_row->avm_alu_u8_r1 = static_cast(mutated_res_lo_u256); + new_lookup_row = std::ranges::find_if(trace.begin(), trace.end(), [final_row](Row r) { + return r.avm_main_clk == final_row->avm_alu_u8_r1 && r.avm_main_sel_rng_8 == FF(1); + }); + new_lookup_row->lookup_u8_1_counts = new_lookup_row->lookup_u8_1_counts + 1; + mutated_res_lo_u256 >>= 8; + + // Set the remaining bits (that are > 16) to the first u16 register to trigger the overflow + final_row->avm_alu_u16_r0 = mutated_res_lo_u256; + + break; + } + return trace; +} +class AvmCmpNegativeTestsLT : public AvmCmpTests, + public testing::WithParamInterface> {}; +class AvmCmpNegativeTestsLTE : public AvmCmpTests, + public testing::WithParamInterface> {}; + +TEST_P(AvmCmpNegativeTestsLT, ParamTest) +{ + const auto [failure, params] = GetParam(); + const auto [failure_string, failure_mode] = failure; + const auto [a, b, output] = params; + auto trace_builder = avm_trace::AvmTraceBuilder(); + trace_builder.calldata_copy(0, 0, 3, 0, std::vector{ a, b, output }); + trace_builder.op_lt(0, 0, 1, 2, AvmMemoryTag::FF); + trace_builder.return_op(0, 0, 0); + auto trace = trace_builder.finalize(); + std::function select_row = [](Row r) { return r.avm_main_sel_op_lt == FF(1); }; + trace = gen_mutated_trace_cmp(trace, select_row, output, failure_mode, false); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), failure_string); +} + +INSTANTIATE_TEST_SUITE_P(AvmCmpNegativeTests, + AvmCmpNegativeTestsLT, + testing::Combine(testing::ValuesIn(cmp_failures), testing::ValuesIn(neg_test_lt))); + +TEST_P(AvmCmpNegativeTestsLTE, ParamTest) +{ + const auto [failure, params] = GetParam(); + const auto [failure_string, failure_mode] = failure; + const auto [a, b, output] = params; + auto trace_builder = avm_trace::AvmTraceBuilder(); + trace_builder.calldata_copy(0, 0, 3, 0, std::vector{ a, b, output }); + trace_builder.op_lte(0, 0, 1, 2, AvmMemoryTag::FF); + trace_builder.return_op(0, 0, 0); + auto trace = trace_builder.finalize(); + std::function select_row = [](Row r) { return r.avm_main_sel_op_lte == FF(1); }; + trace = gen_mutated_trace_cmp(trace, select_row, output, failure_mode, true); + EXPECT_THROW_WITH_MESSAGE(validate_trace_proof(std::move(trace)), failure_string); +} +INSTANTIATE_TEST_SUITE_P(AvmCmpNegativeTests, + AvmCmpNegativeTestsLTE, + testing::Combine(testing::ValuesIn(cmp_failures), testing::ValuesIn(neg_test_lte))); +} // namespace tests_avm diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp index 11f69780a32..c91374202df 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.cpp @@ -77,4 +77,110 @@ void mutate_ic_in_trace(std::vector& trace, std::function&& sele EXPECT_TRUE(mem_row != trace.end()); mem_row->avm_mem_val = newValue; }; + +// TODO: There has to be a better way to do. +// This is a helper function to clear the range check counters associated with the alu register decomposition of +// "previous_value" so we don't trigger a trivial range_check count error +void clear_range_check_counters(std::vector& trace, uint256_t previous_value) +{ + // Find the main row where the old u8 value in the first register is looked up + size_t lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u8_0_counts = trace.at(lookup_value + 1).lookup_u8_0_counts - 1; + previous_value >>= 8; + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u8_1_counts = trace.at(lookup_value + 1).lookup_u8_1_counts - 1; + previous_value >>= 8; + + // U_16_0: Find the main row where the old u16 value in the first register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_0_counts = trace.at(lookup_value + 1).lookup_u16_0_counts - 1; + previous_value >>= 16; + + // U_16_1: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_1_counts = trace.at(lookup_value + 1).lookup_u16_1_counts - 1; + previous_value >>= 16; + + // U_16_2: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_2_counts = trace.at(lookup_value + 1).lookup_u16_2_counts - 1; + previous_value >>= 16; + + // U_16_3: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_3_counts = trace.at(lookup_value + 1).lookup_u16_3_counts - 1; + previous_value >>= 16; + + // U_16_4: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_4_counts = trace.at(lookup_value + 1).lookup_u16_4_counts - 1; + previous_value >>= 16; + + // U_16_5: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_5_counts = trace.at(lookup_value + 1).lookup_u16_5_counts - 1; + previous_value >>= 16; + + // U_16_6: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_6_counts = trace.at(lookup_value + 1).lookup_u16_6_counts - 1; + previous_value >>= 16; + + // U_16_7: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_7_counts = trace.at(lookup_value + 1).lookup_u16_7_counts - 1; + previous_value >>= 16; + + // U_16_8: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_8_counts = trace.at(lookup_value + 1).lookup_u16_8_counts - 1; + previous_value >>= 16; + + // U_16_9: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_9_counts = trace.at(lookup_value + 1).lookup_u16_9_counts - 1; + previous_value >>= 16; + + // U_16_10: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_10_counts = trace.at(lookup_value + 1).lookup_u16_10_counts - 1; + previous_value >>= 16; + + // U_16_11: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_11_counts = trace.at(lookup_value + 1).lookup_u16_11_counts - 1; + previous_value >>= 16; + + // U_16_12: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_12_counts = trace.at(lookup_value + 1).lookup_u16_12_counts - 1; + previous_value >>= 16; + + // U_16_13: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_13_counts = trace.at(lookup_value + 1).lookup_u16_13_counts - 1; + previous_value >>= 16; + + // U_16_14: Find the main row where the old u16 value in the second register is looked up + lookup_value = static_cast(previous_value); + // Decrement the counter + trace.at(lookup_value + 1).lookup_u16_14_counts = trace.at(lookup_value + 1).lookup_u16_14_counts - 1; + previous_value >>= 16; +} } // namespace tests_avm diff --git a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.hpp b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.hpp index 55ddd81b4b0..b1f4df3924a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/tests/helpers.test.hpp @@ -28,5 +28,6 @@ void mutate_ic_in_trace(std::vector& trace, std::function&& selectRow, FF const& newValue, bool alu = false); +void clear_range_check_counters(std::vector& trace, uint256_t previous_value); -} // namespace tests_avm \ No newline at end of file +} // namespace tests_avm