-
Notifications
You must be signed in to change notification settings - Fork 597
feat!: add support for u1 in the avm circuit & witgen #8570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| include "constants_gen.pil"; | ||
| include "gadgets/range_check.pil"; | ||
| include "gadgets/cmp.pil"; | ||
| namespace alu(256); | ||
|
|
@@ -12,16 +13,17 @@ namespace alu(256); | |
| pol commit ic; | ||
| pol commit sel_alu; // Predicate to activate the copy of intermediate registers to ALU table. | ||
|
|
||
| // Instruction tag (1: u8, 2: u16, 3: u32, 4: u64, 5: u128, 6: field) copied from Main table | ||
| // Instruction tag (1: u1, 2: u8, 3: u16, 4: u32, 5: u64, 6: u128, 7: field) copied from Main table | ||
| pol commit in_tag; | ||
|
|
||
| // Flattened boolean instruction tags | ||
| pol commit ff_tag; | ||
| pol commit u1_tag; | ||
| pol commit u8_tag; | ||
| pol commit u16_tag; | ||
| pol commit u32_tag; | ||
| pol commit u64_tag; | ||
| pol commit u128_tag; | ||
| pol commit ff_tag; | ||
|
|
||
| // Compute predicate telling whether there is a row entry in the ALU table. | ||
| sel_alu = op_add + op_sub + op_mul + op_not + op_eq + op_cast + op_lt + op_lte + op_shr + op_shl + op_div; | ||
|
|
@@ -30,18 +32,25 @@ namespace alu(256); | |
| // Remark: Operation selectors are constrained in the main trace. | ||
|
|
||
| // Boolean flattened instructions tags | ||
| ff_tag * (1 - ff_tag) = 0; | ||
| u1_tag * (1 - u1_tag) = 0; | ||
| u8_tag * (1 - u8_tag) = 0; | ||
| u16_tag * (1 - u16_tag) = 0; | ||
| u32_tag * (1 - u32_tag) = 0; | ||
| u64_tag * (1 - u64_tag) = 0; | ||
| u128_tag * (1 - u128_tag) = 0; | ||
| ff_tag * (1 - ff_tag) = 0; | ||
|
|
||
| // Mutual exclusion of the flattened instruction tag. | ||
| sel_alu * (ff_tag + u8_tag + u16_tag + u32_tag + u64_tag + u128_tag - 1) = 0; | ||
| sel_alu * (u1_tag + u8_tag + u16_tag + u32_tag + u64_tag + u128_tag + ff_tag - 1) = 0; | ||
|
|
||
| // Correct flattening of the instruction tag. | ||
| in_tag = u8_tag + 2 * u16_tag + 3 * u32_tag + 4 * u64_tag + 5 * u128_tag + 6 * ff_tag; | ||
| in_tag = (constants.MEM_TAG_U1 * u1_tag) | ||
| + (constants.MEM_TAG_U8 * u8_tag) | ||
| + (constants.MEM_TAG_U16 * u16_tag) | ||
| + (constants.MEM_TAG_U32 * u32_tag) | ||
| + (constants.MEM_TAG_U64 * u64_tag) | ||
| + (constants.MEM_TAG_U128 * u128_tag) | ||
| + (constants.MEM_TAG_FF * ff_tag); | ||
|
|
||
| // Operation selectors are copied from main table and do not need to be constrained here. | ||
| // Mutual exclusion of op_add and op_sub are derived from their mutual exclusion in the | ||
|
|
@@ -59,7 +68,7 @@ namespace alu(256); | |
| range_check_input_value = (op_add + op_sub + op_mul + op_cast + op_div) * ic + (op_shr * a_hi * NON_TRIVIAL_SHIFT) + (op_shl * a_lo * NON_TRIVIAL_SHIFT); | ||
| // The allowed bit range is defined by the instr tag, unless in shifts where it's different | ||
| range_check_num_bits = | ||
| (op_add + op_sub + op_mul + op_cast + op_div) * (u8_tag * 8 + u16_tag * 16 + u32_tag * 32 + u64_tag * 64 + u128_tag * 128) + | ||
| (op_add + op_sub + op_mul + op_cast + op_div) * (u1_tag * 1 + u8_tag * 8 + u16_tag * 16 + u32_tag * 32 + u64_tag * 64 + u128_tag * 128) + | ||
| (op_shl + op_shr) * (MAX_BITS - ib) * NON_TRIVIAL_SHIFT; | ||
|
|
||
| // Permutation to the Range Check Gadget | ||
|
|
@@ -92,15 +101,16 @@ namespace alu(256); | |
| // These are useful and commonly used relations / columns used through the file | ||
|
|
||
| // The maximum number of bits as defined by the instr tag | ||
| pol MAX_BITS = u8_tag * 8 + u16_tag * 16 + u32_tag * 32 + u64_tag * 64 + u128_tag * 128; | ||
| pol MAX_BITS = u1_tag * 1 + u8_tag * 8 + u16_tag * 16 + u32_tag * 32 + u64_tag * 64 + u128_tag * 128; | ||
| // 2^MAX_BITS | ||
| pol MAX_BITS_POW = u8_tag * 2**8 + u16_tag * 2**16 + u32_tag * 2**32 + u64_tag * 2**64 + u128_tag * 2**128; | ||
| pol MAX_BITS_POW = u1_tag * 2 + u8_tag * 2**8 + u16_tag * 2**16 + u32_tag * 2**32 + u64_tag * 2**64 + u128_tag * 2**128; | ||
| pol UINT_MAX = MAX_BITS_POW - 1; | ||
|
|
||
| // Value of p - 1 | ||
| pol MAX_FIELD_VALUE = 21888242871839275222246405745257275088548364400416034343698204186575808495616; | ||
|
|
||
| // Used when we split inputs into lo and hi limbs each of (MAX_BITS / 2) | ||
| // omitted: u1_tag * 0 (no need for limbs...) | ||
| pol LIMB_BITS_POW = u8_tag * 2**4 + u16_tag * 2**8 + u32_tag * 2**16 + u64_tag * 2**32 + u128_tag * 2**64; | ||
| // Lo and Hi Limbs for ia, ib and ic resp. Useful when performing operations over integers | ||
| pol commit a_lo; | ||
|
|
@@ -132,7 +142,8 @@ namespace alu(256); | |
| a_lo * b_hi + b_lo * a_hi = partial_prod_lo + LIMB_BITS_POW * partial_prod_hi; | ||
|
|
||
| // This holds the product over the integers | ||
| pol PRODUCT = a_lo * b_lo + LIMB_BITS_POW * partial_prod_lo + MAX_BITS_POW * (partial_prod_hi + a_hi * b_hi); | ||
| // (u1 multiplication only cares about a_lo and b_lo) | ||
| pol PRODUCT = a_lo * b_lo + (1 - u1_tag) * (LIMB_BITS_POW * partial_prod_lo + MAX_BITS_POW * (partial_prod_hi + a_hi * b_hi)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should not need the exception for u1, ie., the term (1 - u1_tag) can be removed I think.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Without that exception for u1, I believe |
||
|
|
||
| // =============== ADDITION/SUBTRACTION Operation Constraints ================================================= | ||
| pol commit op_add; | ||
|
|
@@ -243,6 +254,7 @@ namespace alu(256); | |
|
|
||
| // =============== Trivial Shift Operation ================================================= | ||
| // We use the comparison gadget to test ib > (MAX_BITS - 1) | ||
| // (always true for u1 - all u1 shifts are trivial) | ||
| (op_shl + op_shr) * (cmp_gadget_input_a - ib) = 0; | ||
| (op_shl + op_shr) * (cmp_gadget_input_b - (MAX_BITS - 1) ) = 0; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,3 +17,4 @@ namespace conversion(256); | |
| pol commit input; | ||
| pol commit radix; | ||
| pol commit num_limbs; | ||
| pol commit output_bits; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -146,7 +146,7 @@ namespace main(256); | |
| // Helper selector to characterize a Binary chiplet selector | ||
| pol commit sel_bin; | ||
|
|
||
| // Instruction memory tags read/write (1: u8, 2: u16, 3: u32, 4: u64, 5: u128, 6: field) | ||
| // Instruction memory tags read/write (1: u1, 2: u8, 3: u16, 4: u32, 5: u64, 6: u128, 7: field) | ||
| pol commit r_in_tag; | ||
| pol commit w_in_tag; | ||
| pol commit alu_in_tag; // Copy of r_in_tag or w_in_tag depending of the operation. It is sent to ALU trace. | ||
|
|
@@ -311,17 +311,17 @@ namespace main(256); | |
| // values should be written into these memory indices. | ||
| // - For indirect memory accesses, the memory trace constraints ensure that | ||
| // loaded values come from memory addresses with tag u32. This is enforced in the memory trace | ||
| // where each memory entry with flag sel_resolve_ind_addr_x (for x = a,b,c,d) constrains r_int_tag == 3 (u32). | ||
| // where each memory entry with flag sel_resolve_ind_addr_x (for x = a,b,c,d) constrains r_int_tag is u32. | ||
| // | ||
| // - ind_addr_a, ind_addr_b, ind_addr_c, ind_addr_d to u32 type: Should be guaranteed by bytecode validation and | ||
| // instruction decomposition as only immediate 32-bit values should be written into the indirect registers. | ||
| // | ||
| // - 0 <= r_in_tag, w_in_tag <= 6 // This should be constrained by the operation decomposition. | ||
| // - 0 <= r_in_tag, w_in_tag <= constants.MEM_TAG_FF // This should be constrained by the operation decomposition. | ||
|
|
||
| //====== COMPARATOR OPCODES CONSTRAINTS ===================================== | ||
| // Enforce that the tag for the ouput of EQ opcode is u8 (i.e. equal to 1). | ||
| #[OUTPUT_U8] | ||
| (sel_op_eq + sel_op_lte + sel_op_lt) * (w_in_tag - 1) = 0; | ||
| // Enforce that the tag for the ouput of EQ opcode is u1 (i.e. equal to 1). | ||
| #[OUTPUT_U1] | ||
| (sel_op_eq + sel_op_lte + sel_op_lt) * (w_in_tag - constants.MEM_TAG_U1) = 0; | ||
|
|
||
| //====== FDIV OPCODE CONSTRAINTS ============================================ | ||
| // Relation for division over the finite field | ||
|
|
@@ -340,13 +340,13 @@ namespace main(256); | |
| #[SUBOP_FDIV_ZERO_ERR2] | ||
| (sel_op_fdiv + sel_op_div) * op_err * (1 - inv) = 0; | ||
|
|
||
| // Enforcement that instruction tags are FF (tag constant 6). | ||
| // Enforcement that instruction tags are FF | ||
| // TODO: These 2 conditions might be removed and enforced through | ||
| // the bytecode decomposition instead. | ||
| #[SUBOP_FDIV_R_IN_TAG_FF] | ||
| sel_op_fdiv * (r_in_tag - 6) = 0; | ||
| sel_op_fdiv * (r_in_tag - constants.MEM_TAG_FF) = 0; | ||
| #[SUBOP_FDIV_W_IN_TAG_FF] | ||
| sel_op_fdiv * (w_in_tag - 6) = 0; | ||
| sel_op_fdiv * (w_in_tag - constants.MEM_TAG_FF) = 0; | ||
|
|
||
| // op_err cannot be maliciously activated for a non-relevant | ||
| // operation selector, i.e., op_err == 1 ==> sel_op_fdiv || sel_op_XXX || ... | ||
|
|
@@ -542,9 +542,9 @@ namespace main(256); | |
| binary.start {binary.clk, binary.acc_ia, binary.acc_ib, binary.acc_ic, binary.op_id, binary.in_tag}; | ||
|
|
||
| #[PERM_MAIN_CONV] | ||
| sel_op_radix_le {clk, ia, ic, id} | ||
| sel_op_radix_le {clk, ia, ib, ic, id} | ||
| is | ||
|
Comment on lines
544
to
546
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| conversion.sel_to_radix_le {conversion.clk, conversion.input, conversion.radix, conversion.num_limbs}; | ||
| conversion.sel_to_radix_le {conversion.clk, conversion.input, conversion.radix, conversion.num_limbs, conversion.output_bits}; | ||
|
|
||
| // This will be enabled when we migrate just to sha256Compression, as getting sha256 to work with it is tricky. | ||
| // #[PERM_MAIN_SHA256] | ||
|
|
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was just a bug