From 178573738731e2e74e4119a035f913da39675d85 Mon Sep 17 00:00:00 2001 From: David Banks <47112877+dbanks12@users.noreply.github.com> Date: Wed, 18 Sep 2024 12:42:18 -0400 Subject: [PATCH] feat!: add support for u1 in the avm, ToRadix's radix arg is a memory addr (#8570) --- avm-transpiler/src/bit_traits.rs | 10 +- avm-transpiler/src/instructions.rs | 4 + avm-transpiler/src/transpile.rs | 49 +- barretenberg/cpp/pil/avm/alu.pil | 30 +- barretenberg/cpp/pil/avm/binary.pil | 4 +- barretenberg/cpp/pil/avm/constants_gen.pil | 7 + .../cpp/pil/avm/fixed/byte_lookup.pil | 6 +- .../cpp/pil/avm/gadgets/conversion.pil | 1 + barretenberg/cpp/pil/avm/main.pil | 22 +- barretenberg/cpp/pil/avm/mem.pil | 35 +- .../dsl/acir_format/serde/acir.hpp | 2 +- .../vm/avm/generated/circuit_builder.cpp | 2 + .../vm/avm/generated/composer.cpp | 6 +- .../barretenberg/vm/avm/generated/flavor.cpp | 1358 +++++++++-------- .../barretenberg/vm/avm/generated/flavor.hpp | 6 +- .../vm/avm/generated/full_row.cpp | 4 + .../vm/avm/generated/full_row.hpp | 4 +- .../vm/avm/generated/relations/alu.hpp | 196 +-- .../vm/avm/generated/relations/main.hpp | 10 +- .../vm/avm/generated/relations/mem.hpp | 30 +- .../generated/relations/perm_main_conv.hpp | 10 +- .../vm/avm/tests/arithmetic.test.cpp | 171 ++- .../vm/avm/tests/bitwise.test.cpp | 39 +- .../barretenberg/vm/avm/tests/cast.test.cpp | 18 + .../vm/avm/tests/comparison.test.cpp | 6 +- .../vm/avm/tests/execution.test.cpp | 1010 ++++++------ .../barretenberg/vm/avm/trace/alu_trace.cpp | 16 +- .../vm/avm/trace/binary_trace.cpp | 23 +- .../src/barretenberg/vm/avm/trace/common.hpp | 14 +- .../vm/avm/trace/deserialization.cpp | 14 +- .../vm/avm/trace/deserialization.hpp | 2 +- .../barretenberg/vm/avm/trace/execution.cpp | 3 +- .../barretenberg/vm/avm/trace/fixed_bytes.cpp | 19 +- .../vm/avm/trace/gadgets/conversion_trace.cpp | 26 +- .../vm/avm/trace/gadgets/conversion_trace.hpp | 4 +- .../src/barretenberg/vm/avm/trace/helper.cpp | 5 + .../src/barretenberg/vm/avm/trace/helper.hpp | 16 +- .../src/barretenberg/vm/avm/trace/opcode.cpp | 1 + .../src/barretenberg/vm/avm/trace/opcode.hpp | 12 - .../src/barretenberg/vm/avm/trace/trace.cpp | 109 +- .../src/barretenberg/vm/avm/trace/trace.hpp | 7 +- .../src/barretenberg/vm/aztec_constants.hpp | 7 + .../src/core/libraries/ConstantsGen.sol | 7 + .../crates/types/src/constants.nr | 9 + .../noir-repo/acvm-repo/acir/codegen/acir.cpp | 2 +- .../acvm-repo/brillig/src/black_box.rs | 2 +- .../acvm-repo/brillig_vm/src/black_box.rs | 6 +- .../brillig/brillig_ir/codegen_intrinsic.rs | 5 +- yarn-project/circuits.js/src/constants.gen.ts | 7 + .../circuits.js/src/scripts/constants.in.ts | 14 + yarn-project/simulator/src/avm/avm_gas.ts | 1 + .../src/avm/avm_memory_types.test.ts | 102 +- .../simulator/src/avm/avm_memory_types.ts | 40 +- .../simulator/src/avm/opcodes/comparators.ts | 4 +- .../src/avm/opcodes/conversion.test.ts | 54 +- .../simulator/src/avm/opcodes/conversion.ts | 29 +- .../src/avm/opcodes/multi_scalar_mul.test.ts | 6 +- .../src/avm/opcodes/multi_scalar_mul.ts | 4 +- .../instruction_serialization.ts | 2 + 59 files changed, 2106 insertions(+), 1506 deletions(-) diff --git a/avm-transpiler/src/bit_traits.rs b/avm-transpiler/src/bit_traits.rs index ff54ef23df5..d4f65ba032e 100644 --- a/avm-transpiler/src/bit_traits.rs +++ b/avm-transpiler/src/bit_traits.rs @@ -58,15 +58,15 @@ impl BitsQueryable for usize { pub fn bits_needed_for(val: &T) -> usize { let num_bits = val.num_bits(); - if num_bits < 8 { + if num_bits <= 8 { 8 - } else if num_bits < 16 { + } else if num_bits <= 16 { 16 - } else if num_bits < 32 { + } else if num_bits <= 32 { 32 - } else if num_bits < 64 { + } else if num_bits <= 64 { 64 - } else if num_bits < 128 { + } else if num_bits <= 128 { 128 } else { 254 diff --git a/avm-transpiler/src/instructions.rs b/avm-transpiler/src/instructions.rs index 0e25dedc3f3..4b3df88e102 100644 --- a/avm-transpiler/src/instructions.rs +++ b/avm-transpiler/src/instructions.rs @@ -94,6 +94,7 @@ impl Default for AvmInstruction { #[derive(Copy, Clone, Debug)] pub enum AvmTypeTag { UNINITIALIZED, + UINT1, UINT8, UINT16, UINT32, @@ -107,6 +108,7 @@ pub enum AvmTypeTag { /// Constants (as used by the SET instruction) can have size /// different from 32 bits pub enum AvmOperand { + U1 { value: u8 }, // same wire format as U8 U8 { value: u8 }, U16 { value: u16 }, U32 { value: u32 }, @@ -118,6 +120,7 @@ pub enum AvmOperand { impl Display for AvmOperand { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { + AvmOperand::U1 { value } => write!(f, " U1:{}", value), AvmOperand::U8 { value } => write!(f, " U8:{}", value), AvmOperand::U16 { value } => write!(f, " U16:{}", value), AvmOperand::U32 { value } => write!(f, " U32:{}", value), @@ -131,6 +134,7 @@ impl Display for AvmOperand { impl AvmOperand { pub fn to_be_bytes(&self) -> Vec { match self { + AvmOperand::U1 { value } => value.to_be_bytes().to_vec(), AvmOperand::U8 { value } => value.to_be_bytes().to_vec(), AvmOperand::U16 { value } => value.to_be_bytes().to_vec(), AvmOperand::U32 { value } => value.to_be_bytes().to_vec(), diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 75a470356e6..de617c2ea72 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -202,15 +202,6 @@ pub fn brillig_to_avm( ], tag: None, }); - if let IntegerBitSize::U1 = bit_size { - // We need to cast the result back to u1 - handle_cast( - &mut avm_instrs, - destination, - destination, - BitSize::Integer(IntegerBitSize::U1), - ); - } } BrilligOpcode::CalldataCopy { destination_address, size_address, offset_address } => { avm_instrs.push(AvmInstruction { @@ -505,32 +496,8 @@ fn handle_cast( let source_offset = source.to_usize() as u32; let dest_offset = destination.to_usize() as u32; - if bit_size == BitSize::Integer(IntegerBitSize::U1) { - assert!( - matches!(tag_from_bit_size(bit_size), AvmTypeTag::UINT8), - "If u1 doesn't map to u8 anymore, change this code!" - ); - avm_instrs.extend([ - // We cast to Field to be able to use toradix. - generate_cast_instruction(source_offset, false, dest_offset, false, AvmTypeTag::FIELD), - // Toradix with radix 2 and 1 limb is the same as modulo 2. - // We need to insert an instruction explicitly because we want to fine-tune 'indirect'. - AvmInstruction { - opcode: AvmOpcode::TORADIXLE, - indirect: Some(ALL_DIRECT), - tag: None, - operands: vec![ - AvmOperand::U32 { value: dest_offset }, - AvmOperand::U32 { value: dest_offset }, - AvmOperand::U32 { value: /*radix=*/ 2}, - AvmOperand::U32 { value: /*limbs=*/ 1}, - ], - }, - ]); - } else { - let tag = tag_from_bit_size(bit_size); - avm_instrs.push(generate_cast_instruction(source_offset, false, dest_offset, false, tag)); - } + let tag = tag_from_bit_size(bit_size); + avm_instrs.push(generate_cast_instruction(source_offset, false, dest_offset, false, tag)); } /// Handle an AVM NOTEHASHEXISTS instruction @@ -987,12 +954,11 @@ fn handle_black_box_function(avm_instrs: &mut Vec, operation: &B ..Default::default() }); } - // We ignore the output bits flag since we represent bits as bytes - BlackBoxOp::ToRadix { input, radix, output, output_bits: _ } => { + BlackBoxOp::ToRadix { input, radix, output, output_bits } => { let num_limbs = output.size as u32; let input_offset = input.0 as u32; let output_offset = output.pointer.0 as u32; - assert!(radix <= &256u32, "Radix must be less than or equal to 256"); + let radix_offset = radix.0 as u32; avm_instrs.push(AvmInstruction { opcode: AvmOpcode::TORADIXLE, @@ -1001,8 +967,9 @@ fn handle_black_box_function(avm_instrs: &mut Vec, operation: &B operands: vec![ AvmOperand::U32 { value: input_offset }, AvmOperand::U32 { value: output_offset }, - AvmOperand::U32 { value: *radix }, + AvmOperand::U32 { value: radix_offset }, AvmOperand::U32 { value: num_limbs }, + AvmOperand::U1 { value: *output_bits as u8 }, ], }); } @@ -1313,8 +1280,6 @@ pub fn map_brillig_pcs_to_avm_pcs(brillig_bytecode: &[BrilligOpcode 2, - BrilligOpcode::Not { bit_size: IntegerBitSize::U1, .. } => 3, _ => 1, }; // next Brillig pc will map to an AVM pc offset by the @@ -1338,7 +1303,7 @@ fn is_integral_bit_size(bit_size: IntegerBitSize) -> bool { fn tag_from_bit_size(bit_size: BitSize) -> AvmTypeTag { match bit_size { - BitSize::Integer(IntegerBitSize::U1) => AvmTypeTag::UINT8, // temp workaround + BitSize::Integer(IntegerBitSize::U1) => AvmTypeTag::UINT1, BitSize::Integer(IntegerBitSize::U8) => AvmTypeTag::UINT8, BitSize::Integer(IntegerBitSize::U16) => AvmTypeTag::UINT16, BitSize::Integer(IntegerBitSize::U32) => AvmTypeTag::UINT32, diff --git a/barretenberg/cpp/pil/avm/alu.pil b/barretenberg/cpp/pil/avm/alu.pil index 6778c42e9d7..392a49d8f04 100644 --- a/barretenberg/cpp/pil/avm/alu.pil +++ b/barretenberg/cpp/pil/avm/alu.pil @@ -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)); // =============== 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; diff --git a/barretenberg/cpp/pil/avm/binary.pil b/barretenberg/cpp/pil/avm/binary.pil index d30edaa7474..d9e7d3d57a6 100644 --- a/barretenberg/cpp/pil/avm/binary.pil +++ b/barretenberg/cpp/pil/avm/binary.pil @@ -13,7 +13,7 @@ namespace binary(256); pol commit acc_ib; pol commit acc_ic; - // This is the instruction tag {1,2,3,4,5} (restricted to not be a field) + // This is the instruction tag {1,2,3,4,5,6} (restricted to not be a field) // Operations over FF are not supported, it is assumed this exclusion is handled // outside of this subtrace. @@ -37,7 +37,7 @@ namespace binary(256); // To support dynamically sized memory operands we use a counter against a lookup // This decrementing counter goes from [MEM_TAG, 0] where MEM_TAG is the number of bytes in the - // corresponding integer. i.e. MEM_TAG is between 1 (U8) and 16(U128). + // corresponding integer. i.e. MEM_TAG is between 1 (U8) and 16 (U128). // Consistency can be achieved with a lookup table between the instr_tag and bytes_length pol commit mem_tag_ctr; #[MEM_TAG_REL] diff --git a/barretenberg/cpp/pil/avm/constants_gen.pil b/barretenberg/cpp/pil/avm/constants_gen.pil index c2a17b1d7ec..04af42fb49c 100644 --- a/barretenberg/cpp/pil/avm/constants_gen.pil +++ b/barretenberg/cpp/pil/avm/constants_gen.pil @@ -11,6 +11,13 @@ namespace constants(256); pol MAX_NULLIFIER_NON_EXISTENT_READ_REQUESTS_PER_CALL = 16; pol MAX_L1_TO_L2_MSG_READ_REQUESTS_PER_CALL = 16; pol MAX_UNENCRYPTED_LOGS_PER_CALL = 4; + pol MEM_TAG_U1 = 1; + pol MEM_TAG_U8 = 2; + pol MEM_TAG_U16 = 3; + pol MEM_TAG_U32 = 4; + pol MEM_TAG_U64 = 5; + pol MEM_TAG_U128 = 6; + pol MEM_TAG_FF = 7; pol SENDER_SELECTOR = 0; pol ADDRESS_SELECTOR = 1; pol STORAGE_ADDRESS_SELECTOR = 1; diff --git a/barretenberg/cpp/pil/avm/fixed/byte_lookup.pil b/barretenberg/cpp/pil/avm/fixed/byte_lookup.pil index 5cd3b8f242f..9579ed1e451 100644 --- a/barretenberg/cpp/pil/avm/fixed/byte_lookup.pil +++ b/barretenberg/cpp/pil/avm/fixed/byte_lookup.pil @@ -8,6 +8,6 @@ namespace byte_lookup(256); pol constant sel_bin; // These two columns are a mapping between instruction tags and their byte lengths - // {U8: 1, U16: 2, ... , U128: 16} - pol constant table_in_tags; // Column of U8,U16,...,U128 - pol constant table_byte_lengths; // Columns of byte lengths 1,2,...,16; + // {U1: 1, U8: 1, U16: 2, ... , U128: 16} + pol constant table_in_tags; // Column of U1,U8,U16,...,U128 + pol constant table_byte_lengths; // Columns of byte lengths 1,1,2,...,16; diff --git a/barretenberg/cpp/pil/avm/gadgets/conversion.pil b/barretenberg/cpp/pil/avm/gadgets/conversion.pil index 115a0571075..5ab45ee45b1 100644 --- a/barretenberg/cpp/pil/avm/gadgets/conversion.pil +++ b/barretenberg/cpp/pil/avm/gadgets/conversion.pil @@ -17,3 +17,4 @@ namespace conversion(256); pol commit input; pol commit radix; pol commit num_limbs; + pol commit output_bits; diff --git a/barretenberg/cpp/pil/avm/main.pil b/barretenberg/cpp/pil/avm/main.pil index b4debf47049..44d63549282 100644 --- a/barretenberg/cpp/pil/avm/main.pil +++ b/barretenberg/cpp/pil/avm/main.pil @@ -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 - 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] diff --git a/barretenberg/cpp/pil/avm/mem.pil b/barretenberg/cpp/pil/avm/mem.pil index ff9ff2dd905..e4b07c9c0f8 100644 --- a/barretenberg/cpp/pil/avm/mem.pil +++ b/barretenberg/cpp/pil/avm/mem.pil @@ -1,4 +1,5 @@ include "main.pil"; +include "constants_gen.pil"; include "./gadgets/range_check.pil"; namespace mem(256); @@ -8,7 +9,7 @@ namespace mem(256); pol commit addr; pol commit space_id; pol commit glob_addr; - pol commit tag; // Memory tag (0: uninitialized, 1: u8, 2: u16, 3: u32, 4: u64, 5: u128, 6:field) + pol commit tag; // Memory tag (0: uninitialized, 1: u1, 2: u8, 3: u16, 4: u32, 5: u64, 6: u128, 7:field) pol commit val; pol commit rw; // Enum: 0 (read), 1 (write) pol commit lastAccess; // Boolean (1 when this row is the last of a given address) @@ -223,11 +224,11 @@ namespace mem(256); rw * tag_err = 0; //====== Indirect Memory Constraints ===================================== - // Enforce r_in_tag == 3, i.e., r_in_tag must be U32 - sel_resolve_ind_addr_a * (r_in_tag - 3) = 0; - sel_resolve_ind_addr_b * (r_in_tag - 3) = 0; - sel_resolve_ind_addr_c * (r_in_tag - 3) = 0; - sel_resolve_ind_addr_d * (r_in_tag - 3) = 0; + // Enforce r_in_tag is U32 + sel_resolve_ind_addr_a * (r_in_tag - constants.MEM_TAG_U32) = 0; + sel_resolve_ind_addr_b * (r_in_tag - constants.MEM_TAG_U32) = 0; + sel_resolve_ind_addr_c * (r_in_tag - constants.MEM_TAG_U32) = 0; + sel_resolve_ind_addr_d * (r_in_tag - constants.MEM_TAG_U32) = 0; // Indirect operation is always a load sel_resolve_ind_addr_a * rw = 0; @@ -236,19 +237,19 @@ namespace mem(256); sel_resolve_ind_addr_d * rw = 0; //====== CALLDATACOPY/RETURN specific constraints ================================== - sel_op_slice * (w_in_tag - 6) = 0; // Only write elements of type FF - sel_op_slice * (r_in_tag - 6) = 0; // Only read elements of type FF + sel_op_slice * (w_in_tag - constants.MEM_TAG_FF) = 0; // Only write elements of type FF + sel_op_slice * (r_in_tag - constants.MEM_TAG_FF) = 0; // Only read elements of type FF //====== POSEIDON2 specific constraints ================================== - sel_op_poseidon_read_a * (w_in_tag - 6) = 0; // Only read elements of type FF - sel_op_poseidon_read_b * (w_in_tag - 6) = 0; // Only read elements of type FF - sel_op_poseidon_read_c * (w_in_tag - 6) = 0; // Only read elements of type FF - sel_op_poseidon_read_d * (w_in_tag - 6) = 0; // Only read elements of type FF - - sel_op_poseidon_write_a * (r_in_tag - 6) = 0; // Only write elements of type FF - sel_op_poseidon_write_b * (r_in_tag - 6) = 0; // Only write elements of type FF - sel_op_poseidon_write_c * (r_in_tag - 6) = 0; // Only write elements of type FF - sel_op_poseidon_write_d * (r_in_tag - 6) = 0; // Only write elements of type FF + sel_op_poseidon_read_a * (w_in_tag - constants.MEM_TAG_FF) = 0; // Only read elements of type FF + sel_op_poseidon_read_b * (w_in_tag - constants.MEM_TAG_FF) = 0; // Only read elements of type FF + sel_op_poseidon_read_c * (w_in_tag - constants.MEM_TAG_FF) = 0; // Only read elements of type FF + sel_op_poseidon_read_d * (w_in_tag - constants.MEM_TAG_FF) = 0; // Only read elements of type FF + + sel_op_poseidon_write_a * (r_in_tag - constants.MEM_TAG_FF) = 0; // Only write elements of type FF + sel_op_poseidon_write_b * (r_in_tag - constants.MEM_TAG_FF) = 0; // Only write elements of type FF + sel_op_poseidon_write_c * (r_in_tag - constants.MEM_TAG_FF) = 0; // Only write elements of type FF + sel_op_poseidon_write_d * (r_in_tag - constants.MEM_TAG_FF) = 0; // Only write elements of type FF //====== MOV/CMOV Opcode Tag Constraint ===================================== // The following constraint ensures that the r_in_tag is set to tag for diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index d4bdab6ebb0..e2053834631 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -462,7 +462,7 @@ struct BlackBoxOp { struct ToRadix { Program::MemoryAddress input; - uint32_t radix; + Program::MemoryAddress radix; Program::HeapArray output; bool output_bits; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp index f007e455874..62066aaa567 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp @@ -107,6 +107,7 @@ AvmCircuitBuilder::ProverPolynomials AvmCircuitBuilder::compute_polynomials() co polys.alu_sel_shift_which.set_if_valid_index(i, rows[i].alu_sel_shift_which); polys.alu_u128_tag.set_if_valid_index(i, rows[i].alu_u128_tag); polys.alu_u16_tag.set_if_valid_index(i, rows[i].alu_u16_tag); + polys.alu_u1_tag.set_if_valid_index(i, rows[i].alu_u1_tag); polys.alu_u32_tag.set_if_valid_index(i, rows[i].alu_u32_tag); polys.alu_u64_tag.set_if_valid_index(i, rows[i].alu_u64_tag); polys.alu_u8_tag.set_if_valid_index(i, rows[i].alu_u8_tag); @@ -152,6 +153,7 @@ AvmCircuitBuilder::ProverPolynomials AvmCircuitBuilder::compute_polynomials() co polys.conversion_clk.set_if_valid_index(i, rows[i].conversion_clk); polys.conversion_input.set_if_valid_index(i, rows[i].conversion_input); polys.conversion_num_limbs.set_if_valid_index(i, rows[i].conversion_num_limbs); + polys.conversion_output_bits.set_if_valid_index(i, rows[i].conversion_output_bits); polys.conversion_radix.set_if_valid_index(i, rows[i].conversion_radix); polys.conversion_sel_to_radix_le.set_if_valid_index(i, rows[i].conversion_sel_to_radix_le); polys.keccakf1600_clk.set_if_valid_index(i, rows[i].keccakf1600_clk); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/composer.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/composer.cpp index 45ffe4c9eea..dfa4af8ba04 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/composer.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/composer.cpp @@ -45,8 +45,10 @@ std::shared_ptr AvmComposer::compute_proving_key(CircuitCons } // Initialize proving_key - const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size(); - proving_key = std::make_shared(subgroup_size, 0); + { + const size_t subgroup_size = circuit_constructor.get_circuit_subgroup_size(); + proving_key = std::make_shared(subgroup_size, 0); + } return proving_key; } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.cpp index d5b13f28986..2509bdeae02 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.cpp @@ -70,682 +70,684 @@ AvmFlavor::AllConstRefValues::AllConstRefValues( , alu_sel_shift_which(il[62]) , alu_u128_tag(il[63]) , alu_u16_tag(il[64]) - , alu_u32_tag(il[65]) - , alu_u64_tag(il[66]) - , alu_u8_tag(il[67]) - , alu_zero_shift(il[68]) - , binary_acc_ia(il[69]) - , binary_acc_ib(il[70]) - , binary_acc_ic(il[71]) - , binary_clk(il[72]) - , binary_ia_bytes(il[73]) - , binary_ib_bytes(il[74]) - , binary_ic_bytes(il[75]) - , binary_in_tag(il[76]) - , binary_mem_tag_ctr(il[77]) - , binary_mem_tag_ctr_inv(il[78]) - , binary_op_id(il[79]) - , binary_sel_bin(il[80]) - , binary_start(il[81]) - , cmp_a_hi(il[82]) - , cmp_a_lo(il[83]) - , cmp_b_hi(il[84]) - , cmp_b_lo(il[85]) - , cmp_borrow(il[86]) - , cmp_clk(il[87]) - , cmp_cmp_rng_ctr(il[88]) - , cmp_input_a(il[89]) - , cmp_input_b(il[90]) - , cmp_op_eq(il[91]) - , cmp_op_eq_diff_inv(il[92]) - , cmp_op_gt(il[93]) - , cmp_p_a_borrow(il[94]) - , cmp_p_b_borrow(il[95]) - , cmp_p_sub_a_hi(il[96]) - , cmp_p_sub_a_lo(il[97]) - , cmp_p_sub_b_hi(il[98]) - , cmp_p_sub_b_lo(il[99]) - , cmp_range_chk_clk(il[100]) - , cmp_res_hi(il[101]) - , cmp_res_lo(il[102]) - , cmp_result(il[103]) - , cmp_sel_cmp(il[104]) - , cmp_sel_rng_chk(il[105]) - , cmp_shift_sel(il[106]) - , conversion_clk(il[107]) - , conversion_input(il[108]) - , conversion_num_limbs(il[109]) - , conversion_radix(il[110]) - , conversion_sel_to_radix_le(il[111]) - , keccakf1600_clk(il[112]) - , keccakf1600_input(il[113]) - , keccakf1600_output(il[114]) - , keccakf1600_sel_keccakf1600(il[115]) - , main_abs_da_rem_gas(il[116]) - , main_abs_l2_rem_gas(il[117]) - , main_alu_in_tag(il[118]) - , main_base_da_gas_op_cost(il[119]) - , main_base_l2_gas_op_cost(il[120]) - , main_bin_op_id(il[121]) - , main_call_ptr(il[122]) - , main_da_gas_remaining(il[123]) - , main_da_out_of_gas(il[124]) - , main_dyn_da_gas_op_cost(il[125]) - , main_dyn_gas_multiplier(il[126]) - , main_dyn_l2_gas_op_cost(il[127]) - , main_emit_l2_to_l1_msg_write_offset(il[128]) - , main_emit_note_hash_write_offset(il[129]) - , main_emit_nullifier_write_offset(il[130]) - , main_emit_unencrypted_log_write_offset(il[131]) - , main_ia(il[132]) - , main_ib(il[133]) - , main_ic(il[134]) - , main_id(il[135]) - , main_id_zero(il[136]) - , main_ind_addr_a(il[137]) - , main_ind_addr_b(il[138]) - , main_ind_addr_c(il[139]) - , main_ind_addr_d(il[140]) - , main_internal_return_ptr(il[141]) - , main_inv(il[142]) - , main_kernel_in_offset(il[143]) - , main_kernel_out_offset(il[144]) - , main_l1_to_l2_msg_exists_write_offset(il[145]) - , main_l2_gas_remaining(il[146]) - , main_l2_out_of_gas(il[147]) - , main_mem_addr_a(il[148]) - , main_mem_addr_b(il[149]) - , main_mem_addr_c(il[150]) - , main_mem_addr_d(il[151]) - , main_note_hash_exist_write_offset(il[152]) - , main_nullifier_exists_write_offset(il[153]) - , main_nullifier_non_exists_write_offset(il[154]) - , main_op_err(il[155]) - , main_opcode_val(il[156]) - , main_pc(il[157]) - , main_r_in_tag(il[158]) - , main_rwa(il[159]) - , main_rwb(il[160]) - , main_rwc(il[161]) - , main_rwd(il[162]) - , main_sel_alu(il[163]) - , main_sel_bin(il[164]) - , main_sel_calldata(il[165]) - , main_sel_execution_row(il[166]) - , main_sel_kernel_inputs(il[167]) - , main_sel_kernel_out(il[168]) - , main_sel_last(il[169]) - , main_sel_mem_op_a(il[170]) - , main_sel_mem_op_b(il[171]) - , main_sel_mem_op_c(il[172]) - , main_sel_mem_op_d(il[173]) - , main_sel_mov_ia_to_ic(il[174]) - , main_sel_mov_ib_to_ic(il[175]) - , main_sel_op_add(il[176]) - , main_sel_op_address(il[177]) - , main_sel_op_and(il[178]) - , main_sel_op_block_number(il[179]) - , main_sel_op_calldata_copy(il[180]) - , main_sel_op_cast(il[181]) - , main_sel_op_chain_id(il[182]) - , main_sel_op_cmov(il[183]) - , main_sel_op_dagasleft(il[184]) - , main_sel_op_div(il[185]) - , main_sel_op_ecadd(il[186]) - , main_sel_op_emit_l2_to_l1_msg(il[187]) - , main_sel_op_emit_note_hash(il[188]) - , main_sel_op_emit_nullifier(il[189]) - , main_sel_op_emit_unencrypted_log(il[190]) - , main_sel_op_eq(il[191]) - , main_sel_op_external_call(il[192]) - , main_sel_op_external_return(il[193]) - , main_sel_op_external_revert(il[194]) - , main_sel_op_fdiv(il[195]) - , main_sel_op_fee_per_da_gas(il[196]) - , main_sel_op_fee_per_l2_gas(il[197]) - , main_sel_op_function_selector(il[198]) - , main_sel_op_get_contract_instance(il[199]) - , main_sel_op_internal_call(il[200]) - , main_sel_op_internal_return(il[201]) - , main_sel_op_jump(il[202]) - , main_sel_op_jumpi(il[203]) - , main_sel_op_keccak(il[204]) - , main_sel_op_l1_to_l2_msg_exists(il[205]) - , main_sel_op_l2gasleft(il[206]) - , main_sel_op_lt(il[207]) - , main_sel_op_lte(il[208]) - , main_sel_op_mov(il[209]) - , main_sel_op_msm(il[210]) - , main_sel_op_mul(il[211]) - , main_sel_op_not(il[212]) - , main_sel_op_note_hash_exists(il[213]) - , main_sel_op_nullifier_exists(il[214]) - , main_sel_op_or(il[215]) - , main_sel_op_pedersen(il[216]) - , main_sel_op_pedersen_commit(il[217]) - , main_sel_op_poseidon2(il[218]) - , main_sel_op_radix_le(il[219]) - , main_sel_op_sender(il[220]) - , main_sel_op_set(il[221]) - , main_sel_op_sha256(il[222]) - , main_sel_op_shl(il[223]) - , main_sel_op_shr(il[224]) - , main_sel_op_sload(il[225]) - , main_sel_op_sstore(il[226]) - , main_sel_op_storage_address(il[227]) - , main_sel_op_sub(il[228]) - , main_sel_op_timestamp(il[229]) - , main_sel_op_transaction_fee(il[230]) - , main_sel_op_version(il[231]) - , main_sel_op_xor(il[232]) - , main_sel_q_kernel_lookup(il[233]) - , main_sel_q_kernel_output_lookup(il[234]) - , main_sel_resolve_ind_addr_a(il[235]) - , main_sel_resolve_ind_addr_b(il[236]) - , main_sel_resolve_ind_addr_c(il[237]) - , main_sel_resolve_ind_addr_d(il[238]) - , main_sel_returndata(il[239]) - , main_sel_rng_16(il[240]) - , main_sel_rng_8(il[241]) - , main_sel_slice_gadget(il[242]) - , main_side_effect_counter(il[243]) - , main_sload_write_offset(il[244]) - , main_space_id(il[245]) - , main_sstore_write_offset(il[246]) - , main_tag_err(il[247]) - , main_w_in_tag(il[248]) - , mem_addr(il[249]) - , mem_clk(il[250]) - , mem_diff(il[251]) - , mem_glob_addr(il[252]) - , mem_last(il[253]) - , mem_lastAccess(il[254]) - , mem_one_min_inv(il[255]) - , mem_r_in_tag(il[256]) - , mem_rw(il[257]) - , mem_sel_mem(il[258]) - , mem_sel_mov_ia_to_ic(il[259]) - , mem_sel_mov_ib_to_ic(il[260]) - , mem_sel_op_a(il[261]) - , mem_sel_op_b(il[262]) - , mem_sel_op_c(il[263]) - , mem_sel_op_cmov(il[264]) - , mem_sel_op_d(il[265]) - , mem_sel_op_poseidon_read_a(il[266]) - , mem_sel_op_poseidon_read_b(il[267]) - , mem_sel_op_poseidon_read_c(il[268]) - , mem_sel_op_poseidon_read_d(il[269]) - , mem_sel_op_poseidon_write_a(il[270]) - , mem_sel_op_poseidon_write_b(il[271]) - , mem_sel_op_poseidon_write_c(il[272]) - , mem_sel_op_poseidon_write_d(il[273]) - , mem_sel_op_slice(il[274]) - , mem_sel_resolve_ind_addr_a(il[275]) - , mem_sel_resolve_ind_addr_b(il[276]) - , mem_sel_resolve_ind_addr_c(il[277]) - , mem_sel_resolve_ind_addr_d(il[278]) - , mem_sel_rng_chk(il[279]) - , mem_skip_check_tag(il[280]) - , mem_space_id(il[281]) - , mem_tag(il[282]) - , mem_tag_err(il[283]) - , mem_tsp(il[284]) - , mem_val(il[285]) - , mem_w_in_tag(il[286]) - , pedersen_clk(il[287]) - , pedersen_input(il[288]) - , pedersen_output(il[289]) - , pedersen_sel_pedersen(il[290]) - , poseidon2_B_10_0(il[291]) - , poseidon2_B_10_1(il[292]) - , poseidon2_B_10_2(il[293]) - , poseidon2_B_10_3(il[294]) - , poseidon2_B_11_0(il[295]) - , poseidon2_B_11_1(il[296]) - , poseidon2_B_11_2(il[297]) - , poseidon2_B_11_3(il[298]) - , poseidon2_B_12_0(il[299]) - , poseidon2_B_12_1(il[300]) - , poseidon2_B_12_2(il[301]) - , poseidon2_B_12_3(il[302]) - , poseidon2_B_13_0(il[303]) - , poseidon2_B_13_1(il[304]) - , poseidon2_B_13_2(il[305]) - , poseidon2_B_13_3(il[306]) - , poseidon2_B_14_0(il[307]) - , poseidon2_B_14_1(il[308]) - , poseidon2_B_14_2(il[309]) - , poseidon2_B_14_3(il[310]) - , poseidon2_B_15_0(il[311]) - , poseidon2_B_15_1(il[312]) - , poseidon2_B_15_2(il[313]) - , poseidon2_B_15_3(il[314]) - , poseidon2_B_16_0(il[315]) - , poseidon2_B_16_1(il[316]) - , poseidon2_B_16_2(il[317]) - , poseidon2_B_16_3(il[318]) - , poseidon2_B_17_0(il[319]) - , poseidon2_B_17_1(il[320]) - , poseidon2_B_17_2(il[321]) - , poseidon2_B_17_3(il[322]) - , poseidon2_B_18_0(il[323]) - , poseidon2_B_18_1(il[324]) - , poseidon2_B_18_2(il[325]) - , poseidon2_B_18_3(il[326]) - , poseidon2_B_19_0(il[327]) - , poseidon2_B_19_1(il[328]) - , poseidon2_B_19_2(il[329]) - , poseidon2_B_19_3(il[330]) - , poseidon2_B_20_0(il[331]) - , poseidon2_B_20_1(il[332]) - , poseidon2_B_20_2(il[333]) - , poseidon2_B_20_3(il[334]) - , poseidon2_B_21_0(il[335]) - , poseidon2_B_21_1(il[336]) - , poseidon2_B_21_2(il[337]) - , poseidon2_B_21_3(il[338]) - , poseidon2_B_22_0(il[339]) - , poseidon2_B_22_1(il[340]) - , poseidon2_B_22_2(il[341]) - , poseidon2_B_22_3(il[342]) - , poseidon2_B_23_0(il[343]) - , poseidon2_B_23_1(il[344]) - , poseidon2_B_23_2(il[345]) - , poseidon2_B_23_3(il[346]) - , poseidon2_B_24_0(il[347]) - , poseidon2_B_24_1(il[348]) - , poseidon2_B_24_2(il[349]) - , poseidon2_B_24_3(il[350]) - , poseidon2_B_25_0(il[351]) - , poseidon2_B_25_1(il[352]) - , poseidon2_B_25_2(il[353]) - , poseidon2_B_25_3(il[354]) - , poseidon2_B_26_0(il[355]) - , poseidon2_B_26_1(il[356]) - , poseidon2_B_26_2(il[357]) - , poseidon2_B_26_3(il[358]) - , poseidon2_B_27_0(il[359]) - , poseidon2_B_27_1(il[360]) - , poseidon2_B_27_2(il[361]) - , poseidon2_B_27_3(il[362]) - , poseidon2_B_28_0(il[363]) - , poseidon2_B_28_1(il[364]) - , poseidon2_B_28_2(il[365]) - , poseidon2_B_28_3(il[366]) - , poseidon2_B_29_0(il[367]) - , poseidon2_B_29_1(il[368]) - , poseidon2_B_29_2(il[369]) - , poseidon2_B_29_3(il[370]) - , poseidon2_B_30_0(il[371]) - , poseidon2_B_30_1(il[372]) - , poseidon2_B_30_2(il[373]) - , poseidon2_B_30_3(il[374]) - , poseidon2_B_31_0(il[375]) - , poseidon2_B_31_1(il[376]) - , poseidon2_B_31_2(il[377]) - , poseidon2_B_31_3(il[378]) - , poseidon2_B_32_0(il[379]) - , poseidon2_B_32_1(il[380]) - , poseidon2_B_32_2(il[381]) - , poseidon2_B_32_3(il[382]) - , poseidon2_B_33_0(il[383]) - , poseidon2_B_33_1(il[384]) - , poseidon2_B_33_2(il[385]) - , poseidon2_B_33_3(il[386]) - , poseidon2_B_34_0(il[387]) - , poseidon2_B_34_1(il[388]) - , poseidon2_B_34_2(il[389]) - , poseidon2_B_34_3(il[390]) - , poseidon2_B_35_0(il[391]) - , poseidon2_B_35_1(il[392]) - , poseidon2_B_35_2(il[393]) - , poseidon2_B_35_3(il[394]) - , poseidon2_B_36_0(il[395]) - , poseidon2_B_36_1(il[396]) - , poseidon2_B_36_2(il[397]) - , poseidon2_B_36_3(il[398]) - , poseidon2_B_37_0(il[399]) - , poseidon2_B_37_1(il[400]) - , poseidon2_B_37_2(il[401]) - , poseidon2_B_37_3(il[402]) - , poseidon2_B_38_0(il[403]) - , poseidon2_B_38_1(il[404]) - , poseidon2_B_38_2(il[405]) - , poseidon2_B_38_3(il[406]) - , poseidon2_B_39_0(il[407]) - , poseidon2_B_39_1(il[408]) - , poseidon2_B_39_2(il[409]) - , poseidon2_B_39_3(il[410]) - , poseidon2_B_40_0(il[411]) - , poseidon2_B_40_1(il[412]) - , poseidon2_B_40_2(il[413]) - , poseidon2_B_40_3(il[414]) - , poseidon2_B_41_0(il[415]) - , poseidon2_B_41_1(il[416]) - , poseidon2_B_41_2(il[417]) - , poseidon2_B_41_3(il[418]) - , poseidon2_B_42_0(il[419]) - , poseidon2_B_42_1(il[420]) - , poseidon2_B_42_2(il[421]) - , poseidon2_B_42_3(il[422]) - , poseidon2_B_43_0(il[423]) - , poseidon2_B_43_1(il[424]) - , poseidon2_B_43_2(il[425]) - , poseidon2_B_43_3(il[426]) - , poseidon2_B_44_0(il[427]) - , poseidon2_B_44_1(il[428]) - , poseidon2_B_44_2(il[429]) - , poseidon2_B_44_3(il[430]) - , poseidon2_B_45_0(il[431]) - , poseidon2_B_45_1(il[432]) - , poseidon2_B_45_2(il[433]) - , poseidon2_B_45_3(il[434]) - , poseidon2_B_46_0(il[435]) - , poseidon2_B_46_1(il[436]) - , poseidon2_B_46_2(il[437]) - , poseidon2_B_46_3(il[438]) - , poseidon2_B_47_0(il[439]) - , poseidon2_B_47_1(il[440]) - , poseidon2_B_47_2(il[441]) - , poseidon2_B_47_3(il[442]) - , poseidon2_B_48_0(il[443]) - , poseidon2_B_48_1(il[444]) - , poseidon2_B_48_2(il[445]) - , poseidon2_B_48_3(il[446]) - , poseidon2_B_49_0(il[447]) - , poseidon2_B_49_1(il[448]) - , poseidon2_B_49_2(il[449]) - , poseidon2_B_49_3(il[450]) - , poseidon2_B_4_0(il[451]) - , poseidon2_B_4_1(il[452]) - , poseidon2_B_4_2(il[453]) - , poseidon2_B_4_3(il[454]) - , poseidon2_B_50_0(il[455]) - , poseidon2_B_50_1(il[456]) - , poseidon2_B_50_2(il[457]) - , poseidon2_B_50_3(il[458]) - , poseidon2_B_51_0(il[459]) - , poseidon2_B_51_1(il[460]) - , poseidon2_B_51_2(il[461]) - , poseidon2_B_51_3(il[462]) - , poseidon2_B_52_0(il[463]) - , poseidon2_B_52_1(il[464]) - , poseidon2_B_52_2(il[465]) - , poseidon2_B_52_3(il[466]) - , poseidon2_B_53_0(il[467]) - , poseidon2_B_53_1(il[468]) - , poseidon2_B_53_2(il[469]) - , poseidon2_B_53_3(il[470]) - , poseidon2_B_54_0(il[471]) - , poseidon2_B_54_1(il[472]) - , poseidon2_B_54_2(il[473]) - , poseidon2_B_54_3(il[474]) - , poseidon2_B_55_0(il[475]) - , poseidon2_B_55_1(il[476]) - , poseidon2_B_55_2(il[477]) - , poseidon2_B_55_3(il[478]) - , poseidon2_B_56_0(il[479]) - , poseidon2_B_56_1(il[480]) - , poseidon2_B_56_2(il[481]) - , poseidon2_B_56_3(il[482]) - , poseidon2_B_57_0(il[483]) - , poseidon2_B_57_1(il[484]) - , poseidon2_B_57_2(il[485]) - , poseidon2_B_57_3(il[486]) - , poseidon2_B_58_0(il[487]) - , poseidon2_B_58_1(il[488]) - , poseidon2_B_58_2(il[489]) - , poseidon2_B_58_3(il[490]) - , poseidon2_B_59_0(il[491]) - , poseidon2_B_59_1(il[492]) - , poseidon2_B_59_2(il[493]) - , poseidon2_B_59_3(il[494]) - , poseidon2_B_5_0(il[495]) - , poseidon2_B_5_1(il[496]) - , poseidon2_B_5_2(il[497]) - , poseidon2_B_5_3(il[498]) - , poseidon2_B_6_0(il[499]) - , poseidon2_B_6_1(il[500]) - , poseidon2_B_6_2(il[501]) - , poseidon2_B_6_3(il[502]) - , poseidon2_B_7_0(il[503]) - , poseidon2_B_7_1(il[504]) - , poseidon2_B_7_2(il[505]) - , poseidon2_B_7_3(il[506]) - , poseidon2_B_8_0(il[507]) - , poseidon2_B_8_1(il[508]) - , poseidon2_B_8_2(il[509]) - , poseidon2_B_8_3(il[510]) - , poseidon2_B_9_0(il[511]) - , poseidon2_B_9_1(il[512]) - , poseidon2_B_9_2(il[513]) - , poseidon2_B_9_3(il[514]) - , poseidon2_EXT_LAYER_4(il[515]) - , poseidon2_EXT_LAYER_5(il[516]) - , poseidon2_EXT_LAYER_6(il[517]) - , poseidon2_EXT_LAYER_7(il[518]) - , poseidon2_T_0_4(il[519]) - , poseidon2_T_0_5(il[520]) - , poseidon2_T_0_6(il[521]) - , poseidon2_T_0_7(il[522]) - , poseidon2_T_1_4(il[523]) - , poseidon2_T_1_5(il[524]) - , poseidon2_T_1_6(il[525]) - , poseidon2_T_1_7(il[526]) - , poseidon2_T_2_4(il[527]) - , poseidon2_T_2_5(il[528]) - , poseidon2_T_2_6(il[529]) - , poseidon2_T_2_7(il[530]) - , poseidon2_T_3_4(il[531]) - , poseidon2_T_3_5(il[532]) - , poseidon2_T_3_6(il[533]) - , poseidon2_T_3_7(il[534]) - , poseidon2_T_60_4(il[535]) - , poseidon2_T_60_5(il[536]) - , poseidon2_T_60_6(il[537]) - , poseidon2_T_60_7(il[538]) - , poseidon2_T_61_4(il[539]) - , poseidon2_T_61_5(il[540]) - , poseidon2_T_61_6(il[541]) - , poseidon2_T_61_7(il[542]) - , poseidon2_T_62_4(il[543]) - , poseidon2_T_62_5(il[544]) - , poseidon2_T_62_6(il[545]) - , poseidon2_T_62_7(il[546]) - , poseidon2_T_63_4(il[547]) - , poseidon2_T_63_5(il[548]) - , poseidon2_T_63_6(il[549]) - , poseidon2_T_63_7(il[550]) - , poseidon2_a_0(il[551]) - , poseidon2_a_1(il[552]) - , poseidon2_a_2(il[553]) - , poseidon2_a_3(il[554]) - , poseidon2_b_0(il[555]) - , poseidon2_b_1(il[556]) - , poseidon2_b_2(il[557]) - , poseidon2_b_3(il[558]) - , poseidon2_clk(il[559]) - , poseidon2_input_addr(il[560]) - , poseidon2_mem_addr_read_a(il[561]) - , poseidon2_mem_addr_read_b(il[562]) - , poseidon2_mem_addr_read_c(il[563]) - , poseidon2_mem_addr_read_d(il[564]) - , poseidon2_mem_addr_write_a(il[565]) - , poseidon2_mem_addr_write_b(il[566]) - , poseidon2_mem_addr_write_c(il[567]) - , poseidon2_mem_addr_write_d(il[568]) - , poseidon2_output_addr(il[569]) - , poseidon2_sel_poseidon_perm(il[570]) - , range_check_alu_rng_chk(il[571]) - , range_check_clk(il[572]) - , range_check_cmp_hi_bits_rng_chk(il[573]) - , range_check_cmp_lo_bits_rng_chk(il[574]) - , range_check_dyn_diff(il[575]) - , range_check_dyn_rng_chk_bits(il[576]) - , range_check_dyn_rng_chk_pow_2(il[577]) - , range_check_gas_da_rng_chk(il[578]) - , range_check_gas_l2_rng_chk(il[579]) - , range_check_is_lte_u112(il[580]) - , range_check_is_lte_u128(il[581]) - , range_check_is_lte_u16(il[582]) - , range_check_is_lte_u32(il[583]) - , range_check_is_lte_u48(il[584]) - , range_check_is_lte_u64(il[585]) - , range_check_is_lte_u80(il[586]) - , range_check_is_lte_u96(il[587]) - , range_check_mem_rng_chk(il[588]) - , range_check_rng_chk_bits(il[589]) - , range_check_sel_lookup_0(il[590]) - , range_check_sel_lookup_1(il[591]) - , range_check_sel_lookup_2(il[592]) - , range_check_sel_lookup_3(il[593]) - , range_check_sel_lookup_4(il[594]) - , range_check_sel_lookup_5(il[595]) - , range_check_sel_lookup_6(il[596]) - , range_check_sel_rng_chk(il[597]) - , range_check_u16_r0(il[598]) - , range_check_u16_r1(il[599]) - , range_check_u16_r2(il[600]) - , range_check_u16_r3(il[601]) - , range_check_u16_r4(il[602]) - , range_check_u16_r5(il[603]) - , range_check_u16_r6(il[604]) - , range_check_u16_r7(il[605]) - , range_check_value(il[606]) - , sha256_clk(il[607]) - , sha256_input(il[608]) - , sha256_output(il[609]) - , sha256_sel_sha256_compression(il[610]) - , sha256_state(il[611]) - , slice_addr(il[612]) - , slice_clk(il[613]) - , slice_cnt(il[614]) - , slice_col_offset(il[615]) - , slice_one_min_inv(il[616]) - , slice_sel_cd_cpy(il[617]) - , slice_sel_mem_active(il[618]) - , slice_sel_return(il[619]) - , slice_sel_start(il[620]) - , slice_space_id(il[621]) - , slice_val(il[622]) - , lookup_rng_chk_pow_2_counts(il[623]) - , lookup_rng_chk_diff_counts(il[624]) - , lookup_rng_chk_0_counts(il[625]) - , lookup_rng_chk_1_counts(il[626]) - , lookup_rng_chk_2_counts(il[627]) - , lookup_rng_chk_3_counts(il[628]) - , lookup_rng_chk_4_counts(il[629]) - , lookup_rng_chk_5_counts(il[630]) - , lookup_rng_chk_6_counts(il[631]) - , lookup_rng_chk_7_counts(il[632]) - , lookup_pow_2_0_counts(il[633]) - , lookup_pow_2_1_counts(il[634]) - , lookup_byte_lengths_counts(il[635]) - , lookup_byte_operations_counts(il[636]) - , lookup_opcode_gas_counts(il[637]) - , kernel_output_lookup_counts(il[638]) - , lookup_into_kernel_counts(il[639]) - , lookup_cd_value_counts(il[640]) - , lookup_ret_value_counts(il[641]) - , incl_main_tag_err_counts(il[642]) - , incl_mem_tag_err_counts(il[643]) - , perm_rng_mem_inv(il[644]) - , perm_rng_cmp_lo_inv(il[645]) - , perm_rng_cmp_hi_inv(il[646]) - , perm_rng_alu_inv(il[647]) - , perm_cmp_alu_inv(il[648]) - , perm_rng_gas_l2_inv(il[649]) - , perm_rng_gas_da_inv(il[650]) - , perm_pos_mem_read_a_inv(il[651]) - , perm_pos_mem_read_b_inv(il[652]) - , perm_pos_mem_read_c_inv(il[653]) - , perm_pos_mem_read_d_inv(il[654]) - , perm_pos_mem_write_a_inv(il[655]) - , perm_pos_mem_write_b_inv(il[656]) - , perm_pos_mem_write_c_inv(il[657]) - , perm_pos_mem_write_d_inv(il[658]) - , perm_slice_mem_inv(il[659]) - , perm_main_alu_inv(il[660]) - , perm_main_bin_inv(il[661]) - , perm_main_conv_inv(il[662]) - , perm_main_pos2_perm_inv(il[663]) - , perm_main_pedersen_inv(il[664]) - , perm_main_slice_inv(il[665]) - , perm_main_mem_a_inv(il[666]) - , perm_main_mem_b_inv(il[667]) - , perm_main_mem_c_inv(il[668]) - , perm_main_mem_d_inv(il[669]) - , perm_main_mem_ind_addr_a_inv(il[670]) - , perm_main_mem_ind_addr_b_inv(il[671]) - , perm_main_mem_ind_addr_c_inv(il[672]) - , perm_main_mem_ind_addr_d_inv(il[673]) - , lookup_rng_chk_pow_2_inv(il[674]) - , lookup_rng_chk_diff_inv(il[675]) - , lookup_rng_chk_0_inv(il[676]) - , lookup_rng_chk_1_inv(il[677]) - , lookup_rng_chk_2_inv(il[678]) - , lookup_rng_chk_3_inv(il[679]) - , lookup_rng_chk_4_inv(il[680]) - , lookup_rng_chk_5_inv(il[681]) - , lookup_rng_chk_6_inv(il[682]) - , lookup_rng_chk_7_inv(il[683]) - , lookup_pow_2_0_inv(il[684]) - , lookup_pow_2_1_inv(il[685]) - , lookup_byte_lengths_inv(il[686]) - , lookup_byte_operations_inv(il[687]) - , lookup_opcode_gas_inv(il[688]) - , kernel_output_lookup_inv(il[689]) - , lookup_into_kernel_inv(il[690]) - , lookup_cd_value_inv(il[691]) - , lookup_ret_value_inv(il[692]) - , incl_main_tag_err_inv(il[693]) - , incl_mem_tag_err_inv(il[694]) - , binary_acc_ia_shift(il[695]) - , binary_acc_ib_shift(il[696]) - , binary_acc_ic_shift(il[697]) - , binary_mem_tag_ctr_shift(il[698]) - , binary_op_id_shift(il[699]) - , cmp_a_hi_shift(il[700]) - , cmp_a_lo_shift(il[701]) - , cmp_b_hi_shift(il[702]) - , cmp_b_lo_shift(il[703]) - , cmp_cmp_rng_ctr_shift(il[704]) - , cmp_op_gt_shift(il[705]) - , cmp_p_sub_a_hi_shift(il[706]) - , cmp_p_sub_a_lo_shift(il[707]) - , cmp_p_sub_b_hi_shift(il[708]) - , cmp_p_sub_b_lo_shift(il[709]) - , cmp_sel_rng_chk_shift(il[710]) - , main_da_gas_remaining_shift(il[711]) - , main_emit_l2_to_l1_msg_write_offset_shift(il[712]) - , main_emit_note_hash_write_offset_shift(il[713]) - , main_emit_nullifier_write_offset_shift(il[714]) - , main_emit_unencrypted_log_write_offset_shift(il[715]) - , main_internal_return_ptr_shift(il[716]) - , main_l1_to_l2_msg_exists_write_offset_shift(il[717]) - , main_l2_gas_remaining_shift(il[718]) - , main_note_hash_exist_write_offset_shift(il[719]) - , main_nullifier_exists_write_offset_shift(il[720]) - , main_nullifier_non_exists_write_offset_shift(il[721]) - , main_pc_shift(il[722]) - , main_sel_execution_row_shift(il[723]) - , main_sload_write_offset_shift(il[724]) - , main_sstore_write_offset_shift(il[725]) - , mem_glob_addr_shift(il[726]) - , mem_rw_shift(il[727]) - , mem_sel_mem_shift(il[728]) - , mem_tag_shift(il[729]) - , mem_tsp_shift(il[730]) - , mem_val_shift(il[731]) - , slice_addr_shift(il[732]) - , slice_clk_shift(il[733]) - , slice_cnt_shift(il[734]) - , slice_col_offset_shift(il[735]) - , slice_sel_cd_cpy_shift(il[736]) - , slice_sel_mem_active_shift(il[737]) - , slice_sel_return_shift(il[738]) - , slice_sel_start_shift(il[739]) - , slice_space_id_shift(il[740]) + , alu_u1_tag(il[65]) + , alu_u32_tag(il[66]) + , alu_u64_tag(il[67]) + , alu_u8_tag(il[68]) + , alu_zero_shift(il[69]) + , binary_acc_ia(il[70]) + , binary_acc_ib(il[71]) + , binary_acc_ic(il[72]) + , binary_clk(il[73]) + , binary_ia_bytes(il[74]) + , binary_ib_bytes(il[75]) + , binary_ic_bytes(il[76]) + , binary_in_tag(il[77]) + , binary_mem_tag_ctr(il[78]) + , binary_mem_tag_ctr_inv(il[79]) + , binary_op_id(il[80]) + , binary_sel_bin(il[81]) + , binary_start(il[82]) + , cmp_a_hi(il[83]) + , cmp_a_lo(il[84]) + , cmp_b_hi(il[85]) + , cmp_b_lo(il[86]) + , cmp_borrow(il[87]) + , cmp_clk(il[88]) + , cmp_cmp_rng_ctr(il[89]) + , cmp_input_a(il[90]) + , cmp_input_b(il[91]) + , cmp_op_eq(il[92]) + , cmp_op_eq_diff_inv(il[93]) + , cmp_op_gt(il[94]) + , cmp_p_a_borrow(il[95]) + , cmp_p_b_borrow(il[96]) + , cmp_p_sub_a_hi(il[97]) + , cmp_p_sub_a_lo(il[98]) + , cmp_p_sub_b_hi(il[99]) + , cmp_p_sub_b_lo(il[100]) + , cmp_range_chk_clk(il[101]) + , cmp_res_hi(il[102]) + , cmp_res_lo(il[103]) + , cmp_result(il[104]) + , cmp_sel_cmp(il[105]) + , cmp_sel_rng_chk(il[106]) + , cmp_shift_sel(il[107]) + , conversion_clk(il[108]) + , conversion_input(il[109]) + , conversion_num_limbs(il[110]) + , conversion_output_bits(il[111]) + , conversion_radix(il[112]) + , conversion_sel_to_radix_le(il[113]) + , keccakf1600_clk(il[114]) + , keccakf1600_input(il[115]) + , keccakf1600_output(il[116]) + , keccakf1600_sel_keccakf1600(il[117]) + , main_abs_da_rem_gas(il[118]) + , main_abs_l2_rem_gas(il[119]) + , main_alu_in_tag(il[120]) + , main_base_da_gas_op_cost(il[121]) + , main_base_l2_gas_op_cost(il[122]) + , main_bin_op_id(il[123]) + , main_call_ptr(il[124]) + , main_da_gas_remaining(il[125]) + , main_da_out_of_gas(il[126]) + , main_dyn_da_gas_op_cost(il[127]) + , main_dyn_gas_multiplier(il[128]) + , main_dyn_l2_gas_op_cost(il[129]) + , main_emit_l2_to_l1_msg_write_offset(il[130]) + , main_emit_note_hash_write_offset(il[131]) + , main_emit_nullifier_write_offset(il[132]) + , main_emit_unencrypted_log_write_offset(il[133]) + , main_ia(il[134]) + , main_ib(il[135]) + , main_ic(il[136]) + , main_id(il[137]) + , main_id_zero(il[138]) + , main_ind_addr_a(il[139]) + , main_ind_addr_b(il[140]) + , main_ind_addr_c(il[141]) + , main_ind_addr_d(il[142]) + , main_internal_return_ptr(il[143]) + , main_inv(il[144]) + , main_kernel_in_offset(il[145]) + , main_kernel_out_offset(il[146]) + , main_l1_to_l2_msg_exists_write_offset(il[147]) + , main_l2_gas_remaining(il[148]) + , main_l2_out_of_gas(il[149]) + , main_mem_addr_a(il[150]) + , main_mem_addr_b(il[151]) + , main_mem_addr_c(il[152]) + , main_mem_addr_d(il[153]) + , main_note_hash_exist_write_offset(il[154]) + , main_nullifier_exists_write_offset(il[155]) + , main_nullifier_non_exists_write_offset(il[156]) + , main_op_err(il[157]) + , main_opcode_val(il[158]) + , main_pc(il[159]) + , main_r_in_tag(il[160]) + , main_rwa(il[161]) + , main_rwb(il[162]) + , main_rwc(il[163]) + , main_rwd(il[164]) + , main_sel_alu(il[165]) + , main_sel_bin(il[166]) + , main_sel_calldata(il[167]) + , main_sel_execution_row(il[168]) + , main_sel_kernel_inputs(il[169]) + , main_sel_kernel_out(il[170]) + , main_sel_last(il[171]) + , main_sel_mem_op_a(il[172]) + , main_sel_mem_op_b(il[173]) + , main_sel_mem_op_c(il[174]) + , main_sel_mem_op_d(il[175]) + , main_sel_mov_ia_to_ic(il[176]) + , main_sel_mov_ib_to_ic(il[177]) + , main_sel_op_add(il[178]) + , main_sel_op_address(il[179]) + , main_sel_op_and(il[180]) + , main_sel_op_block_number(il[181]) + , main_sel_op_calldata_copy(il[182]) + , main_sel_op_cast(il[183]) + , main_sel_op_chain_id(il[184]) + , main_sel_op_cmov(il[185]) + , main_sel_op_dagasleft(il[186]) + , main_sel_op_div(il[187]) + , main_sel_op_ecadd(il[188]) + , main_sel_op_emit_l2_to_l1_msg(il[189]) + , main_sel_op_emit_note_hash(il[190]) + , main_sel_op_emit_nullifier(il[191]) + , main_sel_op_emit_unencrypted_log(il[192]) + , main_sel_op_eq(il[193]) + , main_sel_op_external_call(il[194]) + , main_sel_op_external_return(il[195]) + , main_sel_op_external_revert(il[196]) + , main_sel_op_fdiv(il[197]) + , main_sel_op_fee_per_da_gas(il[198]) + , main_sel_op_fee_per_l2_gas(il[199]) + , main_sel_op_function_selector(il[200]) + , main_sel_op_get_contract_instance(il[201]) + , main_sel_op_internal_call(il[202]) + , main_sel_op_internal_return(il[203]) + , main_sel_op_jump(il[204]) + , main_sel_op_jumpi(il[205]) + , main_sel_op_keccak(il[206]) + , main_sel_op_l1_to_l2_msg_exists(il[207]) + , main_sel_op_l2gasleft(il[208]) + , main_sel_op_lt(il[209]) + , main_sel_op_lte(il[210]) + , main_sel_op_mov(il[211]) + , main_sel_op_msm(il[212]) + , main_sel_op_mul(il[213]) + , main_sel_op_not(il[214]) + , main_sel_op_note_hash_exists(il[215]) + , main_sel_op_nullifier_exists(il[216]) + , main_sel_op_or(il[217]) + , main_sel_op_pedersen(il[218]) + , main_sel_op_pedersen_commit(il[219]) + , main_sel_op_poseidon2(il[220]) + , main_sel_op_radix_le(il[221]) + , main_sel_op_sender(il[222]) + , main_sel_op_set(il[223]) + , main_sel_op_sha256(il[224]) + , main_sel_op_shl(il[225]) + , main_sel_op_shr(il[226]) + , main_sel_op_sload(il[227]) + , main_sel_op_sstore(il[228]) + , main_sel_op_storage_address(il[229]) + , main_sel_op_sub(il[230]) + , main_sel_op_timestamp(il[231]) + , main_sel_op_transaction_fee(il[232]) + , main_sel_op_version(il[233]) + , main_sel_op_xor(il[234]) + , main_sel_q_kernel_lookup(il[235]) + , main_sel_q_kernel_output_lookup(il[236]) + , main_sel_resolve_ind_addr_a(il[237]) + , main_sel_resolve_ind_addr_b(il[238]) + , main_sel_resolve_ind_addr_c(il[239]) + , main_sel_resolve_ind_addr_d(il[240]) + , main_sel_returndata(il[241]) + , main_sel_rng_16(il[242]) + , main_sel_rng_8(il[243]) + , main_sel_slice_gadget(il[244]) + , main_side_effect_counter(il[245]) + , main_sload_write_offset(il[246]) + , main_space_id(il[247]) + , main_sstore_write_offset(il[248]) + , main_tag_err(il[249]) + , main_w_in_tag(il[250]) + , mem_addr(il[251]) + , mem_clk(il[252]) + , mem_diff(il[253]) + , mem_glob_addr(il[254]) + , mem_last(il[255]) + , mem_lastAccess(il[256]) + , mem_one_min_inv(il[257]) + , mem_r_in_tag(il[258]) + , mem_rw(il[259]) + , mem_sel_mem(il[260]) + , mem_sel_mov_ia_to_ic(il[261]) + , mem_sel_mov_ib_to_ic(il[262]) + , mem_sel_op_a(il[263]) + , mem_sel_op_b(il[264]) + , mem_sel_op_c(il[265]) + , mem_sel_op_cmov(il[266]) + , mem_sel_op_d(il[267]) + , mem_sel_op_poseidon_read_a(il[268]) + , mem_sel_op_poseidon_read_b(il[269]) + , mem_sel_op_poseidon_read_c(il[270]) + , mem_sel_op_poseidon_read_d(il[271]) + , mem_sel_op_poseidon_write_a(il[272]) + , mem_sel_op_poseidon_write_b(il[273]) + , mem_sel_op_poseidon_write_c(il[274]) + , mem_sel_op_poseidon_write_d(il[275]) + , mem_sel_op_slice(il[276]) + , mem_sel_resolve_ind_addr_a(il[277]) + , mem_sel_resolve_ind_addr_b(il[278]) + , mem_sel_resolve_ind_addr_c(il[279]) + , mem_sel_resolve_ind_addr_d(il[280]) + , mem_sel_rng_chk(il[281]) + , mem_skip_check_tag(il[282]) + , mem_space_id(il[283]) + , mem_tag(il[284]) + , mem_tag_err(il[285]) + , mem_tsp(il[286]) + , mem_val(il[287]) + , mem_w_in_tag(il[288]) + , pedersen_clk(il[289]) + , pedersen_input(il[290]) + , pedersen_output(il[291]) + , pedersen_sel_pedersen(il[292]) + , poseidon2_B_10_0(il[293]) + , poseidon2_B_10_1(il[294]) + , poseidon2_B_10_2(il[295]) + , poseidon2_B_10_3(il[296]) + , poseidon2_B_11_0(il[297]) + , poseidon2_B_11_1(il[298]) + , poseidon2_B_11_2(il[299]) + , poseidon2_B_11_3(il[300]) + , poseidon2_B_12_0(il[301]) + , poseidon2_B_12_1(il[302]) + , poseidon2_B_12_2(il[303]) + , poseidon2_B_12_3(il[304]) + , poseidon2_B_13_0(il[305]) + , poseidon2_B_13_1(il[306]) + , poseidon2_B_13_2(il[307]) + , poseidon2_B_13_3(il[308]) + , poseidon2_B_14_0(il[309]) + , poseidon2_B_14_1(il[310]) + , poseidon2_B_14_2(il[311]) + , poseidon2_B_14_3(il[312]) + , poseidon2_B_15_0(il[313]) + , poseidon2_B_15_1(il[314]) + , poseidon2_B_15_2(il[315]) + , poseidon2_B_15_3(il[316]) + , poseidon2_B_16_0(il[317]) + , poseidon2_B_16_1(il[318]) + , poseidon2_B_16_2(il[319]) + , poseidon2_B_16_3(il[320]) + , poseidon2_B_17_0(il[321]) + , poseidon2_B_17_1(il[322]) + , poseidon2_B_17_2(il[323]) + , poseidon2_B_17_3(il[324]) + , poseidon2_B_18_0(il[325]) + , poseidon2_B_18_1(il[326]) + , poseidon2_B_18_2(il[327]) + , poseidon2_B_18_3(il[328]) + , poseidon2_B_19_0(il[329]) + , poseidon2_B_19_1(il[330]) + , poseidon2_B_19_2(il[331]) + , poseidon2_B_19_3(il[332]) + , poseidon2_B_20_0(il[333]) + , poseidon2_B_20_1(il[334]) + , poseidon2_B_20_2(il[335]) + , poseidon2_B_20_3(il[336]) + , poseidon2_B_21_0(il[337]) + , poseidon2_B_21_1(il[338]) + , poseidon2_B_21_2(il[339]) + , poseidon2_B_21_3(il[340]) + , poseidon2_B_22_0(il[341]) + , poseidon2_B_22_1(il[342]) + , poseidon2_B_22_2(il[343]) + , poseidon2_B_22_3(il[344]) + , poseidon2_B_23_0(il[345]) + , poseidon2_B_23_1(il[346]) + , poseidon2_B_23_2(il[347]) + , poseidon2_B_23_3(il[348]) + , poseidon2_B_24_0(il[349]) + , poseidon2_B_24_1(il[350]) + , poseidon2_B_24_2(il[351]) + , poseidon2_B_24_3(il[352]) + , poseidon2_B_25_0(il[353]) + , poseidon2_B_25_1(il[354]) + , poseidon2_B_25_2(il[355]) + , poseidon2_B_25_3(il[356]) + , poseidon2_B_26_0(il[357]) + , poseidon2_B_26_1(il[358]) + , poseidon2_B_26_2(il[359]) + , poseidon2_B_26_3(il[360]) + , poseidon2_B_27_0(il[361]) + , poseidon2_B_27_1(il[362]) + , poseidon2_B_27_2(il[363]) + , poseidon2_B_27_3(il[364]) + , poseidon2_B_28_0(il[365]) + , poseidon2_B_28_1(il[366]) + , poseidon2_B_28_2(il[367]) + , poseidon2_B_28_3(il[368]) + , poseidon2_B_29_0(il[369]) + , poseidon2_B_29_1(il[370]) + , poseidon2_B_29_2(il[371]) + , poseidon2_B_29_3(il[372]) + , poseidon2_B_30_0(il[373]) + , poseidon2_B_30_1(il[374]) + , poseidon2_B_30_2(il[375]) + , poseidon2_B_30_3(il[376]) + , poseidon2_B_31_0(il[377]) + , poseidon2_B_31_1(il[378]) + , poseidon2_B_31_2(il[379]) + , poseidon2_B_31_3(il[380]) + , poseidon2_B_32_0(il[381]) + , poseidon2_B_32_1(il[382]) + , poseidon2_B_32_2(il[383]) + , poseidon2_B_32_3(il[384]) + , poseidon2_B_33_0(il[385]) + , poseidon2_B_33_1(il[386]) + , poseidon2_B_33_2(il[387]) + , poseidon2_B_33_3(il[388]) + , poseidon2_B_34_0(il[389]) + , poseidon2_B_34_1(il[390]) + , poseidon2_B_34_2(il[391]) + , poseidon2_B_34_3(il[392]) + , poseidon2_B_35_0(il[393]) + , poseidon2_B_35_1(il[394]) + , poseidon2_B_35_2(il[395]) + , poseidon2_B_35_3(il[396]) + , poseidon2_B_36_0(il[397]) + , poseidon2_B_36_1(il[398]) + , poseidon2_B_36_2(il[399]) + , poseidon2_B_36_3(il[400]) + , poseidon2_B_37_0(il[401]) + , poseidon2_B_37_1(il[402]) + , poseidon2_B_37_2(il[403]) + , poseidon2_B_37_3(il[404]) + , poseidon2_B_38_0(il[405]) + , poseidon2_B_38_1(il[406]) + , poseidon2_B_38_2(il[407]) + , poseidon2_B_38_3(il[408]) + , poseidon2_B_39_0(il[409]) + , poseidon2_B_39_1(il[410]) + , poseidon2_B_39_2(il[411]) + , poseidon2_B_39_3(il[412]) + , poseidon2_B_40_0(il[413]) + , poseidon2_B_40_1(il[414]) + , poseidon2_B_40_2(il[415]) + , poseidon2_B_40_3(il[416]) + , poseidon2_B_41_0(il[417]) + , poseidon2_B_41_1(il[418]) + , poseidon2_B_41_2(il[419]) + , poseidon2_B_41_3(il[420]) + , poseidon2_B_42_0(il[421]) + , poseidon2_B_42_1(il[422]) + , poseidon2_B_42_2(il[423]) + , poseidon2_B_42_3(il[424]) + , poseidon2_B_43_0(il[425]) + , poseidon2_B_43_1(il[426]) + , poseidon2_B_43_2(il[427]) + , poseidon2_B_43_3(il[428]) + , poseidon2_B_44_0(il[429]) + , poseidon2_B_44_1(il[430]) + , poseidon2_B_44_2(il[431]) + , poseidon2_B_44_3(il[432]) + , poseidon2_B_45_0(il[433]) + , poseidon2_B_45_1(il[434]) + , poseidon2_B_45_2(il[435]) + , poseidon2_B_45_3(il[436]) + , poseidon2_B_46_0(il[437]) + , poseidon2_B_46_1(il[438]) + , poseidon2_B_46_2(il[439]) + , poseidon2_B_46_3(il[440]) + , poseidon2_B_47_0(il[441]) + , poseidon2_B_47_1(il[442]) + , poseidon2_B_47_2(il[443]) + , poseidon2_B_47_3(il[444]) + , poseidon2_B_48_0(il[445]) + , poseidon2_B_48_1(il[446]) + , poseidon2_B_48_2(il[447]) + , poseidon2_B_48_3(il[448]) + , poseidon2_B_49_0(il[449]) + , poseidon2_B_49_1(il[450]) + , poseidon2_B_49_2(il[451]) + , poseidon2_B_49_3(il[452]) + , poseidon2_B_4_0(il[453]) + , poseidon2_B_4_1(il[454]) + , poseidon2_B_4_2(il[455]) + , poseidon2_B_4_3(il[456]) + , poseidon2_B_50_0(il[457]) + , poseidon2_B_50_1(il[458]) + , poseidon2_B_50_2(il[459]) + , poseidon2_B_50_3(il[460]) + , poseidon2_B_51_0(il[461]) + , poseidon2_B_51_1(il[462]) + , poseidon2_B_51_2(il[463]) + , poseidon2_B_51_3(il[464]) + , poseidon2_B_52_0(il[465]) + , poseidon2_B_52_1(il[466]) + , poseidon2_B_52_2(il[467]) + , poseidon2_B_52_3(il[468]) + , poseidon2_B_53_0(il[469]) + , poseidon2_B_53_1(il[470]) + , poseidon2_B_53_2(il[471]) + , poseidon2_B_53_3(il[472]) + , poseidon2_B_54_0(il[473]) + , poseidon2_B_54_1(il[474]) + , poseidon2_B_54_2(il[475]) + , poseidon2_B_54_3(il[476]) + , poseidon2_B_55_0(il[477]) + , poseidon2_B_55_1(il[478]) + , poseidon2_B_55_2(il[479]) + , poseidon2_B_55_3(il[480]) + , poseidon2_B_56_0(il[481]) + , poseidon2_B_56_1(il[482]) + , poseidon2_B_56_2(il[483]) + , poseidon2_B_56_3(il[484]) + , poseidon2_B_57_0(il[485]) + , poseidon2_B_57_1(il[486]) + , poseidon2_B_57_2(il[487]) + , poseidon2_B_57_3(il[488]) + , poseidon2_B_58_0(il[489]) + , poseidon2_B_58_1(il[490]) + , poseidon2_B_58_2(il[491]) + , poseidon2_B_58_3(il[492]) + , poseidon2_B_59_0(il[493]) + , poseidon2_B_59_1(il[494]) + , poseidon2_B_59_2(il[495]) + , poseidon2_B_59_3(il[496]) + , poseidon2_B_5_0(il[497]) + , poseidon2_B_5_1(il[498]) + , poseidon2_B_5_2(il[499]) + , poseidon2_B_5_3(il[500]) + , poseidon2_B_6_0(il[501]) + , poseidon2_B_6_1(il[502]) + , poseidon2_B_6_2(il[503]) + , poseidon2_B_6_3(il[504]) + , poseidon2_B_7_0(il[505]) + , poseidon2_B_7_1(il[506]) + , poseidon2_B_7_2(il[507]) + , poseidon2_B_7_3(il[508]) + , poseidon2_B_8_0(il[509]) + , poseidon2_B_8_1(il[510]) + , poseidon2_B_8_2(il[511]) + , poseidon2_B_8_3(il[512]) + , poseidon2_B_9_0(il[513]) + , poseidon2_B_9_1(il[514]) + , poseidon2_B_9_2(il[515]) + , poseidon2_B_9_3(il[516]) + , poseidon2_EXT_LAYER_4(il[517]) + , poseidon2_EXT_LAYER_5(il[518]) + , poseidon2_EXT_LAYER_6(il[519]) + , poseidon2_EXT_LAYER_7(il[520]) + , poseidon2_T_0_4(il[521]) + , poseidon2_T_0_5(il[522]) + , poseidon2_T_0_6(il[523]) + , poseidon2_T_0_7(il[524]) + , poseidon2_T_1_4(il[525]) + , poseidon2_T_1_5(il[526]) + , poseidon2_T_1_6(il[527]) + , poseidon2_T_1_7(il[528]) + , poseidon2_T_2_4(il[529]) + , poseidon2_T_2_5(il[530]) + , poseidon2_T_2_6(il[531]) + , poseidon2_T_2_7(il[532]) + , poseidon2_T_3_4(il[533]) + , poseidon2_T_3_5(il[534]) + , poseidon2_T_3_6(il[535]) + , poseidon2_T_3_7(il[536]) + , poseidon2_T_60_4(il[537]) + , poseidon2_T_60_5(il[538]) + , poseidon2_T_60_6(il[539]) + , poseidon2_T_60_7(il[540]) + , poseidon2_T_61_4(il[541]) + , poseidon2_T_61_5(il[542]) + , poseidon2_T_61_6(il[543]) + , poseidon2_T_61_7(il[544]) + , poseidon2_T_62_4(il[545]) + , poseidon2_T_62_5(il[546]) + , poseidon2_T_62_6(il[547]) + , poseidon2_T_62_7(il[548]) + , poseidon2_T_63_4(il[549]) + , poseidon2_T_63_5(il[550]) + , poseidon2_T_63_6(il[551]) + , poseidon2_T_63_7(il[552]) + , poseidon2_a_0(il[553]) + , poseidon2_a_1(il[554]) + , poseidon2_a_2(il[555]) + , poseidon2_a_3(il[556]) + , poseidon2_b_0(il[557]) + , poseidon2_b_1(il[558]) + , poseidon2_b_2(il[559]) + , poseidon2_b_3(il[560]) + , poseidon2_clk(il[561]) + , poseidon2_input_addr(il[562]) + , poseidon2_mem_addr_read_a(il[563]) + , poseidon2_mem_addr_read_b(il[564]) + , poseidon2_mem_addr_read_c(il[565]) + , poseidon2_mem_addr_read_d(il[566]) + , poseidon2_mem_addr_write_a(il[567]) + , poseidon2_mem_addr_write_b(il[568]) + , poseidon2_mem_addr_write_c(il[569]) + , poseidon2_mem_addr_write_d(il[570]) + , poseidon2_output_addr(il[571]) + , poseidon2_sel_poseidon_perm(il[572]) + , range_check_alu_rng_chk(il[573]) + , range_check_clk(il[574]) + , range_check_cmp_hi_bits_rng_chk(il[575]) + , range_check_cmp_lo_bits_rng_chk(il[576]) + , range_check_dyn_diff(il[577]) + , range_check_dyn_rng_chk_bits(il[578]) + , range_check_dyn_rng_chk_pow_2(il[579]) + , range_check_gas_da_rng_chk(il[580]) + , range_check_gas_l2_rng_chk(il[581]) + , range_check_is_lte_u112(il[582]) + , range_check_is_lte_u128(il[583]) + , range_check_is_lte_u16(il[584]) + , range_check_is_lte_u32(il[585]) + , range_check_is_lte_u48(il[586]) + , range_check_is_lte_u64(il[587]) + , range_check_is_lte_u80(il[588]) + , range_check_is_lte_u96(il[589]) + , range_check_mem_rng_chk(il[590]) + , range_check_rng_chk_bits(il[591]) + , range_check_sel_lookup_0(il[592]) + , range_check_sel_lookup_1(il[593]) + , range_check_sel_lookup_2(il[594]) + , range_check_sel_lookup_3(il[595]) + , range_check_sel_lookup_4(il[596]) + , range_check_sel_lookup_5(il[597]) + , range_check_sel_lookup_6(il[598]) + , range_check_sel_rng_chk(il[599]) + , range_check_u16_r0(il[600]) + , range_check_u16_r1(il[601]) + , range_check_u16_r2(il[602]) + , range_check_u16_r3(il[603]) + , range_check_u16_r4(il[604]) + , range_check_u16_r5(il[605]) + , range_check_u16_r6(il[606]) + , range_check_u16_r7(il[607]) + , range_check_value(il[608]) + , sha256_clk(il[609]) + , sha256_input(il[610]) + , sha256_output(il[611]) + , sha256_sel_sha256_compression(il[612]) + , sha256_state(il[613]) + , slice_addr(il[614]) + , slice_clk(il[615]) + , slice_cnt(il[616]) + , slice_col_offset(il[617]) + , slice_one_min_inv(il[618]) + , slice_sel_cd_cpy(il[619]) + , slice_sel_mem_active(il[620]) + , slice_sel_return(il[621]) + , slice_sel_start(il[622]) + , slice_space_id(il[623]) + , slice_val(il[624]) + , lookup_rng_chk_pow_2_counts(il[625]) + , lookup_rng_chk_diff_counts(il[626]) + , lookup_rng_chk_0_counts(il[627]) + , lookup_rng_chk_1_counts(il[628]) + , lookup_rng_chk_2_counts(il[629]) + , lookup_rng_chk_3_counts(il[630]) + , lookup_rng_chk_4_counts(il[631]) + , lookup_rng_chk_5_counts(il[632]) + , lookup_rng_chk_6_counts(il[633]) + , lookup_rng_chk_7_counts(il[634]) + , lookup_pow_2_0_counts(il[635]) + , lookup_pow_2_1_counts(il[636]) + , lookup_byte_lengths_counts(il[637]) + , lookup_byte_operations_counts(il[638]) + , lookup_opcode_gas_counts(il[639]) + , kernel_output_lookup_counts(il[640]) + , lookup_into_kernel_counts(il[641]) + , lookup_cd_value_counts(il[642]) + , lookup_ret_value_counts(il[643]) + , incl_main_tag_err_counts(il[644]) + , incl_mem_tag_err_counts(il[645]) + , perm_rng_mem_inv(il[646]) + , perm_rng_cmp_lo_inv(il[647]) + , perm_rng_cmp_hi_inv(il[648]) + , perm_rng_alu_inv(il[649]) + , perm_cmp_alu_inv(il[650]) + , perm_rng_gas_l2_inv(il[651]) + , perm_rng_gas_da_inv(il[652]) + , perm_pos_mem_read_a_inv(il[653]) + , perm_pos_mem_read_b_inv(il[654]) + , perm_pos_mem_read_c_inv(il[655]) + , perm_pos_mem_read_d_inv(il[656]) + , perm_pos_mem_write_a_inv(il[657]) + , perm_pos_mem_write_b_inv(il[658]) + , perm_pos_mem_write_c_inv(il[659]) + , perm_pos_mem_write_d_inv(il[660]) + , perm_slice_mem_inv(il[661]) + , perm_main_alu_inv(il[662]) + , perm_main_bin_inv(il[663]) + , perm_main_conv_inv(il[664]) + , perm_main_pos2_perm_inv(il[665]) + , perm_main_pedersen_inv(il[666]) + , perm_main_slice_inv(il[667]) + , perm_main_mem_a_inv(il[668]) + , perm_main_mem_b_inv(il[669]) + , perm_main_mem_c_inv(il[670]) + , perm_main_mem_d_inv(il[671]) + , perm_main_mem_ind_addr_a_inv(il[672]) + , perm_main_mem_ind_addr_b_inv(il[673]) + , perm_main_mem_ind_addr_c_inv(il[674]) + , perm_main_mem_ind_addr_d_inv(il[675]) + , lookup_rng_chk_pow_2_inv(il[676]) + , lookup_rng_chk_diff_inv(il[677]) + , lookup_rng_chk_0_inv(il[678]) + , lookup_rng_chk_1_inv(il[679]) + , lookup_rng_chk_2_inv(il[680]) + , lookup_rng_chk_3_inv(il[681]) + , lookup_rng_chk_4_inv(il[682]) + , lookup_rng_chk_5_inv(il[683]) + , lookup_rng_chk_6_inv(il[684]) + , lookup_rng_chk_7_inv(il[685]) + , lookup_pow_2_0_inv(il[686]) + , lookup_pow_2_1_inv(il[687]) + , lookup_byte_lengths_inv(il[688]) + , lookup_byte_operations_inv(il[689]) + , lookup_opcode_gas_inv(il[690]) + , kernel_output_lookup_inv(il[691]) + , lookup_into_kernel_inv(il[692]) + , lookup_cd_value_inv(il[693]) + , lookup_ret_value_inv(il[694]) + , incl_main_tag_err_inv(il[695]) + , incl_mem_tag_err_inv(il[696]) + , binary_acc_ia_shift(il[697]) + , binary_acc_ib_shift(il[698]) + , binary_acc_ic_shift(il[699]) + , binary_mem_tag_ctr_shift(il[700]) + , binary_op_id_shift(il[701]) + , cmp_a_hi_shift(il[702]) + , cmp_a_lo_shift(il[703]) + , cmp_b_hi_shift(il[704]) + , cmp_b_lo_shift(il[705]) + , cmp_cmp_rng_ctr_shift(il[706]) + , cmp_op_gt_shift(il[707]) + , cmp_p_sub_a_hi_shift(il[708]) + , cmp_p_sub_a_lo_shift(il[709]) + , cmp_p_sub_b_hi_shift(il[710]) + , cmp_p_sub_b_lo_shift(il[711]) + , cmp_sel_rng_chk_shift(il[712]) + , main_da_gas_remaining_shift(il[713]) + , main_emit_l2_to_l1_msg_write_offset_shift(il[714]) + , main_emit_note_hash_write_offset_shift(il[715]) + , main_emit_nullifier_write_offset_shift(il[716]) + , main_emit_unencrypted_log_write_offset_shift(il[717]) + , main_internal_return_ptr_shift(il[718]) + , main_l1_to_l2_msg_exists_write_offset_shift(il[719]) + , main_l2_gas_remaining_shift(il[720]) + , main_note_hash_exist_write_offset_shift(il[721]) + , main_nullifier_exists_write_offset_shift(il[722]) + , main_nullifier_non_exists_write_offset_shift(il[723]) + , main_pc_shift(il[724]) + , main_sel_execution_row_shift(il[725]) + , main_sload_write_offset_shift(il[726]) + , main_sstore_write_offset_shift(il[727]) + , mem_glob_addr_shift(il[728]) + , mem_rw_shift(il[729]) + , mem_sel_mem_shift(il[730]) + , mem_tag_shift(il[731]) + , mem_tsp_shift(il[732]) + , mem_val_shift(il[733]) + , slice_addr_shift(il[734]) + , slice_clk_shift(il[735]) + , slice_cnt_shift(il[736]) + , slice_col_offset_shift(il[737]) + , slice_sel_cd_cpy_shift(il[738]) + , slice_sel_mem_active_shift(il[739]) + , slice_sel_return_shift(il[740]) + , slice_sel_start_shift(il[741]) + , slice_space_id_shift(il[742]) {} AvmFlavor::ProverPolynomials::ProverPolynomials(ProvingKey& proving_key) @@ -827,6 +829,7 @@ AvmFlavor::AllConstRefValues AvmFlavor::ProverPolynomials::get_row(size_t row_id alu_sel_shift_which[row_idx], alu_u128_tag[row_idx], alu_u16_tag[row_idx], + alu_u1_tag[row_idx], alu_u32_tag[row_idx], alu_u64_tag[row_idx], alu_u8_tag[row_idx], @@ -872,6 +875,7 @@ AvmFlavor::AllConstRefValues AvmFlavor::ProverPolynomials::get_row(size_t row_id conversion_clk[row_idx], conversion_input[row_idx], conversion_num_limbs[row_idx], + conversion_output_bits[row_idx], conversion_radix[row_idx], conversion_sel_to_radix_le[row_idx], keccakf1600_clk[row_idx], @@ -1572,6 +1576,7 @@ AvmFlavor::CommitmentLabels::CommitmentLabels() Base::alu_sel_shift_which = "ALU_SEL_SHIFT_WHICH"; Base::alu_u128_tag = "ALU_U128_TAG"; Base::alu_u16_tag = "ALU_U16_TAG"; + Base::alu_u1_tag = "ALU_U1_TAG"; Base::alu_u32_tag = "ALU_U32_TAG"; Base::alu_u64_tag = "ALU_U64_TAG"; Base::alu_u8_tag = "ALU_U8_TAG"; @@ -1617,6 +1622,7 @@ AvmFlavor::CommitmentLabels::CommitmentLabels() Base::conversion_clk = "CONVERSION_CLK"; Base::conversion_input = "CONVERSION_INPUT"; Base::conversion_num_limbs = "CONVERSION_NUM_LIMBS"; + Base::conversion_output_bits = "CONVERSION_OUTPUT_BITS"; Base::conversion_radix = "CONVERSION_RADIX"; Base::conversion_sel_to_radix_le = "CONVERSION_SEL_TO_RADIX_LE"; Base::keccakf1600_clk = "KECCAKF1600_CLK"; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp index 7d3cabeeca8..95008233d50 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/flavor.hpp @@ -89,7 +89,7 @@ template using tuple_cat_t = decltype(std::tuple_cat(std:: // The entities that will be used in the flavor. // clang-format off #define PRECOMPUTED_ENTITIES byte_lookup_sel_bin, byte_lookup_table_byte_lengths, byte_lookup_table_in_tags, byte_lookup_table_input_a, byte_lookup_table_input_b, byte_lookup_table_op_id, byte_lookup_table_output, gas_base_da_gas_fixed_table, gas_base_l2_gas_fixed_table, gas_dyn_da_gas_fixed_table, gas_dyn_l2_gas_fixed_table, gas_sel_gas_cost, main_clk, main_sel_first, main_zeroes, powers_power_of_2 -#define WIRE_ENTITIES main_kernel_inputs, main_kernel_value_out, main_kernel_side_effect_out, main_kernel_metadata_out, main_calldata, main_returndata, alu_a_hi, alu_a_lo, alu_b_hi, alu_b_lo, alu_b_pow, alu_c_hi, alu_c_lo, alu_cf, alu_clk, alu_cmp_gadget_gt, alu_cmp_gadget_input_a, alu_cmp_gadget_input_b, alu_cmp_gadget_result, alu_cmp_gadget_sel, alu_ff_tag, alu_ia, alu_ib, alu_ic, alu_in_tag, alu_max_bits_sub_b_bits, alu_max_bits_sub_b_pow, alu_op_add, alu_op_cast, alu_op_div, alu_op_eq, alu_op_lt, alu_op_lte, alu_op_mul, alu_op_not, alu_op_shl, alu_op_shr, alu_op_sub, alu_partial_prod_hi, alu_partial_prod_lo, alu_range_check_input_value, alu_range_check_num_bits, alu_range_check_sel, alu_remainder, alu_sel_alu, alu_sel_cmp, alu_sel_shift_which, alu_u128_tag, alu_u16_tag, alu_u32_tag, alu_u64_tag, alu_u8_tag, alu_zero_shift, binary_acc_ia, binary_acc_ib, binary_acc_ic, binary_clk, binary_ia_bytes, binary_ib_bytes, binary_ic_bytes, binary_in_tag, binary_mem_tag_ctr, binary_mem_tag_ctr_inv, binary_op_id, binary_sel_bin, binary_start, cmp_a_hi, cmp_a_lo, cmp_b_hi, cmp_b_lo, cmp_borrow, cmp_clk, cmp_cmp_rng_ctr, cmp_input_a, cmp_input_b, cmp_op_eq, cmp_op_eq_diff_inv, cmp_op_gt, cmp_p_a_borrow, cmp_p_b_borrow, cmp_p_sub_a_hi, cmp_p_sub_a_lo, cmp_p_sub_b_hi, cmp_p_sub_b_lo, cmp_range_chk_clk, cmp_res_hi, cmp_res_lo, cmp_result, cmp_sel_cmp, cmp_sel_rng_chk, cmp_shift_sel, conversion_clk, conversion_input, conversion_num_limbs, conversion_radix, conversion_sel_to_radix_le, keccakf1600_clk, keccakf1600_input, keccakf1600_output, keccakf1600_sel_keccakf1600, main_abs_da_rem_gas, main_abs_l2_rem_gas, main_alu_in_tag, main_base_da_gas_op_cost, main_base_l2_gas_op_cost, main_bin_op_id, main_call_ptr, main_da_gas_remaining, main_da_out_of_gas, main_dyn_da_gas_op_cost, main_dyn_gas_multiplier, main_dyn_l2_gas_op_cost, main_emit_l2_to_l1_msg_write_offset, main_emit_note_hash_write_offset, main_emit_nullifier_write_offset, main_emit_unencrypted_log_write_offset, main_ia, main_ib, main_ic, main_id, main_id_zero, main_ind_addr_a, main_ind_addr_b, main_ind_addr_c, main_ind_addr_d, main_internal_return_ptr, main_inv, main_kernel_in_offset, main_kernel_out_offset, main_l1_to_l2_msg_exists_write_offset, main_l2_gas_remaining, main_l2_out_of_gas, main_mem_addr_a, main_mem_addr_b, main_mem_addr_c, main_mem_addr_d, main_note_hash_exist_write_offset, main_nullifier_exists_write_offset, main_nullifier_non_exists_write_offset, main_op_err, main_opcode_val, main_pc, main_r_in_tag, main_rwa, main_rwb, main_rwc, main_rwd, main_sel_alu, main_sel_bin, main_sel_calldata, main_sel_execution_row, main_sel_kernel_inputs, main_sel_kernel_out, main_sel_last, main_sel_mem_op_a, main_sel_mem_op_b, main_sel_mem_op_c, main_sel_mem_op_d, main_sel_mov_ia_to_ic, main_sel_mov_ib_to_ic, main_sel_op_add, main_sel_op_address, main_sel_op_and, main_sel_op_block_number, main_sel_op_calldata_copy, main_sel_op_cast, main_sel_op_chain_id, main_sel_op_cmov, main_sel_op_dagasleft, main_sel_op_div, main_sel_op_ecadd, main_sel_op_emit_l2_to_l1_msg, main_sel_op_emit_note_hash, main_sel_op_emit_nullifier, main_sel_op_emit_unencrypted_log, main_sel_op_eq, main_sel_op_external_call, main_sel_op_external_return, main_sel_op_external_revert, main_sel_op_fdiv, main_sel_op_fee_per_da_gas, main_sel_op_fee_per_l2_gas, main_sel_op_function_selector, main_sel_op_get_contract_instance, main_sel_op_internal_call, main_sel_op_internal_return, main_sel_op_jump, main_sel_op_jumpi, main_sel_op_keccak, main_sel_op_l1_to_l2_msg_exists, main_sel_op_l2gasleft, main_sel_op_lt, main_sel_op_lte, main_sel_op_mov, main_sel_op_msm, main_sel_op_mul, main_sel_op_not, main_sel_op_note_hash_exists, main_sel_op_nullifier_exists, main_sel_op_or, main_sel_op_pedersen, main_sel_op_pedersen_commit, main_sel_op_poseidon2, main_sel_op_radix_le, main_sel_op_sender, main_sel_op_set, main_sel_op_sha256, main_sel_op_shl, main_sel_op_shr, main_sel_op_sload, main_sel_op_sstore, main_sel_op_storage_address, main_sel_op_sub, main_sel_op_timestamp, main_sel_op_transaction_fee, main_sel_op_version, main_sel_op_xor, main_sel_q_kernel_lookup, main_sel_q_kernel_output_lookup, main_sel_resolve_ind_addr_a, main_sel_resolve_ind_addr_b, main_sel_resolve_ind_addr_c, main_sel_resolve_ind_addr_d, main_sel_returndata, main_sel_rng_16, main_sel_rng_8, main_sel_slice_gadget, main_side_effect_counter, main_sload_write_offset, main_space_id, main_sstore_write_offset, main_tag_err, main_w_in_tag, mem_addr, mem_clk, mem_diff, mem_glob_addr, mem_last, mem_lastAccess, mem_one_min_inv, mem_r_in_tag, mem_rw, mem_sel_mem, mem_sel_mov_ia_to_ic, mem_sel_mov_ib_to_ic, mem_sel_op_a, mem_sel_op_b, mem_sel_op_c, mem_sel_op_cmov, mem_sel_op_d, mem_sel_op_poseidon_read_a, mem_sel_op_poseidon_read_b, mem_sel_op_poseidon_read_c, mem_sel_op_poseidon_read_d, mem_sel_op_poseidon_write_a, mem_sel_op_poseidon_write_b, mem_sel_op_poseidon_write_c, mem_sel_op_poseidon_write_d, mem_sel_op_slice, mem_sel_resolve_ind_addr_a, mem_sel_resolve_ind_addr_b, mem_sel_resolve_ind_addr_c, mem_sel_resolve_ind_addr_d, mem_sel_rng_chk, mem_skip_check_tag, mem_space_id, mem_tag, mem_tag_err, mem_tsp, mem_val, mem_w_in_tag, pedersen_clk, pedersen_input, pedersen_output, pedersen_sel_pedersen, poseidon2_B_10_0, poseidon2_B_10_1, poseidon2_B_10_2, poseidon2_B_10_3, poseidon2_B_11_0, poseidon2_B_11_1, poseidon2_B_11_2, poseidon2_B_11_3, poseidon2_B_12_0, poseidon2_B_12_1, poseidon2_B_12_2, poseidon2_B_12_3, poseidon2_B_13_0, poseidon2_B_13_1, poseidon2_B_13_2, poseidon2_B_13_3, poseidon2_B_14_0, poseidon2_B_14_1, poseidon2_B_14_2, poseidon2_B_14_3, poseidon2_B_15_0, poseidon2_B_15_1, poseidon2_B_15_2, poseidon2_B_15_3, poseidon2_B_16_0, poseidon2_B_16_1, poseidon2_B_16_2, poseidon2_B_16_3, poseidon2_B_17_0, poseidon2_B_17_1, poseidon2_B_17_2, poseidon2_B_17_3, poseidon2_B_18_0, poseidon2_B_18_1, poseidon2_B_18_2, poseidon2_B_18_3, poseidon2_B_19_0, poseidon2_B_19_1, poseidon2_B_19_2, poseidon2_B_19_3, poseidon2_B_20_0, poseidon2_B_20_1, poseidon2_B_20_2, poseidon2_B_20_3, poseidon2_B_21_0, poseidon2_B_21_1, poseidon2_B_21_2, poseidon2_B_21_3, poseidon2_B_22_0, poseidon2_B_22_1, poseidon2_B_22_2, poseidon2_B_22_3, poseidon2_B_23_0, poseidon2_B_23_1, poseidon2_B_23_2, poseidon2_B_23_3, poseidon2_B_24_0, poseidon2_B_24_1, poseidon2_B_24_2, poseidon2_B_24_3, poseidon2_B_25_0, poseidon2_B_25_1, poseidon2_B_25_2, poseidon2_B_25_3, poseidon2_B_26_0, poseidon2_B_26_1, poseidon2_B_26_2, poseidon2_B_26_3, poseidon2_B_27_0, poseidon2_B_27_1, poseidon2_B_27_2, poseidon2_B_27_3, poseidon2_B_28_0, poseidon2_B_28_1, poseidon2_B_28_2, poseidon2_B_28_3, poseidon2_B_29_0, poseidon2_B_29_1, poseidon2_B_29_2, poseidon2_B_29_3, poseidon2_B_30_0, poseidon2_B_30_1, poseidon2_B_30_2, poseidon2_B_30_3, poseidon2_B_31_0, poseidon2_B_31_1, poseidon2_B_31_2, poseidon2_B_31_3, poseidon2_B_32_0, poseidon2_B_32_1, poseidon2_B_32_2, poseidon2_B_32_3, poseidon2_B_33_0, poseidon2_B_33_1, poseidon2_B_33_2, poseidon2_B_33_3, poseidon2_B_34_0, poseidon2_B_34_1, poseidon2_B_34_2, poseidon2_B_34_3, poseidon2_B_35_0, poseidon2_B_35_1, poseidon2_B_35_2, poseidon2_B_35_3, poseidon2_B_36_0, poseidon2_B_36_1, poseidon2_B_36_2, poseidon2_B_36_3, poseidon2_B_37_0, poseidon2_B_37_1, poseidon2_B_37_2, poseidon2_B_37_3, poseidon2_B_38_0, poseidon2_B_38_1, poseidon2_B_38_2, poseidon2_B_38_3, poseidon2_B_39_0, poseidon2_B_39_1, poseidon2_B_39_2, poseidon2_B_39_3, poseidon2_B_40_0, poseidon2_B_40_1, poseidon2_B_40_2, poseidon2_B_40_3, poseidon2_B_41_0, poseidon2_B_41_1, poseidon2_B_41_2, poseidon2_B_41_3, poseidon2_B_42_0, poseidon2_B_42_1, poseidon2_B_42_2, poseidon2_B_42_3, poseidon2_B_43_0, poseidon2_B_43_1, poseidon2_B_43_2, poseidon2_B_43_3, poseidon2_B_44_0, poseidon2_B_44_1, poseidon2_B_44_2, poseidon2_B_44_3, poseidon2_B_45_0, poseidon2_B_45_1, poseidon2_B_45_2, poseidon2_B_45_3, poseidon2_B_46_0, poseidon2_B_46_1, poseidon2_B_46_2, poseidon2_B_46_3, poseidon2_B_47_0, poseidon2_B_47_1, poseidon2_B_47_2, poseidon2_B_47_3, poseidon2_B_48_0, poseidon2_B_48_1, poseidon2_B_48_2, poseidon2_B_48_3, poseidon2_B_49_0, poseidon2_B_49_1, poseidon2_B_49_2, poseidon2_B_49_3, poseidon2_B_4_0, poseidon2_B_4_1, poseidon2_B_4_2, poseidon2_B_4_3, poseidon2_B_50_0, poseidon2_B_50_1, poseidon2_B_50_2, poseidon2_B_50_3, poseidon2_B_51_0, poseidon2_B_51_1, poseidon2_B_51_2, poseidon2_B_51_3, poseidon2_B_52_0, poseidon2_B_52_1, poseidon2_B_52_2, poseidon2_B_52_3, poseidon2_B_53_0, poseidon2_B_53_1, poseidon2_B_53_2, poseidon2_B_53_3, poseidon2_B_54_0, poseidon2_B_54_1, poseidon2_B_54_2, poseidon2_B_54_3, poseidon2_B_55_0, poseidon2_B_55_1, poseidon2_B_55_2, poseidon2_B_55_3, poseidon2_B_56_0, poseidon2_B_56_1, poseidon2_B_56_2, poseidon2_B_56_3, poseidon2_B_57_0, poseidon2_B_57_1, poseidon2_B_57_2, poseidon2_B_57_3, poseidon2_B_58_0, poseidon2_B_58_1, poseidon2_B_58_2, poseidon2_B_58_3, poseidon2_B_59_0, poseidon2_B_59_1, poseidon2_B_59_2, poseidon2_B_59_3, poseidon2_B_5_0, poseidon2_B_5_1, poseidon2_B_5_2, poseidon2_B_5_3, poseidon2_B_6_0, poseidon2_B_6_1, poseidon2_B_6_2, poseidon2_B_6_3, poseidon2_B_7_0, poseidon2_B_7_1, poseidon2_B_7_2, poseidon2_B_7_3, poseidon2_B_8_0, poseidon2_B_8_1, poseidon2_B_8_2, poseidon2_B_8_3, poseidon2_B_9_0, poseidon2_B_9_1, poseidon2_B_9_2, poseidon2_B_9_3, poseidon2_EXT_LAYER_4, poseidon2_EXT_LAYER_5, poseidon2_EXT_LAYER_6, poseidon2_EXT_LAYER_7, poseidon2_T_0_4, poseidon2_T_0_5, poseidon2_T_0_6, poseidon2_T_0_7, poseidon2_T_1_4, poseidon2_T_1_5, poseidon2_T_1_6, poseidon2_T_1_7, poseidon2_T_2_4, poseidon2_T_2_5, poseidon2_T_2_6, poseidon2_T_2_7, poseidon2_T_3_4, poseidon2_T_3_5, poseidon2_T_3_6, poseidon2_T_3_7, poseidon2_T_60_4, poseidon2_T_60_5, poseidon2_T_60_6, poseidon2_T_60_7, poseidon2_T_61_4, poseidon2_T_61_5, poseidon2_T_61_6, poseidon2_T_61_7, poseidon2_T_62_4, poseidon2_T_62_5, poseidon2_T_62_6, poseidon2_T_62_7, poseidon2_T_63_4, poseidon2_T_63_5, poseidon2_T_63_6, poseidon2_T_63_7, poseidon2_a_0, poseidon2_a_1, poseidon2_a_2, poseidon2_a_3, poseidon2_b_0, poseidon2_b_1, poseidon2_b_2, poseidon2_b_3, poseidon2_clk, poseidon2_input_addr, poseidon2_mem_addr_read_a, poseidon2_mem_addr_read_b, poseidon2_mem_addr_read_c, poseidon2_mem_addr_read_d, poseidon2_mem_addr_write_a, poseidon2_mem_addr_write_b, poseidon2_mem_addr_write_c, poseidon2_mem_addr_write_d, poseidon2_output_addr, poseidon2_sel_poseidon_perm, range_check_alu_rng_chk, range_check_clk, range_check_cmp_hi_bits_rng_chk, range_check_cmp_lo_bits_rng_chk, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_gas_da_rng_chk, range_check_gas_l2_rng_chk, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_mem_rng_chk, range_check_rng_chk_bits, range_check_sel_lookup_0, range_check_sel_lookup_1, range_check_sel_lookup_2, range_check_sel_lookup_3, range_check_sel_lookup_4, range_check_sel_lookup_5, range_check_sel_lookup_6, range_check_sel_rng_chk, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, sha256_clk, sha256_input, sha256_output, sha256_sel_sha256_compression, sha256_state, slice_addr, slice_clk, slice_cnt, slice_col_offset, slice_one_min_inv, slice_sel_cd_cpy, slice_sel_mem_active, slice_sel_return, slice_sel_start, slice_space_id, slice_val, lookup_rng_chk_pow_2_counts, lookup_rng_chk_diff_counts, lookup_rng_chk_0_counts, lookup_rng_chk_1_counts, lookup_rng_chk_2_counts, lookup_rng_chk_3_counts, lookup_rng_chk_4_counts, lookup_rng_chk_5_counts, lookup_rng_chk_6_counts, lookup_rng_chk_7_counts, lookup_pow_2_0_counts, lookup_pow_2_1_counts, lookup_byte_lengths_counts, lookup_byte_operations_counts, lookup_opcode_gas_counts, kernel_output_lookup_counts, lookup_into_kernel_counts, lookup_cd_value_counts, lookup_ret_value_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts +#define WIRE_ENTITIES main_kernel_inputs, main_kernel_value_out, main_kernel_side_effect_out, main_kernel_metadata_out, main_calldata, main_returndata, alu_a_hi, alu_a_lo, alu_b_hi, alu_b_lo, alu_b_pow, alu_c_hi, alu_c_lo, alu_cf, alu_clk, alu_cmp_gadget_gt, alu_cmp_gadget_input_a, alu_cmp_gadget_input_b, alu_cmp_gadget_result, alu_cmp_gadget_sel, alu_ff_tag, alu_ia, alu_ib, alu_ic, alu_in_tag, alu_max_bits_sub_b_bits, alu_max_bits_sub_b_pow, alu_op_add, alu_op_cast, alu_op_div, alu_op_eq, alu_op_lt, alu_op_lte, alu_op_mul, alu_op_not, alu_op_shl, alu_op_shr, alu_op_sub, alu_partial_prod_hi, alu_partial_prod_lo, alu_range_check_input_value, alu_range_check_num_bits, alu_range_check_sel, alu_remainder, alu_sel_alu, alu_sel_cmp, alu_sel_shift_which, alu_u128_tag, alu_u16_tag, alu_u1_tag, alu_u32_tag, alu_u64_tag, alu_u8_tag, alu_zero_shift, binary_acc_ia, binary_acc_ib, binary_acc_ic, binary_clk, binary_ia_bytes, binary_ib_bytes, binary_ic_bytes, binary_in_tag, binary_mem_tag_ctr, binary_mem_tag_ctr_inv, binary_op_id, binary_sel_bin, binary_start, cmp_a_hi, cmp_a_lo, cmp_b_hi, cmp_b_lo, cmp_borrow, cmp_clk, cmp_cmp_rng_ctr, cmp_input_a, cmp_input_b, cmp_op_eq, cmp_op_eq_diff_inv, cmp_op_gt, cmp_p_a_borrow, cmp_p_b_borrow, cmp_p_sub_a_hi, cmp_p_sub_a_lo, cmp_p_sub_b_hi, cmp_p_sub_b_lo, cmp_range_chk_clk, cmp_res_hi, cmp_res_lo, cmp_result, cmp_sel_cmp, cmp_sel_rng_chk, cmp_shift_sel, conversion_clk, conversion_input, conversion_num_limbs, conversion_output_bits, conversion_radix, conversion_sel_to_radix_le, keccakf1600_clk, keccakf1600_input, keccakf1600_output, keccakf1600_sel_keccakf1600, main_abs_da_rem_gas, main_abs_l2_rem_gas, main_alu_in_tag, main_base_da_gas_op_cost, main_base_l2_gas_op_cost, main_bin_op_id, main_call_ptr, main_da_gas_remaining, main_da_out_of_gas, main_dyn_da_gas_op_cost, main_dyn_gas_multiplier, main_dyn_l2_gas_op_cost, main_emit_l2_to_l1_msg_write_offset, main_emit_note_hash_write_offset, main_emit_nullifier_write_offset, main_emit_unencrypted_log_write_offset, main_ia, main_ib, main_ic, main_id, main_id_zero, main_ind_addr_a, main_ind_addr_b, main_ind_addr_c, main_ind_addr_d, main_internal_return_ptr, main_inv, main_kernel_in_offset, main_kernel_out_offset, main_l1_to_l2_msg_exists_write_offset, main_l2_gas_remaining, main_l2_out_of_gas, main_mem_addr_a, main_mem_addr_b, main_mem_addr_c, main_mem_addr_d, main_note_hash_exist_write_offset, main_nullifier_exists_write_offset, main_nullifier_non_exists_write_offset, main_op_err, main_opcode_val, main_pc, main_r_in_tag, main_rwa, main_rwb, main_rwc, main_rwd, main_sel_alu, main_sel_bin, main_sel_calldata, main_sel_execution_row, main_sel_kernel_inputs, main_sel_kernel_out, main_sel_last, main_sel_mem_op_a, main_sel_mem_op_b, main_sel_mem_op_c, main_sel_mem_op_d, main_sel_mov_ia_to_ic, main_sel_mov_ib_to_ic, main_sel_op_add, main_sel_op_address, main_sel_op_and, main_sel_op_block_number, main_sel_op_calldata_copy, main_sel_op_cast, main_sel_op_chain_id, main_sel_op_cmov, main_sel_op_dagasleft, main_sel_op_div, main_sel_op_ecadd, main_sel_op_emit_l2_to_l1_msg, main_sel_op_emit_note_hash, main_sel_op_emit_nullifier, main_sel_op_emit_unencrypted_log, main_sel_op_eq, main_sel_op_external_call, main_sel_op_external_return, main_sel_op_external_revert, main_sel_op_fdiv, main_sel_op_fee_per_da_gas, main_sel_op_fee_per_l2_gas, main_sel_op_function_selector, main_sel_op_get_contract_instance, main_sel_op_internal_call, main_sel_op_internal_return, main_sel_op_jump, main_sel_op_jumpi, main_sel_op_keccak, main_sel_op_l1_to_l2_msg_exists, main_sel_op_l2gasleft, main_sel_op_lt, main_sel_op_lte, main_sel_op_mov, main_sel_op_msm, main_sel_op_mul, main_sel_op_not, main_sel_op_note_hash_exists, main_sel_op_nullifier_exists, main_sel_op_or, main_sel_op_pedersen, main_sel_op_pedersen_commit, main_sel_op_poseidon2, main_sel_op_radix_le, main_sel_op_sender, main_sel_op_set, main_sel_op_sha256, main_sel_op_shl, main_sel_op_shr, main_sel_op_sload, main_sel_op_sstore, main_sel_op_storage_address, main_sel_op_sub, main_sel_op_timestamp, main_sel_op_transaction_fee, main_sel_op_version, main_sel_op_xor, main_sel_q_kernel_lookup, main_sel_q_kernel_output_lookup, main_sel_resolve_ind_addr_a, main_sel_resolve_ind_addr_b, main_sel_resolve_ind_addr_c, main_sel_resolve_ind_addr_d, main_sel_returndata, main_sel_rng_16, main_sel_rng_8, main_sel_slice_gadget, main_side_effect_counter, main_sload_write_offset, main_space_id, main_sstore_write_offset, main_tag_err, main_w_in_tag, mem_addr, mem_clk, mem_diff, mem_glob_addr, mem_last, mem_lastAccess, mem_one_min_inv, mem_r_in_tag, mem_rw, mem_sel_mem, mem_sel_mov_ia_to_ic, mem_sel_mov_ib_to_ic, mem_sel_op_a, mem_sel_op_b, mem_sel_op_c, mem_sel_op_cmov, mem_sel_op_d, mem_sel_op_poseidon_read_a, mem_sel_op_poseidon_read_b, mem_sel_op_poseidon_read_c, mem_sel_op_poseidon_read_d, mem_sel_op_poseidon_write_a, mem_sel_op_poseidon_write_b, mem_sel_op_poseidon_write_c, mem_sel_op_poseidon_write_d, mem_sel_op_slice, mem_sel_resolve_ind_addr_a, mem_sel_resolve_ind_addr_b, mem_sel_resolve_ind_addr_c, mem_sel_resolve_ind_addr_d, mem_sel_rng_chk, mem_skip_check_tag, mem_space_id, mem_tag, mem_tag_err, mem_tsp, mem_val, mem_w_in_tag, pedersen_clk, pedersen_input, pedersen_output, pedersen_sel_pedersen, poseidon2_B_10_0, poseidon2_B_10_1, poseidon2_B_10_2, poseidon2_B_10_3, poseidon2_B_11_0, poseidon2_B_11_1, poseidon2_B_11_2, poseidon2_B_11_3, poseidon2_B_12_0, poseidon2_B_12_1, poseidon2_B_12_2, poseidon2_B_12_3, poseidon2_B_13_0, poseidon2_B_13_1, poseidon2_B_13_2, poseidon2_B_13_3, poseidon2_B_14_0, poseidon2_B_14_1, poseidon2_B_14_2, poseidon2_B_14_3, poseidon2_B_15_0, poseidon2_B_15_1, poseidon2_B_15_2, poseidon2_B_15_3, poseidon2_B_16_0, poseidon2_B_16_1, poseidon2_B_16_2, poseidon2_B_16_3, poseidon2_B_17_0, poseidon2_B_17_1, poseidon2_B_17_2, poseidon2_B_17_3, poseidon2_B_18_0, poseidon2_B_18_1, poseidon2_B_18_2, poseidon2_B_18_3, poseidon2_B_19_0, poseidon2_B_19_1, poseidon2_B_19_2, poseidon2_B_19_3, poseidon2_B_20_0, poseidon2_B_20_1, poseidon2_B_20_2, poseidon2_B_20_3, poseidon2_B_21_0, poseidon2_B_21_1, poseidon2_B_21_2, poseidon2_B_21_3, poseidon2_B_22_0, poseidon2_B_22_1, poseidon2_B_22_2, poseidon2_B_22_3, poseidon2_B_23_0, poseidon2_B_23_1, poseidon2_B_23_2, poseidon2_B_23_3, poseidon2_B_24_0, poseidon2_B_24_1, poseidon2_B_24_2, poseidon2_B_24_3, poseidon2_B_25_0, poseidon2_B_25_1, poseidon2_B_25_2, poseidon2_B_25_3, poseidon2_B_26_0, poseidon2_B_26_1, poseidon2_B_26_2, poseidon2_B_26_3, poseidon2_B_27_0, poseidon2_B_27_1, poseidon2_B_27_2, poseidon2_B_27_3, poseidon2_B_28_0, poseidon2_B_28_1, poseidon2_B_28_2, poseidon2_B_28_3, poseidon2_B_29_0, poseidon2_B_29_1, poseidon2_B_29_2, poseidon2_B_29_3, poseidon2_B_30_0, poseidon2_B_30_1, poseidon2_B_30_2, poseidon2_B_30_3, poseidon2_B_31_0, poseidon2_B_31_1, poseidon2_B_31_2, poseidon2_B_31_3, poseidon2_B_32_0, poseidon2_B_32_1, poseidon2_B_32_2, poseidon2_B_32_3, poseidon2_B_33_0, poseidon2_B_33_1, poseidon2_B_33_2, poseidon2_B_33_3, poseidon2_B_34_0, poseidon2_B_34_1, poseidon2_B_34_2, poseidon2_B_34_3, poseidon2_B_35_0, poseidon2_B_35_1, poseidon2_B_35_2, poseidon2_B_35_3, poseidon2_B_36_0, poseidon2_B_36_1, poseidon2_B_36_2, poseidon2_B_36_3, poseidon2_B_37_0, poseidon2_B_37_1, poseidon2_B_37_2, poseidon2_B_37_3, poseidon2_B_38_0, poseidon2_B_38_1, poseidon2_B_38_2, poseidon2_B_38_3, poseidon2_B_39_0, poseidon2_B_39_1, poseidon2_B_39_2, poseidon2_B_39_3, poseidon2_B_40_0, poseidon2_B_40_1, poseidon2_B_40_2, poseidon2_B_40_3, poseidon2_B_41_0, poseidon2_B_41_1, poseidon2_B_41_2, poseidon2_B_41_3, poseidon2_B_42_0, poseidon2_B_42_1, poseidon2_B_42_2, poseidon2_B_42_3, poseidon2_B_43_0, poseidon2_B_43_1, poseidon2_B_43_2, poseidon2_B_43_3, poseidon2_B_44_0, poseidon2_B_44_1, poseidon2_B_44_2, poseidon2_B_44_3, poseidon2_B_45_0, poseidon2_B_45_1, poseidon2_B_45_2, poseidon2_B_45_3, poseidon2_B_46_0, poseidon2_B_46_1, poseidon2_B_46_2, poseidon2_B_46_3, poseidon2_B_47_0, poseidon2_B_47_1, poseidon2_B_47_2, poseidon2_B_47_3, poseidon2_B_48_0, poseidon2_B_48_1, poseidon2_B_48_2, poseidon2_B_48_3, poseidon2_B_49_0, poseidon2_B_49_1, poseidon2_B_49_2, poseidon2_B_49_3, poseidon2_B_4_0, poseidon2_B_4_1, poseidon2_B_4_2, poseidon2_B_4_3, poseidon2_B_50_0, poseidon2_B_50_1, poseidon2_B_50_2, poseidon2_B_50_3, poseidon2_B_51_0, poseidon2_B_51_1, poseidon2_B_51_2, poseidon2_B_51_3, poseidon2_B_52_0, poseidon2_B_52_1, poseidon2_B_52_2, poseidon2_B_52_3, poseidon2_B_53_0, poseidon2_B_53_1, poseidon2_B_53_2, poseidon2_B_53_3, poseidon2_B_54_0, poseidon2_B_54_1, poseidon2_B_54_2, poseidon2_B_54_3, poseidon2_B_55_0, poseidon2_B_55_1, poseidon2_B_55_2, poseidon2_B_55_3, poseidon2_B_56_0, poseidon2_B_56_1, poseidon2_B_56_2, poseidon2_B_56_3, poseidon2_B_57_0, poseidon2_B_57_1, poseidon2_B_57_2, poseidon2_B_57_3, poseidon2_B_58_0, poseidon2_B_58_1, poseidon2_B_58_2, poseidon2_B_58_3, poseidon2_B_59_0, poseidon2_B_59_1, poseidon2_B_59_2, poseidon2_B_59_3, poseidon2_B_5_0, poseidon2_B_5_1, poseidon2_B_5_2, poseidon2_B_5_3, poseidon2_B_6_0, poseidon2_B_6_1, poseidon2_B_6_2, poseidon2_B_6_3, poseidon2_B_7_0, poseidon2_B_7_1, poseidon2_B_7_2, poseidon2_B_7_3, poseidon2_B_8_0, poseidon2_B_8_1, poseidon2_B_8_2, poseidon2_B_8_3, poseidon2_B_9_0, poseidon2_B_9_1, poseidon2_B_9_2, poseidon2_B_9_3, poseidon2_EXT_LAYER_4, poseidon2_EXT_LAYER_5, poseidon2_EXT_LAYER_6, poseidon2_EXT_LAYER_7, poseidon2_T_0_4, poseidon2_T_0_5, poseidon2_T_0_6, poseidon2_T_0_7, poseidon2_T_1_4, poseidon2_T_1_5, poseidon2_T_1_6, poseidon2_T_1_7, poseidon2_T_2_4, poseidon2_T_2_5, poseidon2_T_2_6, poseidon2_T_2_7, poseidon2_T_3_4, poseidon2_T_3_5, poseidon2_T_3_6, poseidon2_T_3_7, poseidon2_T_60_4, poseidon2_T_60_5, poseidon2_T_60_6, poseidon2_T_60_7, poseidon2_T_61_4, poseidon2_T_61_5, poseidon2_T_61_6, poseidon2_T_61_7, poseidon2_T_62_4, poseidon2_T_62_5, poseidon2_T_62_6, poseidon2_T_62_7, poseidon2_T_63_4, poseidon2_T_63_5, poseidon2_T_63_6, poseidon2_T_63_7, poseidon2_a_0, poseidon2_a_1, poseidon2_a_2, poseidon2_a_3, poseidon2_b_0, poseidon2_b_1, poseidon2_b_2, poseidon2_b_3, poseidon2_clk, poseidon2_input_addr, poseidon2_mem_addr_read_a, poseidon2_mem_addr_read_b, poseidon2_mem_addr_read_c, poseidon2_mem_addr_read_d, poseidon2_mem_addr_write_a, poseidon2_mem_addr_write_b, poseidon2_mem_addr_write_c, poseidon2_mem_addr_write_d, poseidon2_output_addr, poseidon2_sel_poseidon_perm, range_check_alu_rng_chk, range_check_clk, range_check_cmp_hi_bits_rng_chk, range_check_cmp_lo_bits_rng_chk, range_check_dyn_diff, range_check_dyn_rng_chk_bits, range_check_dyn_rng_chk_pow_2, range_check_gas_da_rng_chk, range_check_gas_l2_rng_chk, range_check_is_lte_u112, range_check_is_lte_u128, range_check_is_lte_u16, range_check_is_lte_u32, range_check_is_lte_u48, range_check_is_lte_u64, range_check_is_lte_u80, range_check_is_lte_u96, range_check_mem_rng_chk, range_check_rng_chk_bits, range_check_sel_lookup_0, range_check_sel_lookup_1, range_check_sel_lookup_2, range_check_sel_lookup_3, range_check_sel_lookup_4, range_check_sel_lookup_5, range_check_sel_lookup_6, range_check_sel_rng_chk, range_check_u16_r0, range_check_u16_r1, range_check_u16_r2, range_check_u16_r3, range_check_u16_r4, range_check_u16_r5, range_check_u16_r6, range_check_u16_r7, range_check_value, sha256_clk, sha256_input, sha256_output, sha256_sel_sha256_compression, sha256_state, slice_addr, slice_clk, slice_cnt, slice_col_offset, slice_one_min_inv, slice_sel_cd_cpy, slice_sel_mem_active, slice_sel_return, slice_sel_start, slice_space_id, slice_val, lookup_rng_chk_pow_2_counts, lookup_rng_chk_diff_counts, lookup_rng_chk_0_counts, lookup_rng_chk_1_counts, lookup_rng_chk_2_counts, lookup_rng_chk_3_counts, lookup_rng_chk_4_counts, lookup_rng_chk_5_counts, lookup_rng_chk_6_counts, lookup_rng_chk_7_counts, lookup_pow_2_0_counts, lookup_pow_2_1_counts, lookup_byte_lengths_counts, lookup_byte_operations_counts, lookup_opcode_gas_counts, kernel_output_lookup_counts, lookup_into_kernel_counts, lookup_cd_value_counts, lookup_ret_value_counts, incl_main_tag_err_counts, incl_mem_tag_err_counts #define DERIVED_WITNESS_ENTITIES perm_rng_mem_inv, perm_rng_cmp_lo_inv, perm_rng_cmp_hi_inv, perm_rng_alu_inv, perm_cmp_alu_inv, perm_rng_gas_l2_inv, perm_rng_gas_da_inv, perm_pos_mem_read_a_inv, perm_pos_mem_read_b_inv, perm_pos_mem_read_c_inv, perm_pos_mem_read_d_inv, perm_pos_mem_write_a_inv, perm_pos_mem_write_b_inv, perm_pos_mem_write_c_inv, perm_pos_mem_write_d_inv, perm_slice_mem_inv, perm_main_alu_inv, perm_main_bin_inv, perm_main_conv_inv, perm_main_pos2_perm_inv, perm_main_pedersen_inv, perm_main_slice_inv, perm_main_mem_a_inv, perm_main_mem_b_inv, perm_main_mem_c_inv, perm_main_mem_d_inv, perm_main_mem_ind_addr_a_inv, perm_main_mem_ind_addr_b_inv, perm_main_mem_ind_addr_c_inv, perm_main_mem_ind_addr_d_inv, lookup_rng_chk_pow_2_inv, lookup_rng_chk_diff_inv, lookup_rng_chk_0_inv, lookup_rng_chk_1_inv, lookup_rng_chk_2_inv, lookup_rng_chk_3_inv, lookup_rng_chk_4_inv, lookup_rng_chk_5_inv, lookup_rng_chk_6_inv, lookup_rng_chk_7_inv, lookup_pow_2_0_inv, lookup_pow_2_1_inv, lookup_byte_lengths_inv, lookup_byte_operations_inv, lookup_opcode_gas_inv, kernel_output_lookup_inv, lookup_into_kernel_inv, lookup_cd_value_inv, lookup_ret_value_inv, incl_main_tag_err_inv, incl_mem_tag_err_inv #define SHIFTED_ENTITIES binary_acc_ia_shift, binary_acc_ib_shift, binary_acc_ic_shift, binary_mem_tag_ctr_shift, binary_op_id_shift, cmp_a_hi_shift, cmp_a_lo_shift, cmp_b_hi_shift, cmp_b_lo_shift, cmp_cmp_rng_ctr_shift, cmp_op_gt_shift, cmp_p_sub_a_hi_shift, cmp_p_sub_a_lo_shift, cmp_p_sub_b_hi_shift, cmp_p_sub_b_lo_shift, cmp_sel_rng_chk_shift, main_da_gas_remaining_shift, main_emit_l2_to_l1_msg_write_offset_shift, main_emit_note_hash_write_offset_shift, main_emit_nullifier_write_offset_shift, main_emit_unencrypted_log_write_offset_shift, main_internal_return_ptr_shift, main_l1_to_l2_msg_exists_write_offset_shift, main_l2_gas_remaining_shift, main_note_hash_exist_write_offset_shift, main_nullifier_exists_write_offset_shift, main_nullifier_non_exists_write_offset_shift, main_pc_shift, main_sel_execution_row_shift, main_sload_write_offset_shift, main_sstore_write_offset_shift, mem_glob_addr_shift, mem_rw_shift, mem_sel_mem_shift, mem_tag_shift, mem_tsp_shift, mem_val_shift, slice_addr_shift, slice_clk_shift, slice_cnt_shift, slice_col_offset_shift, slice_sel_cd_cpy_shift, slice_sel_mem_active_shift, slice_sel_return_shift, slice_sel_start_shift, slice_space_id_shift #define TO_BE_SHIFTED(e) e.binary_acc_ia, e.binary_acc_ib, e.binary_acc_ic, e.binary_mem_tag_ctr, e.binary_op_id, e.cmp_a_hi, e.cmp_a_lo, e.cmp_b_hi, e.cmp_b_lo, e.cmp_cmp_rng_ctr, e.cmp_op_gt, e.cmp_p_sub_a_hi, e.cmp_p_sub_a_lo, e.cmp_p_sub_b_hi, e.cmp_p_sub_b_lo, e.cmp_sel_rng_chk, e.main_da_gas_remaining, e.main_emit_l2_to_l1_msg_write_offset, e.main_emit_note_hash_write_offset, e.main_emit_nullifier_write_offset, e.main_emit_unencrypted_log_write_offset, e.main_internal_return_ptr, e.main_l1_to_l2_msg_exists_write_offset, e.main_l2_gas_remaining, e.main_note_hash_exist_write_offset, e.main_nullifier_exists_write_offset, e.main_nullifier_non_exists_write_offset, e.main_pc, e.main_sel_execution_row, e.main_sload_write_offset, e.main_sstore_write_offset, e.mem_glob_addr, e.mem_rw, e.mem_sel_mem, e.mem_tag, e.mem_tsp, e.mem_val, e.slice_addr, e.slice_clk, e.slice_cnt, e.slice_col_offset, e.slice_sel_cd_cpy, e.slice_sel_mem_active, e.slice_sel_return, e.slice_sel_start, e.slice_space_id @@ -118,12 +118,12 @@ class AvmFlavor { static constexpr bool HasZK = false; static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 16; - static constexpr size_t NUM_WITNESS_ENTITIES = 679; + static constexpr size_t NUM_WITNESS_ENTITIES = 681; static constexpr size_t NUM_SHIFTED_ENTITIES = 46; 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 = 741; + static constexpr size_t NUM_ALL_ENTITIES = 743; // The total number of witnesses including shifts and derived entities. static constexpr size_t NUM_ALL_WITNESS_ENTITIES = NUM_WITNESS_ENTITIES + NUM_SHIFTED_ENTITIES; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.cpp index 1f465d4098c..acb3ecb1a3c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.cpp @@ -84,6 +84,7 @@ template std::vector AvmFullRow::names() "alu_sel_shift_which", "alu_u128_tag", "alu_u16_tag", + "alu_u1_tag", "alu_u32_tag", "alu_u64_tag", "alu_u8_tag", @@ -129,6 +130,7 @@ template std::vector AvmFullRow::names() "conversion_clk", "conversion_input", "conversion_num_limbs", + "conversion_output_bits", "conversion_radix", "conversion_sel_to_radix_le", "keccakf1600_clk", @@ -784,6 +786,7 @@ template RefVector AvmFullRow::as_vector() const alu_sel_shift_which, alu_u128_tag, alu_u16_tag, + alu_u1_tag, alu_u32_tag, alu_u64_tag, alu_u8_tag, @@ -829,6 +832,7 @@ template RefVector AvmFullRow::as_vector() const conversion_clk, conversion_input, conversion_num_limbs, + conversion_output_bits, conversion_radix, conversion_sel_to_radix_le, keccakf1600_clk, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.hpp index c4bbe015e9c..cb3d1180b55 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/full_row.hpp @@ -75,6 +75,7 @@ template struct AvmFullRow { FF alu_sel_shift_which{}; FF alu_u128_tag{}; FF alu_u16_tag{}; + FF alu_u1_tag{}; FF alu_u32_tag{}; FF alu_u64_tag{}; FF alu_u8_tag{}; @@ -120,6 +121,7 @@ template struct AvmFullRow { FF conversion_clk{}; FF conversion_input{}; FF conversion_num_limbs{}; + FF conversion_output_bits{}; FF conversion_radix{}; FF conversion_sel_to_radix_le{}; FF keccakf1600_clk{}; @@ -709,7 +711,7 @@ template struct AvmFullRow { RefVector as_vector() const; static std::vector names(); - static constexpr size_t SIZE = 695; + static constexpr size_t SIZE = 697; }; template std::ostream& operator<<(std::ostream& os, AvmFullRow const& row); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/alu.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/alu.hpp index 8cb08635d00..e96b9ed2408 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/alu.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/alu.hpp @@ -10,10 +10,10 @@ template class aluImpl { public: using FF = FF_; - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 4, 4, - 2, 2, 3, 3, 4, 4, 5, 5, 5, 4, 6, 3, - 3, 3, 5, 5, 4, 6, 4, 3, 3, 3, 2, 3, - 3, 3, 4, 3, 3, 3, 3, 3, 4, 4, 4, 5 }; + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS = { 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 4, 4, + 2, 2, 3, 3, 4, 4, 5, 5, 5, 4, 7, 3, 3, + 3, 5, 5, 4, 7, 4, 3, 3, 3, 2, 3, 3, 3, + 4, 3, 3, 3, 3, 3, 4, 4, 4, 5 }; template void static accumulate(ContainerOverSubrelations& evals, @@ -21,11 +21,19 @@ template class aluImpl { [[maybe_unused]] const RelationParameters&, [[maybe_unused]] const FF& scaling_factor) { + const auto constants_MEM_TAG_U8 = FF(2); + const auto constants_MEM_TAG_U16 = FF(3); + const auto constants_MEM_TAG_U32 = FF(4); + const auto constants_MEM_TAG_U64 = FF(5); + const auto constants_MEM_TAG_U128 = FF(6); + const auto constants_MEM_TAG_FF = FF(7); const auto alu_MAX_BITS = - (((((new_term.alu_u8_tag * FF(8)) + (new_term.alu_u16_tag * FF(16))) + (new_term.alu_u32_tag * FF(32))) + + ((((((new_term.alu_u1_tag * FF(1)) + (new_term.alu_u8_tag * FF(8))) + (new_term.alu_u16_tag * FF(16))) + + (new_term.alu_u32_tag * FF(32))) + (new_term.alu_u64_tag * FF(64))) + (new_term.alu_u128_tag * FF(128))); - const auto alu_MAX_BITS_POW = (((((new_term.alu_u8_tag * FF(256)) + (new_term.alu_u16_tag * FF(65536))) + + const auto alu_MAX_BITS_POW = ((((((new_term.alu_u1_tag * FF(2)) + (new_term.alu_u8_tag * FF(256))) + + (new_term.alu_u16_tag * FF(65536))) + (new_term.alu_u32_tag * FF(4294967296UL))) + (new_term.alu_u64_tag * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))) + (new_term.alu_u128_tag * FF(uint256_t{ 0UL, 0UL, 1UL, 0UL }))); @@ -35,8 +43,10 @@ template class aluImpl { (new_term.alu_u64_tag * FF(4294967296UL))) + (new_term.alu_u128_tag * FF(uint256_t{ 0UL, 1UL, 0UL, 0UL }))); const auto alu_PRODUCT = - (((new_term.alu_a_lo * new_term.alu_b_lo) + (alu_LIMB_BITS_POW * new_term.alu_partial_prod_lo)) + - (alu_MAX_BITS_POW * (new_term.alu_partial_prod_hi + (new_term.alu_a_hi * new_term.alu_b_hi)))); + ((new_term.alu_a_lo * new_term.alu_b_lo) + + ((FF(1) - new_term.alu_u1_tag) * + ((alu_LIMB_BITS_POW * new_term.alu_partial_prod_lo) + + (alu_MAX_BITS_POW * (new_term.alu_partial_prod_hi + (new_term.alu_a_hi * new_term.alu_b_hi)))))); const auto alu_RESULT = ((new_term.alu_op_add * (new_term.alu_ia + new_term.alu_ib)) + (new_term.alu_op_sub * (new_term.alu_ia - new_term.alu_ib))); const auto alu_NON_TRIVIAL_SHIFT = (FF(1) - new_term.alu_zero_shift); @@ -58,7 +68,7 @@ template class aluImpl { } { using Accumulator = typename std::tuple_element_t<1, ContainerOverSubrelations>; - auto tmp = (new_term.alu_ff_tag * (FF(1) - new_term.alu_ff_tag)); + auto tmp = (new_term.alu_u1_tag * (FF(1) - new_term.alu_u1_tag)); tmp *= scaling_factor; std::get<1>(evals) += typename Accumulator::View(tmp); } @@ -94,27 +104,36 @@ template class aluImpl { } { using Accumulator = typename std::tuple_element_t<7, ContainerOverSubrelations>; - auto tmp = - (new_term.alu_sel_alu * - ((((((new_term.alu_ff_tag + new_term.alu_u8_tag) + new_term.alu_u16_tag) + new_term.alu_u32_tag) + - new_term.alu_u64_tag) + - new_term.alu_u128_tag) - - FF(1))); + auto tmp = (new_term.alu_ff_tag * (FF(1) - new_term.alu_ff_tag)); tmp *= scaling_factor; std::get<7>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<8, ContainerOverSubrelations>; - auto tmp = (new_term.alu_in_tag - - (((((new_term.alu_u8_tag + (FF(2) * new_term.alu_u16_tag)) + (FF(3) * new_term.alu_u32_tag)) + - (FF(4) * new_term.alu_u64_tag)) + - (FF(5) * new_term.alu_u128_tag)) + - (FF(6) * new_term.alu_ff_tag))); + auto tmp = + (new_term.alu_sel_alu * + (((((((new_term.alu_u1_tag + new_term.alu_u8_tag) + new_term.alu_u16_tag) + new_term.alu_u32_tag) + + new_term.alu_u64_tag) + + new_term.alu_u128_tag) + + new_term.alu_ff_tag) - + FF(1))); tmp *= scaling_factor; std::get<8>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<9, ContainerOverSubrelations>; + auto tmp = + (new_term.alu_in_tag - ((((((new_term.alu_u1_tag + (constants_MEM_TAG_U8 * new_term.alu_u8_tag)) + + (constants_MEM_TAG_U16 * new_term.alu_u16_tag)) + + (constants_MEM_TAG_U32 * new_term.alu_u32_tag)) + + (constants_MEM_TAG_U64 * new_term.alu_u64_tag)) + + (constants_MEM_TAG_U128 * new_term.alu_u128_tag)) + + (constants_MEM_TAG_FF * new_term.alu_ff_tag))); + tmp *= scaling_factor; + std::get<9>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<10, ContainerOverSubrelations>; auto tmp = (new_term.alu_range_check_sel - (((FF(1) - new_term.alu_ff_tag) * @@ -122,10 +141,10 @@ template class aluImpl { new_term.alu_op_div)) + ((new_term.alu_op_shr + new_term.alu_op_shl) * alu_NON_TRIVIAL_SHIFT))); tmp *= scaling_factor; - std::get<9>(evals) += typename Accumulator::View(tmp); + std::get<10>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<10, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<11, ContainerOverSubrelations>; auto tmp = (new_term.alu_range_check_input_value - (((((((new_term.alu_op_add + new_term.alu_op_sub) + new_term.alu_op_mul) + new_term.alu_op_cast) + @@ -134,261 +153,262 @@ template class aluImpl { ((new_term.alu_op_shr * new_term.alu_a_hi) * alu_NON_TRIVIAL_SHIFT)) + ((new_term.alu_op_shl * new_term.alu_a_lo) * alu_NON_TRIVIAL_SHIFT))); tmp *= scaling_factor; - std::get<10>(evals) += typename Accumulator::View(tmp); + std::get<11>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<11, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<12, ContainerOverSubrelations>; auto tmp = (new_term.alu_range_check_num_bits - ((((((new_term.alu_op_add + new_term.alu_op_sub) + new_term.alu_op_mul) + new_term.alu_op_cast) + new_term.alu_op_div) * - (((((new_term.alu_u8_tag * FF(8)) + (new_term.alu_u16_tag * FF(16))) + + ((((((new_term.alu_u1_tag * FF(1)) + (new_term.alu_u8_tag * FF(8))) + + (new_term.alu_u16_tag * FF(16))) + (new_term.alu_u32_tag * FF(32))) + (new_term.alu_u64_tag * FF(64))) + (new_term.alu_u128_tag * FF(128)))) + (((new_term.alu_op_shl + new_term.alu_op_shr) * (alu_MAX_BITS - new_term.alu_ib)) * alu_NON_TRIVIAL_SHIFT))); tmp *= scaling_factor; - std::get<11>(evals) += typename Accumulator::View(tmp); + std::get<12>(evals) += typename Accumulator::View(tmp); } { - using Accumulator = typename std::tuple_element_t<12, ContainerOverSubrelations>; + using Accumulator = typename std::tuple_element_t<13, ContainerOverSubrelations>; auto tmp = (new_term.alu_cmp_gadget_gt - ((((new_term.alu_op_lt + new_term.alu_op_lte) + new_term.alu_op_div) + new_term.alu_op_shr) + new_term.alu_op_shl)); tmp *= scaling_factor; - std::get<12>(evals) += typename Accumulator::View(tmp); - } - { - using Accumulator = typename std::tuple_element_t<13, ContainerOverSubrelations>; - auto tmp = (new_term.alu_cmp_gadget_sel - (new_term.alu_cmp_gadget_gt + new_term.alu_op_eq)); - tmp *= scaling_factor; std::get<13>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<14, ContainerOverSubrelations>; - auto tmp = (((new_term.alu_a_lo * new_term.alu_b_hi) + (new_term.alu_b_lo * new_term.alu_a_hi)) - - (new_term.alu_partial_prod_lo + (alu_LIMB_BITS_POW * new_term.alu_partial_prod_hi))); + auto tmp = (new_term.alu_cmp_gadget_sel - (new_term.alu_cmp_gadget_gt + new_term.alu_op_eq)); tmp *= scaling_factor; std::get<14>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<15, ContainerOverSubrelations>; - auto tmp = (new_term.alu_cf * (FF(1) - new_term.alu_cf)); + auto tmp = (((new_term.alu_a_lo * new_term.alu_b_hi) + (new_term.alu_b_lo * new_term.alu_a_hi)) - + (new_term.alu_partial_prod_lo + (alu_LIMB_BITS_POW * new_term.alu_partial_prod_hi))); tmp *= scaling_factor; std::get<15>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<16, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_add * ((alu_RESULT - new_term.alu_ic) - (new_term.alu_cf * alu_MAX_BITS_POW))); + auto tmp = (new_term.alu_cf * (FF(1) - new_term.alu_cf)); tmp *= scaling_factor; std::get<16>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<17, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_sub * ((alu_RESULT - new_term.alu_ic) + (new_term.alu_cf * alu_MAX_BITS_POW))); + auto tmp = (new_term.alu_op_add * ((alu_RESULT - new_term.alu_ic) - (new_term.alu_cf * alu_MAX_BITS_POW))); tmp *= scaling_factor; std::get<17>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<18, ContainerOverSubrelations>; - auto tmp = - ((new_term.alu_ff_tag * new_term.alu_op_mul) * ((new_term.alu_ia * new_term.alu_ib) - new_term.alu_ic)); + auto tmp = (new_term.alu_op_sub * ((alu_RESULT - new_term.alu_ic) + (new_term.alu_cf * alu_MAX_BITS_POW))); tmp *= scaling_factor; std::get<18>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<19, ContainerOverSubrelations>; - auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_mul) * - ((new_term.alu_ia - new_term.alu_a_lo) - (alu_LIMB_BITS_POW * new_term.alu_a_hi))); + auto tmp = + ((new_term.alu_ff_tag * new_term.alu_op_mul) * ((new_term.alu_ia * new_term.alu_ib) - new_term.alu_ic)); tmp *= scaling_factor; std::get<19>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<20, ContainerOverSubrelations>; auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_mul) * - ((new_term.alu_ib - new_term.alu_b_lo) - (alu_LIMB_BITS_POW * new_term.alu_b_hi))); + ((new_term.alu_ia - new_term.alu_a_lo) - (alu_LIMB_BITS_POW * new_term.alu_a_hi))); tmp *= scaling_factor; std::get<20>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<21, ContainerOverSubrelations>; - auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_mul) * (new_term.alu_ic - new_term.alu_c_lo)); + auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_mul) * + ((new_term.alu_ib - new_term.alu_b_lo) - (alu_LIMB_BITS_POW * new_term.alu_b_hi))); tmp *= scaling_factor; std::get<21>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<22, ContainerOverSubrelations>; - auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_mul) * - (alu_PRODUCT - (new_term.alu_c_lo + (alu_MAX_BITS_POW * new_term.alu_c_hi)))); + auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_mul) * (new_term.alu_ic - new_term.alu_c_lo)); tmp *= scaling_factor; std::get<22>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<23, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_div * (new_term.alu_cmp_gadget_input_a - new_term.alu_ib)); + auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_mul) * + (alu_PRODUCT - (new_term.alu_c_lo + (alu_MAX_BITS_POW * new_term.alu_c_hi)))); tmp *= scaling_factor; std::get<23>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<24, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_div * (new_term.alu_cmp_gadget_input_b - new_term.alu_remainder)); + auto tmp = (new_term.alu_op_div * (new_term.alu_cmp_gadget_input_a - new_term.alu_ib)); tmp *= scaling_factor; std::get<24>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<25, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_div * (new_term.alu_cmp_gadget_result - FF(1))); + auto tmp = (new_term.alu_op_div * (new_term.alu_cmp_gadget_input_b - new_term.alu_remainder)); tmp *= scaling_factor; std::get<25>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<26, ContainerOverSubrelations>; - auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_div) * - ((new_term.alu_ib - new_term.alu_a_lo) - (alu_LIMB_BITS_POW * new_term.alu_a_hi))); + auto tmp = (new_term.alu_op_div * (new_term.alu_cmp_gadget_result - FF(1))); tmp *= scaling_factor; std::get<26>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<27, ContainerOverSubrelations>; auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_div) * - ((new_term.alu_ic - new_term.alu_b_lo) - (alu_LIMB_BITS_POW * new_term.alu_b_hi))); + ((new_term.alu_ib - new_term.alu_a_lo) - (alu_LIMB_BITS_POW * new_term.alu_a_hi))); tmp *= scaling_factor; std::get<27>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<28, ContainerOverSubrelations>; - auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_div) * (new_term.alu_ia - new_term.alu_c_lo)); + auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_div) * + ((new_term.alu_ic - new_term.alu_b_lo) - (alu_LIMB_BITS_POW * new_term.alu_b_hi))); tmp *= scaling_factor; std::get<28>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<29, ContainerOverSubrelations>; - auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_div) * - (alu_PRODUCT - - ((new_term.alu_c_lo - new_term.alu_remainder) + (alu_MAX_BITS_POW * new_term.alu_c_hi)))); + auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_div) * (new_term.alu_ia - new_term.alu_c_lo)); tmp *= scaling_factor; std::get<29>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<30, ContainerOverSubrelations>; - auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_not) * - ((new_term.alu_ia + new_term.alu_ic) - alu_UINT_MAX)); + auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_div) * + (alu_PRODUCT - + ((new_term.alu_c_lo - new_term.alu_remainder) + (alu_MAX_BITS_POW * new_term.alu_c_hi)))); tmp *= scaling_factor; std::get<30>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<31, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_eq * (new_term.alu_ia - new_term.alu_cmp_gadget_input_a)); + auto tmp = (((FF(1) - new_term.alu_ff_tag) * new_term.alu_op_not) * + ((new_term.alu_ia + new_term.alu_ic) - alu_UINT_MAX)); tmp *= scaling_factor; std::get<31>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<32, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_eq * (new_term.alu_ib - new_term.alu_cmp_gadget_input_b)); + auto tmp = (new_term.alu_op_eq * (new_term.alu_ia - new_term.alu_cmp_gadget_input_a)); tmp *= scaling_factor; std::get<32>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<33, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_eq * (new_term.alu_ic - new_term.alu_cmp_gadget_result)); + auto tmp = (new_term.alu_op_eq * (new_term.alu_ib - new_term.alu_cmp_gadget_input_b)); tmp *= scaling_factor; std::get<33>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<34, ContainerOverSubrelations>; - auto tmp = (new_term.alu_sel_cmp - (new_term.alu_op_lt + new_term.alu_op_lte)); + auto tmp = (new_term.alu_op_eq * (new_term.alu_ic - new_term.alu_cmp_gadget_result)); tmp *= scaling_factor; std::get<34>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<35, ContainerOverSubrelations>; - auto tmp = ((new_term.alu_op_lt * (new_term.alu_ib - new_term.alu_cmp_gadget_input_a)) + - (new_term.alu_op_lte * (new_term.alu_ia - new_term.alu_cmp_gadget_input_a))); + auto tmp = (new_term.alu_sel_cmp - (new_term.alu_op_lt + new_term.alu_op_lte)); tmp *= scaling_factor; std::get<35>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<36, ContainerOverSubrelations>; - auto tmp = ((new_term.alu_op_lt * (new_term.alu_ia - new_term.alu_cmp_gadget_input_b)) + - (new_term.alu_op_lte * (new_term.alu_ib - new_term.alu_cmp_gadget_input_b))); + auto tmp = ((new_term.alu_op_lt * (new_term.alu_ib - new_term.alu_cmp_gadget_input_a)) + + (new_term.alu_op_lte * (new_term.alu_ia - new_term.alu_cmp_gadget_input_a))); tmp *= scaling_factor; std::get<36>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<37, ContainerOverSubrelations>; - auto tmp = ((new_term.alu_op_lte * ((FF(1) - new_term.alu_cmp_gadget_result) - new_term.alu_ic)) + - (new_term.alu_op_lt * (new_term.alu_cmp_gadget_result - new_term.alu_ic))); + auto tmp = ((new_term.alu_op_lt * (new_term.alu_ia - new_term.alu_cmp_gadget_input_b)) + + (new_term.alu_op_lte * (new_term.alu_ib - new_term.alu_cmp_gadget_input_b))); tmp *= scaling_factor; std::get<37>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<38, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_cast * - ((new_term.alu_ia - new_term.alu_a_lo) - (alu_MAX_BITS_POW * new_term.alu_a_hi))); + auto tmp = ((new_term.alu_op_lte * ((FF(1) - new_term.alu_cmp_gadget_result) - new_term.alu_ic)) + + (new_term.alu_op_lt * (new_term.alu_cmp_gadget_result - new_term.alu_ic))); tmp *= scaling_factor; std::get<38>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<39, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_cast * (new_term.alu_ic - new_term.alu_a_lo)); + auto tmp = (new_term.alu_op_cast * + ((new_term.alu_ia - new_term.alu_a_lo) - (alu_MAX_BITS_POW * new_term.alu_a_hi))); tmp *= scaling_factor; std::get<39>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<40, ContainerOverSubrelations>; - auto tmp = - ((new_term.alu_op_shl + new_term.alu_op_shr) * (new_term.alu_cmp_gadget_input_a - new_term.alu_ib)); + auto tmp = (new_term.alu_op_cast * (new_term.alu_ic - new_term.alu_a_lo)); tmp *= scaling_factor; std::get<40>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<41, ContainerOverSubrelations>; - auto tmp = ((new_term.alu_op_shl + new_term.alu_op_shr) * - (new_term.alu_cmp_gadget_input_b - (alu_MAX_BITS - FF(1)))); + auto tmp = + ((new_term.alu_op_shl + new_term.alu_op_shr) * (new_term.alu_cmp_gadget_input_a - new_term.alu_ib)); tmp *= scaling_factor; std::get<41>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<42, ContainerOverSubrelations>; auto tmp = ((new_term.alu_op_shl + new_term.alu_op_shr) * - (new_term.alu_zero_shift - new_term.alu_cmp_gadget_result)); + (new_term.alu_cmp_gadget_input_b - (alu_MAX_BITS - FF(1)))); tmp *= scaling_factor; std::get<42>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<43, ContainerOverSubrelations>; - auto tmp = - (new_term.alu_sel_shift_which - ((new_term.alu_op_shr + new_term.alu_op_shl) * alu_NON_TRIVIAL_SHIFT)); + auto tmp = ((new_term.alu_op_shl + new_term.alu_op_shr) * + (new_term.alu_zero_shift - new_term.alu_cmp_gadget_result)); tmp *= scaling_factor; std::get<43>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<44, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_shr * - ((new_term.alu_ia - new_term.alu_a_lo) - (new_term.alu_b_pow * new_term.alu_a_hi))); + auto tmp = + (new_term.alu_sel_shift_which - ((new_term.alu_op_shr + new_term.alu_op_shl) * alu_NON_TRIVIAL_SHIFT)); tmp *= scaling_factor; std::get<44>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<45, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_shr * (new_term.alu_ic - (new_term.alu_a_hi * alu_NON_TRIVIAL_SHIFT))); + auto tmp = (new_term.alu_op_shr * + ((new_term.alu_ia - new_term.alu_a_lo) - (new_term.alu_b_pow * new_term.alu_a_hi))); tmp *= scaling_factor; std::get<45>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<46, ContainerOverSubrelations>; - auto tmp = (new_term.alu_op_shl * ((new_term.alu_ia - new_term.alu_a_lo) - - (new_term.alu_max_bits_sub_b_pow * new_term.alu_a_hi))); + auto tmp = (new_term.alu_op_shr * (new_term.alu_ic - (new_term.alu_a_hi * alu_NON_TRIVIAL_SHIFT))); tmp *= scaling_factor; std::get<46>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<47, ContainerOverSubrelations>; + auto tmp = (new_term.alu_op_shl * ((new_term.alu_ia - new_term.alu_a_lo) - + (new_term.alu_max_bits_sub_b_pow * new_term.alu_a_hi))); + tmp *= scaling_factor; + std::get<47>(evals) += typename Accumulator::View(tmp); + } + { + using Accumulator = typename std::tuple_element_t<48, ContainerOverSubrelations>; auto tmp = (new_term.alu_op_shl * (new_term.alu_ic - ((new_term.alu_a_lo * new_term.alu_b_pow) * alu_NON_TRIVIAL_SHIFT))); tmp *= scaling_factor; - std::get<47>(evals) += typename Accumulator::View(tmp); + std::get<48>(evals) += typename Accumulator::View(tmp); } } }; @@ -400,13 +420,13 @@ template class alu : public Relation> { static std::string get_subrelation_label(size_t index) { switch (index) { - case 18: + case 19: return "ALU_MULTIPLICATION_FF"; - case 22: + case 23: return "ALU_PROD_MUL"; - case 29: - return "DIVISION_RELATION"; case 30: + return "DIVISION_RELATION"; + case 31: return "ALU_OP_NOT"; } return std::to_string(index); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp index 146bb6d1bc2..62c0ada9784 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/main.hpp @@ -23,6 +23,8 @@ template class mainImpl { [[maybe_unused]] const RelationParameters&, [[maybe_unused]] const FF& scaling_factor) { + const auto constants_MEM_TAG_U1 = FF(1); + const auto constants_MEM_TAG_FF = FF(7); const auto constants_misc_INTERNAL_CALL_SPACE_ID = FF(255); const auto main_KERNEL_INPUT_SELECTORS = ((((((((((new_term.main_sel_op_address + new_term.main_sel_op_storage_address) + @@ -534,7 +536,7 @@ template class mainImpl { { using Accumulator = typename std::tuple_element_t<74, ContainerOverSubrelations>; auto tmp = (((new_term.main_sel_op_eq + new_term.main_sel_op_lte) + new_term.main_sel_op_lt) * - (new_term.main_w_in_tag - FF(1))); + (new_term.main_w_in_tag - constants_MEM_TAG_U1)); tmp *= scaling_factor; std::get<74>(evals) += typename Accumulator::View(tmp); } @@ -561,13 +563,13 @@ template class mainImpl { } { using Accumulator = typename std::tuple_element_t<78, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_fdiv * (new_term.main_r_in_tag - FF(6))); + auto tmp = (new_term.main_sel_op_fdiv * (new_term.main_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<78>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<79, ContainerOverSubrelations>; - auto tmp = (new_term.main_sel_op_fdiv * (new_term.main_w_in_tag - FF(6))); + auto tmp = (new_term.main_sel_op_fdiv * (new_term.main_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<79>(evals) += typename Accumulator::View(tmp); } @@ -800,7 +802,7 @@ template class main : public Relation> { case 0: return "OPCODE_SELECTORS"; case 74: - return "OUTPUT_U8"; + return "OUTPUT_U1"; case 75: return "SUBOP_FDIV"; case 76: diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/mem.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/mem.hpp index b99228615e9..e52feb9a46b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/mem.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/mem.hpp @@ -21,6 +21,8 @@ template class memImpl { [[maybe_unused]] const RelationParameters&, [[maybe_unused]] const FF& scaling_factor) { + const auto constants_MEM_TAG_U32 = FF(4); + const auto constants_MEM_TAG_FF = FF(7); const auto mem_SEL_DIRECT_MEM_OP_A = ((new_term.mem_sel_op_a + new_term.mem_sel_op_poseidon_read_a) + new_term.mem_sel_op_poseidon_write_a); const auto mem_SEL_DIRECT_MEM_OP_B = @@ -258,25 +260,25 @@ template class memImpl { } { using Accumulator = typename std::tuple_element_t<33, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_a * (new_term.mem_r_in_tag - FF(3))); + auto tmp = (new_term.mem_sel_resolve_ind_addr_a * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); tmp *= scaling_factor; std::get<33>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<34, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_b * (new_term.mem_r_in_tag - FF(3))); + auto tmp = (new_term.mem_sel_resolve_ind_addr_b * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); tmp *= scaling_factor; std::get<34>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<35, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_c * (new_term.mem_r_in_tag - FF(3))); + auto tmp = (new_term.mem_sel_resolve_ind_addr_c * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); tmp *= scaling_factor; std::get<35>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<36, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_resolve_ind_addr_d * (new_term.mem_r_in_tag - FF(3))); + auto tmp = (new_term.mem_sel_resolve_ind_addr_d * (new_term.mem_r_in_tag - constants_MEM_TAG_U32)); tmp *= scaling_factor; std::get<36>(evals) += typename Accumulator::View(tmp); } @@ -306,61 +308,61 @@ template class memImpl { } { using Accumulator = typename std::tuple_element_t<41, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_slice * (new_term.mem_w_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_slice * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<41>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<42, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_slice * (new_term.mem_r_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_slice * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<42>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<43, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_read_a * (new_term.mem_w_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_poseidon_read_a * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<43>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<44, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_read_b * (new_term.mem_w_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_poseidon_read_b * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<44>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<45, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_read_c * (new_term.mem_w_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_poseidon_read_c * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<45>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<46, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_read_d * (new_term.mem_w_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_poseidon_read_d * (new_term.mem_w_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<46>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<47, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_write_a * (new_term.mem_r_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_poseidon_write_a * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<47>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<48, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_write_b * (new_term.mem_r_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_poseidon_write_b * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<48>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<49, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_write_c * (new_term.mem_r_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_poseidon_write_c * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<49>(evals) += typename Accumulator::View(tmp); } { using Accumulator = typename std::tuple_element_t<50, ContainerOverSubrelations>; - auto tmp = (new_term.mem_sel_op_poseidon_write_d * (new_term.mem_r_in_tag - FF(6))); + auto tmp = (new_term.mem_sel_op_poseidon_write_d * (new_term.mem_r_in_tag - constants_MEM_TAG_FF)); tmp *= scaling_factor; std::get<50>(evals) += typename Accumulator::View(tmp); } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/perm_main_conv.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/perm_main_conv.hpp index 70fabd25948..a97b8c1a046 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/perm_main_conv.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/relations/perm_main_conv.hpp @@ -11,7 +11,7 @@ namespace bb { class perm_main_conv_permutation_settings { public: // This constant defines how many columns are bundled together to form each set. - constexpr static size_t COLUMNS_PER_SET = 4; + constexpr static size_t COLUMNS_PER_SET = 5; template static inline auto inverse_polynomial_is_computed_at_row(const AllEntities& in) { @@ -26,12 +26,14 @@ class perm_main_conv_permutation_settings { in.conversion_sel_to_radix_le, in.main_clk, in.main_ia, + in.main_ib, in.main_ic, in.main_id, in.conversion_clk, in.conversion_input, in.conversion_radix, - in.conversion_num_limbs); + in.conversion_num_limbs, + in.conversion_output_bits); } template static inline auto get_nonconst_entities(AllEntities& in) @@ -42,12 +44,14 @@ class perm_main_conv_permutation_settings { in.conversion_sel_to_radix_le, in.main_clk, in.main_ia, + in.main_ib, in.main_ic, in.main_id, in.conversion_clk, in.conversion_input, in.conversion_radix, - in.conversion_num_limbs); + in.conversion_num_limbs, + in.conversion_output_bits); } }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp index ea204252647..e5367cd8cce 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/arithmetic.test.cpp @@ -162,7 +162,7 @@ size_t common_validate_eq(std::vector const& trace, EXPECT_TRUE(alu_row != trace.end()); common_validate_arithmetic_op(*row, *alu_row, a, b, c, addr_a, addr_b, addr_c, tag); - EXPECT_EQ(row->main_w_in_tag, FF(static_cast(AvmMemoryTag::U8))); + EXPECT_EQ(row->main_w_in_tag, FF(static_cast(AvmMemoryTag::U1))); // Check that equality selector is set. EXPECT_EQ(row->main_sel_op_eq, FF(1)); @@ -314,6 +314,7 @@ class AvmArithmeticTests : public ::testing::Test { }; class AvmArithmeticTestsFF : public AvmArithmeticTests {}; +class AvmArithmeticTestsU1 : public AvmArithmeticTests {}; class AvmArithmeticTestsU8 : public AvmArithmeticTests {}; class AvmArithmeticTestsU16 : public AvmArithmeticTests {}; class AvmArithmeticTestsU32 : public AvmArithmeticTests {}; @@ -325,6 +326,10 @@ class AvmArithmeticNegativeTestsFF : public AvmArithmeticTests { protected: void SetUp() override { GTEST_SKIP(); } }; +class AvmArithmeticNegativeTestsU1 : public AvmArithmeticTests { + protected: + void SetUp() override { GTEST_SKIP(); } +}; class AvmArithmeticNegativeTestsU8 : public AvmArithmeticTests { protected: void SetUp() override { GTEST_SKIP(); } @@ -347,9 +352,10 @@ class AvmArithmeticNegativeTestsU128 : public AvmArithmeticTests { }; std::vector uint_mem_tags{ - { AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } + { AvmMemoryTag::U1, AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } }; std::vector> positive_op_div_test_values = { { + { FF(1), FF(1), FF(1) }, { FF(10), FF(5), FF(2) }, { FF(5323), FF(5323), FF(1) }, { FF(13793), FF(10590617LLU), FF(0) }, @@ -708,6 +714,155 @@ TEST_F(AvmArithmeticTests, DivisionByZeroError) validate_trace(std::move(trace), public_inputs); } +/****************************************************************************** + * Positive Tests - U1 + ******************************************************************************/ + +// Test on basic addition over u1 type. +TEST_F(AvmArithmeticTestsU1, addition) +{ + // trace_builder + trace_builder.op_set(0, 1, 0, AvmMemoryTag::U1); + trace_builder.op_set(0, 0, 1, AvmMemoryTag::U1); + + // Memory layout: [1,0,0,0,0,....] + trace_builder.op_add(0, 0, 1, 2, AvmMemoryTag::U1); // [1,0,1,0,0,....] + trace_builder.op_return(0, 0, 0); + auto trace = trace_builder.finalize(); + + auto alu_row = common_validate_add(trace, FF(1), FF(0), FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::U1); + + EXPECT_EQ(alu_row.alu_u1_tag, FF(1)); + EXPECT_EQ(alu_row.alu_cf, FF(0)); + + validate_trace(std::move(trace), public_inputs); +} + +// Test on basic addition over u1 type with carry. +TEST_F(AvmArithmeticTestsU1, additionCarry) +{ + // trace_builder + trace_builder.op_set(0, 1, 0, AvmMemoryTag::U1); + trace_builder.op_set(0, 1, 1, AvmMemoryTag::U1); + + // Memory layout: [1,1,0,0,0,....] + trace_builder.op_add(0, 0, 1, 2, AvmMemoryTag::U1); // [1,1,0,0,0,....] + trace_builder.op_return(0, 0, 0); + auto trace = trace_builder.finalize(); + + auto alu_row = common_validate_add(trace, FF(1), FF(1), FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::U1); + + EXPECT_EQ(alu_row.alu_u1_tag, FF(1)); + EXPECT_EQ(alu_row.alu_cf, FF(1)); + + validate_trace(std::move(trace), public_inputs); +} + +// Test on basic subtraction over u1 type. +TEST_F(AvmArithmeticTestsU1, subtraction) +{ + // trace_builder + trace_builder.op_set(0, 1, 0, AvmMemoryTag::U1); + trace_builder.op_set(0, 1, 1, AvmMemoryTag::U1); + + // Memory layout: [1,1,0,0,0,....] + trace_builder.op_sub(0, 0, 1, 2, AvmMemoryTag::U1); // [1,1,0,0,0,....] + trace_builder.op_return(0, 0, 0); + auto trace = trace_builder.finalize(); + + auto alu_row = common_validate_sub(trace, FF(1), FF(1), FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::U1); + + EXPECT_EQ(alu_row.alu_u1_tag, FF(1)); + EXPECT_EQ(alu_row.alu_cf, FF(0)); + + validate_trace(std::move(trace), public_inputs); +} + +// Test on subtraction over u1 type with carry. +// For a subtraction a - b = c, there is a carry flag iff a < b (equivalent to a < c) +TEST_F(AvmArithmeticTestsU1, subtractionCarry) +{ + // trace_builder + trace_builder.op_set(0, 0, 0, AvmMemoryTag::U1); + trace_builder.op_set(0, 1, 1, AvmMemoryTag::U1); + + // Memory layout: [0,1,0,0,0,....] + trace_builder.op_sub(0, 0, 1, 2, AvmMemoryTag::U1); // [0,1,1,0,0,....] + trace_builder.op_return(0, 0, 0); + auto trace = trace_builder.finalize(); + + auto alu_row = common_validate_sub(trace, FF(0), FF(1), FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::U1); + + EXPECT_EQ(alu_row.alu_u1_tag, FF(1)); + EXPECT_EQ(alu_row.alu_cf, FF(1)); + + validate_trace(std::move(trace), public_inputs); +} + +// Test on basic multiplication over u1 type. +TEST_F(AvmArithmeticTestsU1, multiplication) +{ + // trace_builder + trace_builder.op_set(0, 1, 0, AvmMemoryTag::U1); + trace_builder.op_set(0, 1, 1, AvmMemoryTag::U1); + + trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U1); + trace_builder.op_return(0, 0, 0); + auto trace = trace_builder.finalize(); + + auto alu_row_index = common_validate_mul(trace, FF(1), FF(1), FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::U1); + auto alu_row = trace.at(alu_row_index); + + EXPECT_EQ(alu_row.alu_u1_tag, FF(1)); + + validate_trace(std::move(trace), public_inputs); +} + +// Test on basic multiplication by 0 over u1 type. +TEST_F(AvmArithmeticTestsU1, multiplicationByzero) +{ + // trace_builder + trace_builder.op_set(0, 1, 0, AvmMemoryTag::U1); + trace_builder.op_set(0, 0, 1, AvmMemoryTag::U1); + + trace_builder.op_mul(0, 0, 1, 2, AvmMemoryTag::U1); + trace_builder.op_return(0, 0, 0); + auto trace = trace_builder.finalize(); + + auto alu_row_index = common_validate_mul(trace, FF(1), FF(0), FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::U1); + auto alu_row = trace.at(alu_row_index); + + EXPECT_EQ(alu_row.alu_u1_tag, FF(1)); + + validate_trace(std::move(trace), public_inputs); +} + +// Test of equality on u1 elements +TEST_F(AvmArithmeticTestsU1, equality) +{ + auto trace = gen_trace_eq(1, 1, 0, 1, 2, AvmMemoryTag::U1); + + auto alu_row_index = common_validate_eq(trace, FF(1), FF(1), FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::U1); + auto alu_row = trace.at(alu_row_index); + + EXPECT_EQ(alu_row.alu_u1_tag, FF(1)); + EXPECT_EQ(alu_row.cmp_op_eq_diff_inv, FF(0)); + validate_trace(std::move(trace), public_inputs); +} + +// Test correct non-equality of U1 elements +TEST_F(AvmArithmeticTestsU1, nonEquality) +{ + auto trace = gen_trace_eq(0, 1, 12, 15, 28, AvmMemoryTag::U1); + + auto alu_row_index = common_validate_eq(trace, 0, 1, FF(0), FF(12), FF(15), FF(28), AvmMemoryTag::U1); + auto alu_row = trace.at(alu_row_index); + + EXPECT_EQ(alu_row.alu_u1_tag, FF(1)); + EXPECT_EQ(alu_row.cmp_op_eq_diff_inv, FF(-1).invert()); + validate_trace(std::move(trace), public_inputs); +} + /****************************************************************************** * Positive Tests - U8 ******************************************************************************/ @@ -1771,7 +1926,7 @@ TEST_F(AvmArithmeticNegativeTestsFF, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->main_w_in_tag = FF(4); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U1"); } // Tests a situation for field elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -1839,7 +1994,7 @@ TEST_F(AvmArithmeticNegativeTestsU8, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->main_w_in_tag = FF(3); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U1"); } // Tests a situation for U8 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -1906,7 +2061,7 @@ TEST_F(AvmArithmeticNegativeTestsU16, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->main_w_in_tag = FF(5); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U1"); } // Tests a situation for U16 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -1973,7 +2128,7 @@ TEST_F(AvmArithmeticNegativeTestsU32, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->main_w_in_tag = FF(6); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U1"); } // Tests a situation for U32 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -2047,7 +2202,7 @@ TEST_F(AvmArithmeticNegativeTestsU64, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->main_w_in_tag = FF(2); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U1"); } // Tests a situation for U64 elements the (a-b)^1 is incorrect. i.e. (a-b) * (a-b)^1 != 1 for (a-b) != 0; @@ -2177,7 +2332,7 @@ TEST_F(AvmArithmeticNegativeTestsU128, eqOutputWrongTag) ASSERT_TRUE(row != trace.end()); row->main_w_in_tag = FF(4); - EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U8"); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "OUTPUT_U1"); } // 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/avm/tests/bitwise.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp index 921225665ea..d8c08470596 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/bitwise.test.cpp @@ -67,6 +67,9 @@ void common_validate_op_not(std::vector const& trace, case AvmMemoryTag::U0: FAIL() << "Unintialized Mem Tags Disallowed"; break; + case AvmMemoryTag::U1: + EXPECT_EQ(alu_row->alu_u1_tag, FF(1)); + break; case AvmMemoryTag::U8: EXPECT_EQ(alu_row->alu_u8_tag, FF(1)); break; @@ -377,10 +380,11 @@ class AvmBitwiseTests : public ::testing::Test { using TwoOpParamRow = std::tuple, AvmMemoryTag>; std::vector mem_tags{ - { AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } + { AvmMemoryTag::U1, AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } }; -std::vector> positive_op_not_test_values = { { { 1, 254 }, +std::vector> positive_op_not_test_values = { { { 1, 0 }, + { 1, 254 }, { 512, 65'023 }, { 131'072, 4'294'836'223LLU }, { 0x100000000LLU, 0xfffffffeffffffffLLU }, @@ -401,6 +405,7 @@ std::vector gen_two_op_params(std::vector> oper std::vector positive_op_and_test_values = { { { FF(1), FF(1), FF(1) }, + { FF(1), FF(1), FF(1) }, { FF(5323), FF(321), FF(65) }, { FF(13793), FF(10590617LLU), FF(4481) }, { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), FF(0x14444c0ccc30LLU) }, @@ -411,6 +416,7 @@ std::vector positive_op_and_test_values = { std::vector> positive_op_or_test_values = { { { FF(1), FF(1), FF(1) }, + { FF(1), FF(1), FF(1) }, { FF(5323), FF(321), FF(0x15cb) }, { FF(13793), FF(10590617LLU), FF(0xa1bdf9) }, { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), FF(0x7bfffccefcdfffLLU) }, @@ -420,6 +426,7 @@ std::vector> positive_op_or_test_values = { }; std::vector> positive_op_xor_test_values = { { { FF(1), FF(1), FF(0) }, + { FF(1), FF(1), FF(0) }, { FF(5323), FF(321), FF(0x158a) }, { FF(13793), FF(10590617LLU), FF(0xa1ac78) }, { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), uint256_t::from_uint128(0x7bebb882f013cf) }, @@ -428,7 +435,8 @@ std::vector> positive_op_xor_test_values = { uint256_t::from_uint128((uint128_t{ 0xa906021301080001 } << 64) + uint128_t{ 0x0001080876844827 }) } } }; std::vector> positive_op_shr_test_values = { - { { FF(20), FF(3), FF(2) }, + { { FF(1), FF(1), FF(0) }, + { FF(20), FF(3), FF(2) }, { FF(5323), FF(255), FF(0) }, { FF(36148), FF(13), FF(4) }, { FF(0x7bff744e3cdf79LLU), FF(64), FF(0) }, @@ -437,7 +445,8 @@ std::vector> positive_op_shr_test_values = { FF(2) } } }; std::vector> positive_op_shl_test_values = { - { { FF(20), FF(8), FF(0) }, + { { FF(1), FF(1), FF(0) }, + { FF(20), FF(8), FF(0) }, { FF(5323), FF(10), FF(11264) }, { FF(13793), FF(255), FF(0) }, { FF(239), FF(50), uint256_t::from_uint128(269090077735387136) }, @@ -602,6 +611,10 @@ class AvmBitwiseNegativeTestsFF : public AvmBitwiseTests { protected: void SetUp() override { GTEST_SKIP(); } }; +class AvmBitwiseNegativeTestsU1 : public AvmBitwiseTests { + protected: + void SetUp() override { GTEST_SKIP(); } +}; class AvmBitwiseNegativeTestsU8 : public AvmBitwiseTests { protected: void SetUp() override { GTEST_SKIP(); } @@ -754,19 +767,25 @@ TEST_F(AvmBitwiseNegativeTestsFF, UndefinedOverFF) // TODO(ilyas): When the SET opcodes applies relational constraints, this will fail // we will need to look at a new way of doing this test. for (size_t i = 1; i < 4; i++) { - trace.at(i).mem_tag = FF(6); - trace.at(i).mem_r_in_tag = FF(6); - trace.at(i).mem_w_in_tag = FF(6); + trace.at(i).mem_tag = FF(static_cast(AvmMemoryTag::FF)); + trace.at(i).mem_r_in_tag = FF(static_cast(AvmMemoryTag::FF)); + trace.at(i).mem_w_in_tag = FF(static_cast(AvmMemoryTag::FF)); trace.at(i).alu_ff_tag = FF::one(); trace.at(i).alu_u8_tag = FF::zero(); - trace.at(i).main_r_in_tag = FF(6); - trace.at(i).main_w_in_tag = FF(6); - trace.at(i).alu_in_tag = FF(6); + trace.at(i).main_r_in_tag = FF(static_cast(AvmMemoryTag::FF)); + trace.at(i).main_w_in_tag = FF(static_cast(AvmMemoryTag::FF)); + trace.at(i).alu_in_tag = FF(static_cast(AvmMemoryTag::FF)); } EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_FF_NOT_XOR"); } +TEST_F(AvmBitwiseNegativeTestsU1, BitwiseNot) +{ + std::vector trace = gen_mutated_trace_not(FF{ 0 }, FF{ 0 }, AvmMemoryTag::U1); + EXPECT_THROW_WITH_MESSAGE(validate_trace_check_circuit(std::move(trace)), "ALU_OP_NOT"); +} + TEST_F(AvmBitwiseNegativeTestsU8, BitwiseNot) { std::vector trace = gen_mutated_trace_not(FF{ 1 }, FF{ 2 }, AvmMemoryTag::U8); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp index b9985009ba3..4029174a709 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/cast.test.cpp @@ -121,6 +121,24 @@ class AvmCastNegativeTests : public AvmCastTests { void SetUp() override { GTEST_SKIP(); } }; +TEST_F(AvmCastTests, basicU1ToU8) +{ + gen_trace(1, 0, 1, AvmMemoryTag::U1, AvmMemoryTag::U8); + validate_cast_trace(1, 1, 0, 1, AvmMemoryTag::U1, AvmMemoryTag::U8); +} + +TEST_F(AvmCastTests, noTruncationU8ToU1) +{ + gen_trace(1, 0, 1, AvmMemoryTag::U8, AvmMemoryTag::U1); + validate_cast_trace(1, 1, 0, 1, AvmMemoryTag::U8, AvmMemoryTag::U1); +} + +TEST_F(AvmCastTests, truncationU8ToU1) +{ + gen_trace(15, 0, 1, AvmMemoryTag::U8, AvmMemoryTag::U1); + validate_cast_trace(15, 1, 0, 1, AvmMemoryTag::U8, AvmMemoryTag::U1); +} + TEST_F(AvmCastTests, basicU8ToU16) { gen_trace(237, 0, 1, AvmMemoryTag::U8, AvmMemoryTag::U16); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/comparison.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/comparison.test.cpp index b1315b0bb97..3cbd6b3e2df 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/comparison.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/comparison.test.cpp @@ -51,7 +51,7 @@ void common_validate_cmp(Row const& row, // Check the instruction tags EXPECT_EQ(row.main_r_in_tag, FF(static_cast(tag))); - EXPECT_EQ(row.main_w_in_tag, FF(static_cast(AvmMemoryTag::U8))); + EXPECT_EQ(row.main_w_in_tag, FF(static_cast(AvmMemoryTag::U1))); // Check that intermediate registers are correctly copied in Alu trace EXPECT_EQ(alu_row.alu_ia, a); @@ -60,6 +60,7 @@ void common_validate_cmp(Row const& row, } } // namespace std::vector positive_op_lt_test_values = { { { FF(1), FF(1), FF(0) }, + { FF(1), FF(1), FF(0) }, { FF(5323), FF(321), FF(0) }, { FF(13793), FF(10590617LLU), FF(1) }, { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), FF(0) }, @@ -69,6 +70,7 @@ std::vector positive_op_lt_test_values = { { { FF(1), FF(1), FF(0) 1 } } }; std::vector positive_op_lte_test_values = { { { FF(1), FF(1), FF(1) }, + { FF(1), FF(1), FF(1) }, { FF(5323), FF(321), FF(0) }, { FF(13793), FF(10590617LLU), FF(1) }, { FF(0x7bff744e3cdf79LLU), FF(0x14ccccccccb6LLU), FF(0) }, @@ -78,7 +80,7 @@ std::vector positive_op_lte_test_values = { }; std::vector mem_tag_arr{ - { AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } + { AvmMemoryTag::U1, AvmMemoryTag::U8, AvmMemoryTag::U16, AvmMemoryTag::U32, AvmMemoryTag::U64, AvmMemoryTag::U128 } }; class AvmCmpTests : public ::testing::Test { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp index bb6302e8662..cc5fca87b33 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp @@ -68,9 +68,9 @@ class AvmExecutionTests : public ::testing::Test { // Parsing, trace generation and proving is verified. TEST_F(AvmExecutionTests, basicAddReturn) { - std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD - "00" // Indirect flag - "01" // U8 + std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD + "00" // Indirect flag + + to_hex(AvmMemoryTag::U8) + "0007" // addr a 7 "0009" // addr b 9 "0001" // addr c 1 @@ -108,19 +108,19 @@ TEST_F(AvmExecutionTests, basicAddReturn) // Positive test for SET and SUB opcodes TEST_F(AvmExecutionTests, setAndSubOpcodes) { - std::string bytecode_hex = to_hex(OpCode::SET_16) + // opcode SET - "00" // Indirect flag - "02" // U16 + std::string bytecode_hex = to_hex(OpCode::SET_16) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U16) + "B813" // val 47123 "00AA" // dst_offset 170 + to_hex(OpCode::SET_16) + // opcode SET "00" // Indirect flag - "02" // U16 - "9103" // val 37123 - "0033" // dst_offset 51 - + to_hex(OpCode::SUB_8) + // opcode SUB - "00" // Indirect flag - "02" // U16 + + to_hex(AvmMemoryTag::U16) + + "9103" // val 37123 + "0033" // dst_offset 51 + + to_hex(OpCode::SUB_8) + // opcode SUB + "00" // Indirect flag + + to_hex(AvmMemoryTag::U16) + "AA" // addr a "33" // addr b "01" // addr c 1 @@ -178,23 +178,23 @@ TEST_F(AvmExecutionTests, setAndSubOpcodes) // the result at offset 1. TEST_F(AvmExecutionTests, powerWithMulOpcodes) { - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "04" // U64 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U64) + "05" // val "00" // dst_offset 0 + to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - "04" // U64 - "01" // val - "01"; // dst_offset 1 + + to_hex(AvmMemoryTag::U64) + + "01" // val + "01"; // dst_offset 1 std::string const mul_hex = to_hex(OpCode::MUL_8) + // opcode MUL "00" // Indirect flag - "04" // U64 - "00" // addr a - "01" // addr b - "01"; // addr c 1 + + to_hex(AvmMemoryTag::U64) + + "00" // addr a + "01" // addr b + "01"; // addr c 1 std::string const ret_hex = to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag @@ -259,26 +259,26 @@ TEST_F(AvmExecutionTests, powerWithMulOpcodes) // 0 1 2 3 4 5 TEST_F(AvmExecutionTests, simpleInternalCall) { - std::string bytecode_hex = to_hex(OpCode::SET_32) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_32) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "0D3D2518" // val 222111000 = 0xD3D2518 "0004" // dst_offset 4 + to_hex(OpCode::INTERNALCALL) + // opcode INTERNALCALL "00000004" // jmp_dest + to_hex(OpCode::ADD_16) + // opcode ADD "00" // Indirect flag - "03" // U32 - "0004" // addr a 4 - "0007" // addr b 7 - "0009" // addr c9 - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "00000000" // ret offset 0 - "00000000" // ret size 0 - + to_hex(OpCode::SET_32) + // opcode SET - "00" // Indirect flag - "03" // U32 + + to_hex(AvmMemoryTag::U32) + + "0004" // addr a 4 + "0007" // addr b 7 + "0009" // addr c9 + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000000" // ret offset 0 + "00000000" // ret size 0 + + to_hex(OpCode::SET_32) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "075BCD15" // val 123456789 = 0x75BCD15 "0007" // dst_offset 7 + to_hex(OpCode::INTERNALRETURN) // opcode INTERNALRETURN @@ -338,12 +338,11 @@ TEST_F(AvmExecutionTests, nestedInternalCalls) // val and dst_offset is assumed to be 2 bytes return to_hex(OpCode::SET_32) // opcode SET + "00" // Indirect flag - + "01" // U8 - + "000000" + val + "00" + dst_offset; + + to_hex(AvmMemoryTag::U8) + "000000" + val + "00" + dst_offset; }; - const std::string tag_address_arguments = "00" // Indirect Flag - "01" // U8 + const std::string tag_address_arguments = "00" // Indirect Flag + + to_hex(AvmMemoryTag::U8) + "02" // addr a 2 "03" // addr b 3 "02"; // addr c 2 @@ -401,14 +400,14 @@ TEST_F(AvmExecutionTests, nestedInternalCalls) // 0 1 2 3 4 TEST_F(AvmExecutionTests, jumpAndCalldatacopy) { - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 - "00" // val - "00" // dst_offset 101 - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // val + "00" // dst_offset 101 + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "02" // val "01" // dst_offset 101 + to_hex(OpCode::CALLDATACOPY) + // opcode CALLDATACOPY (no in tag) @@ -420,20 +419,20 @@ TEST_F(AvmExecutionTests, jumpAndCalldatacopy) "0005" // jmp_dest (FDIV located at 3) + to_hex(OpCode::SUB_8) + // opcode SUB "00" // Indirect flag - "06" // FF - "0B" // addr 11 - "0A" // addr 10 - "01" // addr c 1 (If executed would be 156 - 13 = 143) - + to_hex(OpCode::FDIV_8) + // opcode FDIV - "00" // Indirect flag - "06" // tag - "0B" // addr 11 - "0A" // addr 10 - "01" // addr c 1 (156 / 13 = 12) - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "00000000" // ret offset 0 - "00000000" // ret size 0 + + to_hex(AvmMemoryTag::FF) + + "0B" // addr 11 + "0A" // addr 10 + "01" // addr c 1 (If executed would be 156 - 13 = 143) + + to_hex(OpCode::FDIV_8) + // opcode FDIV + "00" // Indirect flag + + to_hex(AvmMemoryTag::FF) + + "0B" // addr 11 + "0A" // addr 10 + "01" // addr c 1 (156 / 13 = 12) + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000000" // ret offset 0 + "00000000" // ret size 0 ; auto bytecode = hex_to_bytes(bytecode_hex); @@ -492,14 +491,14 @@ TEST_F(AvmExecutionTests, jumpAndCalldatacopy) // We test this bytecode with two calldatacopy values: 9873123 and 0. TEST_F(AvmExecutionTests, jumpiAndCalldatacopy) { - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 - "00" // val - "00" // dst_offset - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // val + "00" // dst_offset + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "01" // val "01" // dst_offset + to_hex(OpCode::CALLDATACOPY) + // opcode CALLDATACOPY (no in tag) @@ -509,29 +508,29 @@ TEST_F(AvmExecutionTests, jumpiAndCalldatacopy) "0000000A" // dst_offset 10 + to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - "02" // U16 - "14" // val 20 - "65" // dst_offset 101 - + to_hex(OpCode::JUMPI_16) + // opcode JUMPI - "00" // Indirect flag - "0006" // jmp_dest (MUL located at 6) - "000A" // cond_offset 10 - + to_hex(OpCode::ADD_16) + // opcode ADD - "00" // Indirect flag - "02" // U16 - "0065" // addr 101 - "0065" // addr 101 - "0065" // output addr 101 - + to_hex(OpCode::MUL_8) + // opcode MUL - "00" // Indirect flag - "02" // U16 - "65" // addr 101 - "65" // addr 101 - "66" // output of MUL addr 102 - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "00000000" // ret offset 0 - "00000000" // ret size 0 + + to_hex(AvmMemoryTag::U16) + + "14" // val 20 + "65" // dst_offset 101 + + to_hex(OpCode::JUMPI_16) + // opcode JUMPI + "00" // Indirect flag + "0006" // jmp_dest (MUL located at 6) + "000A" // cond_offset 10 + + to_hex(OpCode::ADD_16) + // opcode ADD + "00" // Indirect flag + + to_hex(AvmMemoryTag::U16) + + "0065" // addr 101 + "0065" // addr 101 + "0065" // output addr 101 + + to_hex(OpCode::MUL_8) + // opcode MUL + "00" // Indirect flag + + to_hex(AvmMemoryTag::U16) + + "65" // addr 101 + "65" // addr 101 + "66" // output of MUL addr 102 + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000000" // ret offset 0 + "00000000" // ret size 0 ; auto bytecode = hex_to_bytes(bytecode_hex); @@ -573,9 +572,9 @@ TEST_F(AvmExecutionTests, jumpiAndCalldatacopy) // Positive test with MOV. TEST_F(AvmExecutionTests, movOpcode) { - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "01" // U8 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U8) + "13" // val 19 "AB" // dst_offset 171 + to_hex(OpCode::MOV_8) + // opcode MOV @@ -621,19 +620,19 @@ TEST_F(AvmExecutionTests, movOpcode) // Positive test with CMOV. TEST_F(AvmExecutionTests, cmovOpcode) { - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "01" // U8 - "03" // val 3 - "10" // a_offset 16 - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "02" // U16 - "04" // val 4 - "11" // b_offset 17 - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U8) + + "03" // val 3 + "10" // a_offset 16 + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U16) + + "04" // val 4 + "11" // b_offset 17 + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "05" // val 5 "20" // cond_offset 32 + to_hex(OpCode::CMOV) + // opcode CMOV @@ -677,19 +676,19 @@ TEST_F(AvmExecutionTests, cmovOpcode) // Positive test with indirect MOV. TEST_F(AvmExecutionTests, indMovOpcode) { - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 - "0A" // val 10 - "01" // dst_offset 1 - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 - "0B" // val 11 - "02" // dst_offset 2 - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "01" // U8 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "0A" // val 10 + "01" // dst_offset 1 + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "0B" // val 11 + "02" // dst_offset 2 + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U8) + "FF" // val 255 "0A" // dst_offset 10 + to_hex(OpCode::MOV_8) + // opcode MOV @@ -725,14 +724,14 @@ TEST_F(AvmExecutionTests, indMovOpcode) // Positive test for SET and CAST opcodes TEST_F(AvmExecutionTests, setAndCastOpcodes) { - std::string bytecode_hex = to_hex(OpCode::SET_16) + // opcode SET - "00" // Indirect flag - "02" // U16 + std::string bytecode_hex = to_hex(OpCode::SET_16) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U16) + "B813" // val 47123 "0011" // dst_offset 17 + to_hex(OpCode::CAST_8) + // opcode CAST "00" // Indirect flag - "01" // U8 + + to_hex(AvmMemoryTag::U8) + "11" // addr a "12" // addr casted a + to_hex(OpCode::RETURN) + // opcode RETURN @@ -766,14 +765,14 @@ TEST_F(AvmExecutionTests, setAndCastOpcodes) // Positive test with TO_RADIX_LE. TEST_F(AvmExecutionTests, toRadixLeOpcode) { - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 - "00" // val - "00" // dst_offset - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // val + "00" // dst_offset + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "01" // val "01" // dst_offset + to_hex(OpCode::CALLDATACOPY) + // opcode CALLDATACOPY @@ -783,24 +782,96 @@ TEST_F(AvmExecutionTests, toRadixLeOpcode) "00000001" // dst_offset + to_hex(OpCode::SET_8) + // opcode SET for indirect src "00" // Indirect flag - "03" // U32 - "01" // value 1 (i.e. where the src from calldata is copied) - "11" // dst_offset 17 - + to_hex(OpCode::SET_8) + // opcode SET for indirect dst + + to_hex(AvmMemoryTag::U32) + + "01" // value 1 (i.e. where the src from calldata is copied) + "11" // dst_offset 17 + + to_hex(OpCode::SET_8) + // opcode SET for indirect dst + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "05" // value 5 (i.e. where the dst will be written to) + "15" // dst_offset 21 + + to_hex(OpCode::SET_8) + // opcode SET for indirect dst + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "02" // value 2 (i.e. radix 2 - perform bitwise decomposition) + "80" // radix_offset 80 + + to_hex(OpCode::TORADIXLE) + // opcode TO_RADIX_LE + "03" // Indirect flag + "00000011" // src_offset 17 (indirect) + "00000015" // dst_offset 21 (indirect) + "00000080" // radix_offset 80 (direct) + "00000100" // limbs: 256 + "00" // output_bits: false + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000005" // ret offset 0 + "00000100"; // ret size 0 + + auto bytecode = hex_to_bytes(bytecode_hex); + auto instructions = Deserialization::parse(bytecode); + + // Assign a vector that we will mutate internally in gen_trace to store the return values; + std::vector returndata; + auto trace = + Execution::gen_trace(instructions, returndata, std::vector{ FF::modulus - FF(1) }, public_inputs_vec); + + // Find the first row enabling the TORADIXLE selector + // Expected output is bitwise decomposition of MODULUS - 1..could hardcode the result but it's a bit long + std::vector expected_output; + // Extract each bit. + for (size_t i = 0; i < 256; i++) { + FF expected_limb = (FF::modulus - 1) >> i & 1; + expected_output.emplace_back(expected_limb); + } + EXPECT_EQ(returndata, expected_output); + + validate_trace(std::move(trace), public_inputs, { FF::modulus - FF(1) }, returndata); +} + +// Positive test with TO_RADIX_LE. +TEST_F(AvmExecutionTests, toRadixLeOpcodeBitsMode) +{ + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // val + "00" // dst_offset + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "01" // val + "01" // dst_offset + + to_hex(OpCode::CALLDATACOPY) + // opcode CALLDATACOPY "00" // Indirect flag - "03" // U32 - "05" // value 5 (i.e. where the dst will be written to) - "15" // dst_offset 21 - + to_hex(OpCode::TORADIXLE) + // opcode TO_RADIX_LE - "03" // Indirect flag - "00000011" // src_offset 17 (indirect) - "00000015" // dst_offset 21 (indirect) - "00000002" // radix: 2 (i.e. perform bitwise decomposition) - "00000100" // limbs: 256 - + to_hex(OpCode::RETURN) + // opcode RETURN + "00000000" // cd_offset + "00000001" // copy_size + "00000001" // dst_offset + + to_hex(OpCode::SET_8) + // opcode SET for indirect src "00" // Indirect flag - "00000005" // ret offset 0 - "00000100"; // ret size 0 + + to_hex(AvmMemoryTag::U32) + + "01" // value 1 (i.e. where the src from calldata is copied) + "11" // dst_offset 17 + + to_hex(OpCode::SET_8) + // opcode SET for indirect dst + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "05" // value 5 (i.e. where the dst will be written to) + "15" // dst_offset 21 + + to_hex(OpCode::SET_8) + // opcode SET for indirect dst + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "02" // value 2 (i.e. radix 2 - perform bitwise decomposition) + "80" // radix_offset 80 + + to_hex(OpCode::TORADIXLE) + // opcode TO_RADIX_LE + "03" // Indirect flag + "00000011" // src_offset 17 (indirect) + "00000015" // dst_offset 21 (indirect) + "00000080" // radix_offset 80 (direct) + "00000100" // limbs: 256 + "01" // output_bits: true + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000005" // ret offset 0 + "00000100"; // ret size 0 auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse(bytecode); @@ -831,38 +902,36 @@ TEST_F(AvmExecutionTests, sha256CompressionOpcode) // Test vectors taken from noir black_box_solver // State = Uint32Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), for (uint8_t i = 1; i <= 8; i++) { - bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" + // U32 - to_hex(i) + // val i - to_hex(i); // val i + bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + to_hex(i) + // val i + to_hex(i); // val i } // Set operations for sha256 input // Test vectors taken from noir black_box_solver // Input = Uint32Array.from([1, 2, 3, 4, 5, 6, 7, 8]), for (uint8_t i = 1; i <= 16; i++) { - bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" + // U32 - to_hex(i) + // val i - to_hex(i + 8); // val i + bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + to_hex(i) + // val i + to_hex(i + 8); // val i } std::string bytecode_hex = bytecode_preamble // Initial SET operations to store state and input + to_hex(OpCode::SET_16) + // opcode SET for indirect dst (output) "00" // Indirect flag - "03" // U32 - "0100" // value 256 (i.e. where the dst will be written to) - "0024" // dst_offset 36 - + to_hex(OpCode::SET_8) + // opcode SET for indirect state - "00" // Indirect flag - "03" // U32 - "01" // value 1 (i.e. where the state will be read from) - "22" // dst_offset 34 - + to_hex(OpCode::SET_8) + // opcode SET for indirect input - "00" // Indirect flag - "03" // U32 - "09" // value 9 (i.e. where the input will be read from) - "23" // dst_offset 35 + + to_hex(AvmMemoryTag::U32) + + "0100" // value 256 (i.e. where the dst will be written to) + "0024" // dst_offset 36 + + to_hex(OpCode::SET_8) + // opcode SET for indirect state + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "01" // value 1 (i.e. where the state will be read from) + "22" // dst_offset 34 + + to_hex(OpCode::SET_8) + // opcode SET for indirect input + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "09" // value 9 (i.e. where the input will be read from) + "23" // dst_offset 35 + to_hex(OpCode::SHA256COMPRESSION) + // opcode SHA256COMPRESSION "07" // Indirect flag (first 3 operands indirect) "00000024" // output offset (indirect 36) @@ -906,34 +975,34 @@ TEST_F(AvmExecutionTests, sha256Opcode) FF(0xde), FF(0x5d), FF(0xae), FF(0x22), FF(0x23), FF(0xb0), FF(0x03), FF(0x61), FF(0xa3), FF(0x96), FF(0x17), FF(0x7a), FF(0x9c), FF(0xb4), FF(0x10), FF(0xff), FF(0x61), FF(0xf2), FF(0x00), FF(0x15), FF(0xad), }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // Initial SET operations to store state and input - "00" // Indirect Flag - "01" // U8 - "61" // val 97 - "01" // dst_offset 1 - + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) - "00" // Indirect flag - "01" // U8 - "62" // value 98 (i.e. where the src will be read from)A - "02" // input_offset 2 - + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) - "00" // Indirect flag - "01" // U32 - "63" // value 99 (i.e. where the src will be read from) - "03" // input_offset 36 - + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) - "00" // Indirect flag - "03" // U32 - "01" // value 1 (i.e. where the src will be read from) - "24" // input_offset 36 - + to_hex(OpCode::SET_8) + // - "00" // Indirect flag - "03" // U8 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // Initial SET operations to store state and input + "00" // Indirect Flag + + to_hex(AvmMemoryTag::U8) + + "61" // val 97 + "01" // dst_offset 1 + + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) + "00" // Indirect flag + + to_hex(AvmMemoryTag::U8) + + "62" // value 98 (i.e. where the src will be read from)A + "02" // input_offset 2 + + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "63" // value 99 (i.e. where the src will be read from) + "03" // input_offset 36 + + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "01" // value 1 (i.e. where the src will be read from) + "24" // input_offset 36 + + to_hex(OpCode::SET_8) + // + "00" // Indirect flag + + to_hex(AvmMemoryTag::U8) + "03" // value 3 (i.e. where the length parameter is stored) "25" // input_offset 37 + to_hex(OpCode::SET_16) + // opcode SET for indirect dst (output) "00" // Indirect flag - "03" // U32 + + to_hex(AvmMemoryTag::U32) + "0100" // value 256 (i.e. where the ouput will be written to) "0023" // dst_offset 35 + to_hex(OpCode::SHA256) + // opcode SHA256 @@ -968,14 +1037,14 @@ TEST_F(AvmExecutionTests, poseidon2PermutationOpCode) FF(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")), FF(std::string("9a807b615c4d3e2fa0b1c2d3e4f56789fedcba9876543210abcdef0123456789")) }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 - "00" // val - "00" // dst_offset - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // val + "00" // dst_offset + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "04" // val "01" // dst_offset + to_hex(OpCode::CALLDATACOPY) + // opcode CALL DATA COPY @@ -985,22 +1054,22 @@ TEST_F(AvmExecutionTests, poseidon2PermutationOpCode) "00000001" // dst_offset 1 + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) "00" // Indirect flag - "03" // U32 - "01" // value 1 (i.e. where the src will be read from) - "24" // dst_offset 36 - + to_hex(OpCode::SET_8) + // opcode SET for indirect dst (output) - "00" // Indirect flag - "03" // U32 - "09" // value 9 (i.e. where the ouput will be written to) - "23" // dst_offset 35 - + to_hex(OpCode::POSEIDON2) + // opcode POSEIDON2 - "03" // Indirect flag (first 2 operands indirect) - "00000024" // input offset (indirect 36) - "00000023" // output offset (indirect 35) - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "00000009" // ret offset 256 - "00000004"; // ret size 8 + + to_hex(AvmMemoryTag::U32) + + "01" // value 1 (i.e. where the src will be read from) + "24" // dst_offset 36 + + to_hex(OpCode::SET_8) + // opcode SET for indirect dst (output) + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "09" // value 9 (i.e. where the ouput will be written to) + "23" // dst_offset 35 + + to_hex(OpCode::POSEIDON2) + // opcode POSEIDON2 + "03" // Indirect flag (first 2 operands indirect) + "00000024" // input offset (indirect 36) + "00000023" // output offset (indirect 35) + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000009" // ret offset 256 + "00000004"; // ret size 8 auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse(bytecode); @@ -1047,28 +1116,27 @@ TEST_F(AvmExecutionTests, keccakf1600OpCode) std::string bytecode_preamble; // Set operations for keccak state for (uint8_t i = 0; i < 25; i++) { - bytecode_preamble += to_hex(OpCode::SET_64) + // opcode SET - "00" // Indirect flag - "04" + // U64 - to_hex(state[i]) + // val i - to_hex(i + 1); // dst offset + bytecode_preamble += to_hex(OpCode::SET_64) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U64) + to_hex(state[i]) + // val i + to_hex(i + 1); // dst offset } // We use calldatacopy twice because we need to set up 4 inputs - std::string bytecode_hex = bytecode_preamble + // Initial SET operations to store state and input - to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) - "00" // Indirect flag - "03" // U32 - "01" // value 1 (i.e. where the src will be read from) - "24" // input_offset 36 - + to_hex(OpCode::SET_8) + // - "00" // Indirect flag - "03" // U32 - "19" // value 25 (i.e. where the length parameter is stored) - "25" // input_offset 37 - + to_hex(OpCode::SET_16) + // opcode SET for indirect dst (output) - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = bytecode_preamble + // Initial SET operations to store state and input + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "01" // value 1 (i.e. where the src will be read from) + "24" // input_offset 36 + + to_hex(OpCode::SET_8) + // + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "19" // value 25 (i.e. where the length parameter is stored) + "25" // input_offset 37 + + to_hex(OpCode::SET_16) + // opcode SET for indirect dst (output) + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "0100" // value 256 (i.e. where the ouput will be written to) "0023" // dst_offset 35 + to_hex(OpCode::KECCAKF1600) + // opcode KECCAKF1600 @@ -1108,24 +1176,24 @@ TEST_F(AvmExecutionTests, keccakOpCode) FF(0x33), FF(0x65), FF(0x19), FF(0x37), FF(0xe8), FF(0x05), FF(0x27), FF(0x0c), FF(0xa3), FF(0xf3), FF(0xaf), FF(0x1c), FF(0x0d), FF(0xd2), FF(0x46), FF(0x2d), FF(0xca), FF(0x4b), FF(0x3b), FF(0x1a), FF(0xbf) }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // Initial SET operations to store state and input - "00" // Indirect Flag - "01" // U8 - "BD" // val 189 - "01" // dst_offset 1 - + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) - "00" // Indirect flag - "03" // U32 - "01" // value 1 (i.e. where the src will be read from) - "24" // input_offset 36 - + to_hex(OpCode::SET_8) + // - "00" // Indirect flag - "03" // U8 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // Initial SET operations to store state and input + "00" // Indirect Flag + + to_hex(AvmMemoryTag::U8) + + "BD" // val 189 + "01" // dst_offset 1 + + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "01" // value 1 (i.e. where the src will be read from) + "24" // input_offset 36 + + to_hex(OpCode::SET_8) + // + "00" // Indirect flag + + to_hex(AvmMemoryTag::U8) + "01" // value 1 (i.e. where the length parameter is stored) "25" // input_offset 37 + to_hex(OpCode::SET_16) + // opcode SET for indirect dst (output) "00" // Indirect flag - "03" // U32 + + to_hex(AvmMemoryTag::U32) + "0100" // value 256 (i.e. where the ouput will be written to) "0023" // dst_offset 35 + to_hex(OpCode::KECCAK) + // opcode KECCAK @@ -1159,14 +1227,14 @@ TEST_F(AvmExecutionTests, pedersenHashOpCode) // output = 0x1c446df60816b897cda124524e6b03f36df0cec333fad87617aab70d7861daa6 // hash_index = 5; FF expected_output = FF("0x1c446df60816b897cda124524e6b03f36df0cec333fad87617aab70d7861daa6"); - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 - "00" // val - "00" // dst_offset - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // val + "00" // dst_offset + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "02" // val "01" // dst_offset + to_hex(OpCode::CALLDATACOPY) + // Calldatacopy @@ -1176,29 +1244,29 @@ TEST_F(AvmExecutionTests, pedersenHashOpCode) "00000000" // dst_offset + to_hex(OpCode::SET_8) + // opcode SET for direct hash index offset "00" // Indirect flag - "03" // U32 - "05" // value 5 - "02" // input_offset 2 - + to_hex(OpCode::SET_8) + // opcode SET for indirect src - "00" // Indirect flag - "03" // U32 - "00" // value 0 (i.e. where the src will be read from) - "04" // dst_offset 4 - + to_hex(OpCode::SET_8) + // opcode SET for direct src_length - "00" // Indirect flag - "03" // U32 - "02" // value 2 - "05" // dst_offset - + to_hex(OpCode::PEDERSEN) + // opcode PEDERSEN - "04" // Indirect flag (3rd operand indirect) - "00000002" // hash_index offset (direct) - "00000003" // dest offset (direct) - "00000004" // input offset (indirect) - "00000005" // length offset (direct) - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "00000003" // ret offset 3 - "00000001"; // ret size 1 + + to_hex(AvmMemoryTag::U32) + + "05" // value 5 + "02" // input_offset 2 + + to_hex(OpCode::SET_8) + // opcode SET for indirect src + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // value 0 (i.e. where the src will be read from) + "04" // dst_offset 4 + + to_hex(OpCode::SET_8) + // opcode SET for direct src_length + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "02" // value 2 + "05" // dst_offset + + to_hex(OpCode::PEDERSEN) + // opcode PEDERSEN + "04" // Indirect flag (3rd operand indirect) + "00000002" // hash_index offset (direct) + "00000003" // dest offset (direct) + "00000004" // input offset (indirect) + "00000005" // length offset (direct) + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000003" // ret offset 3 + "00000001"; // ret size 1 auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse(bytecode); @@ -1223,14 +1291,14 @@ TEST_F(AvmExecutionTests, embeddedCurveAddOpCode) auto b_is_inf = b.is_point_at_infinity(); grumpkin::g1::affine_element res = a + b; auto expected_output = std::vector{ res.x, res.y, res.is_point_at_infinity() }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 - "00" // val - "00" // dst_offset - + to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // val + "00" // dst_offset + + to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "06" // val "01" // dst_offset + to_hex(OpCode::CALLDATACOPY) + // Calldatacopy @@ -1240,32 +1308,32 @@ TEST_F(AvmExecutionTests, embeddedCurveAddOpCode) "00000000" // dst_offset + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 "00" // Indirect flag - "01" // U8 tag field - "02" // a_is_inf - "02" // a_is_inf - + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 - "00" // Indirect flag - "01" // U8 tag field - "05" // b_is_inf - "05" // b_is_inf - + to_hex(OpCode::SET_8) + // opcode SET for direct src_length - "00" // Indirect flag - "03" // U32 - "07" // value - "06" // dst_offset - + to_hex(OpCode::ECADD) + // opcode ECADD - "40" // Indirect flag (sixth operand indirect) - "00000000" // hash_index offset (direct) - "00000001" // dest offset (direct) - "00000002" // input offset (indirect) - "00000003" // length offset (direct) - "00000004" // length offset (direct) - "00000005" // length offset (direct) - "00000006" // length offset (direct) - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "00000007" // ret offset 3 - "00000003"; // ret size 1 + + to_hex(AvmMemoryTag::U8) + + "02" // a_is_inf + "02" // a_is_inf + + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 + "00" // Indirect flag + + to_hex(AvmMemoryTag::U8) + + "05" // b_is_inf + "05" // b_is_inf + + to_hex(OpCode::SET_8) + // opcode SET for direct src_length + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "07" // value + "06" // dst_offset + + to_hex(OpCode::ECADD) + // opcode ECADD + "40" // Indirect flag (sixth operand indirect) + "00000000" // hash_index offset (direct) + "00000001" // dest offset (direct) + "00000002" // input offset (indirect) + "00000003" // length offset (direct) + "00000004" // length offset (direct) + "00000005" // length offset (direct) + "00000006" // length offset (direct) + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "00000007" // ret offset 3 + "00000003"; // ret size 1 auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse(bytecode); @@ -1299,15 +1367,15 @@ TEST_F(AvmExecutionTests, msmOpCode) // Send all the input as Fields and cast them to U8 later std::vector calldata = { FF(a.x), FF(a.y), a_is_inf, FF(b.x), FF(b.y), b_is_inf, scalar_a_lo, scalar_a_hi, scalar_b_lo, scalar_b_hi }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "00" // val "00" // dst_offset + to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - "03" // U32 - "0A" // val + + to_hex(AvmMemoryTag::U32) + + "0A" // val "01" + to_hex(OpCode::CALLDATACOPY) + // Calldatacopy "00" // Indirect flag @@ -1316,44 +1384,44 @@ TEST_F(AvmExecutionTests, msmOpCode) "00000000" // dst_offset 0 + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 "00" // Indirect flag - "01" // U8 tag field - "02" // a_is_inf - "02" // - + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 - "00" // Indirect flag - "01" // U8 tag field - "05" // b_is_inf - "05" // - + to_hex(OpCode::SET_8) + // opcode SET for length - "00" // Indirect flag - "03" // U32 - "06" // Length of point elements (6) - "0b" // dst offset (11) - + to_hex(OpCode::SET_8) + // SET Indirects - "00" // Indirect flag - "03" // U32 - "00" // points offset - "0d" // dst offset + - + to_hex(OpCode::SET_8) + // SET Indirects - "00" // Indirect flag - "03" // U32 - "06" // scalars offset - "0e" + // dst offset - to_hex(OpCode::SET_8) + // SET Indirects - "00" // Indirect flag - "03" // U32 - "0c" // output offset - "0f" + // dst offset - to_hex(OpCode::MSM) + // opcode MSM - "07" // Indirect flag (first 3 indirect) - "0000000d" // points offset - "0000000e" // scalars offset - "0000000f" // output offset - "0000000b" // length offset - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "0000000c" // ret offset 12 (this overwrites) - "00000003"; // ret size 3 + + to_hex(AvmMemoryTag::U8) + + "02" // a_is_inf + "02" // + + to_hex(OpCode::CAST_8) + // opcode CAST inf to U8 + "00" // Indirect flag + + to_hex(AvmMemoryTag::U8) + + "05" // b_is_inf + "05" // + + to_hex(OpCode::SET_8) + // opcode SET for length + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "06" // Length of point elements (6) + "0b" // dst offset (11) + + to_hex(OpCode::SET_8) + // SET Indirects + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // points offset + "0d" // dst offset + + + to_hex(OpCode::SET_8) + // SET Indirects + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "06" // scalars offset + "0e" + // dst offset + to_hex(OpCode::SET_8) + // SET Indirects + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "0c" // output offset + "0f" + // dst offset + to_hex(OpCode::MSM) + // opcode MSM + "07" // Indirect flag (first 3 indirect) + "0000000d" // points offset + "0000000e" // scalars offset + "0000000f" // output offset + "0000000b" // length offset + + to_hex(OpCode::RETURN) + // opcode RETURN + "00" // Indirect flag + "0000000c" // ret offset 12 (this overwrites) + "00000003"; // ret size 3 auto bytecode = hex_to_bytes(bytecode_hex); auto instructions = Deserialization::parse(bytecode); @@ -1382,39 +1450,39 @@ TEST_F(AvmExecutionTests, pedersenCommitmentOpcode) std::vector expected_output = { expected_result.x, expected_result.y, expected_result.is_point_at_infinity() }; // Send all the input as Fields and cast them to U8 later std::vector calldata = { scalar_a, scalar_b }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "00" // val "00" // dst_offset + to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - "03" // U32 - "02" // val + + to_hex(AvmMemoryTag::U32) + + "02" // val "01" + - to_hex(OpCode::CALLDATACOPY) + // Calldatacopy - "00" // Indirect flag - "00000000" // cd_offset 0 - "00000001" // copy_size (2 elements) - "00000000" // dst_offset 0 - + to_hex(OpCode::SET_8) + // opcode SET for indirect input - "00" // Indirect flag - "03" // U32 - "00" // Input stored at memory 0 - "0b" // dst offset (11) - + to_hex(OpCode::SET_8) + // opcode SET for indirect output - "00" // Indirect flag - "03" // U32 - "20" // output offset - "0d" // dst offset - + to_hex(OpCode::SET_8) + // opcode SET for input length - "00" // Indirect flag - "03" // U32 - "02" // scalars length (2) - "02" + // dst offset (2) - to_hex(OpCode::SET_8) + // opcode SET for ctx index - "00" // Indirect flag - "03" // U32 + to_hex(OpCode::CALLDATACOPY) + // Calldatacopy + "00" // Indirect flag + "00000000" // cd_offset 0 + "00000001" // copy_size (2 elements) + "00000000" // dst_offset 0 + + to_hex(OpCode::SET_8) + // opcode SET for indirect input + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "00" // Input stored at memory 0 + "0b" // dst offset (11) + + to_hex(OpCode::SET_8) + // opcode SET for indirect output + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "20" // output offset + "0d" // dst offset + + to_hex(OpCode::SET_8) + // opcode SET for input length + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + + "02" // scalars length (2) + "02" + // dst offset (2) + to_hex(OpCode::SET_8) + // opcode SET for ctx index + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "00" // ctx index (0) "0f" + // dst offset to_hex(OpCode::PEDERSENCOMMITMENT) + // opcode MSM @@ -1651,9 +1719,9 @@ TEST_F(AvmExecutionTests, kernelInputOpcodes) // Positive test for L2GASLEFT opcode TEST_F(AvmExecutionTests, l2GasLeft) { - std::string bytecode_hex = to_hex(OpCode::SET_16) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_16) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "0101" // val 257 "0011" // dst_offset 17 + to_hex(OpCode::L2GASLEFT) + // opcode L2GASLEFT @@ -1692,9 +1760,9 @@ TEST_F(AvmExecutionTests, l2GasLeft) // Positive test for DAGASLEFT opcode TEST_F(AvmExecutionTests, daGasLeft) { - std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "0007" // addr a 7 "0009" // addr b 9 "0001" // addr c 1 @@ -1754,13 +1822,13 @@ TEST_F(AvmExecutionTests, kernelOutputEmitOpcodes) // Set values into the first register to emit std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode Set "00" // Indirect flag - "03" // U32 - "01" // value 1 - "01" // dst_offset 1 + + to_hex(AvmMemoryTag::U32) + + "01" // value 1 + "01" // dst_offset 1 // Cast set to field - + to_hex(OpCode::CAST_8) + // opcode CAST - "00" // Indirect flag - "06" // tag field + + to_hex(OpCode::CAST_8) + // opcode CAST + "00" // Indirect flag + + to_hex(AvmMemoryTag::FF) + "01" // dst 1 "01" // dst 1 + to_hex(OpCode::EMITNOTEHASH) + // opcode EMITNOTEHASH @@ -1854,14 +1922,14 @@ TEST_F(AvmExecutionTests, kernelOutputEmitOpcodes) TEST_F(AvmExecutionTests, kernelOutputStorageLoadOpcodeSimple) { // Sload from a value that has not previously been written to will require a hint to process - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "09" // value 9 "01" // dst_offset 1 + to_hex(OpCode::CAST_8) + // opcode CAST (Cast set to field) "00" // Indirect flag - "06" // tag field + + to_hex(AvmMemoryTag::FF) + "01" // dst 1 "01" // dst 1 + to_hex(OpCode::SLOAD) + // opcode SLOAD @@ -1910,15 +1978,15 @@ TEST_F(AvmExecutionTests, kernelOutputStorageStoreOpcodeSimple) { // SSTORE, write 2 elements of calldata to dstOffset 1 and 2. std::vector calldata = { 42, 123, 9, 10 }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "00" // val "00" // dst_offset + to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - "03" // U32 - "04" // val + + to_hex(AvmMemoryTag::U32) + + "04" // val "01" + to_hex(OpCode::CALLDATACOPY) + // opcode CALLDATACOPY "00" // Indirect flag @@ -1968,13 +2036,13 @@ TEST_F(AvmExecutionTests, kernelOutputStorageOpcodes) // Sload from a value that has not previously been written to will require a hint to process std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - "03" // U32 - "09" // value 9 - "01" // dst_offset 1 + + to_hex(AvmMemoryTag::U32) + + "09" // value 9 + "01" // dst_offset 1 // Cast set to field + to_hex(OpCode::CAST_8) + // opcode CAST "00" // Indirect flag - "06" // tag field + + to_hex(AvmMemoryTag::FF) + "01" // dst 1 "01" // dst 1 + to_hex(OpCode::SLOAD) + // opcode SLOAD @@ -2043,13 +2111,13 @@ TEST_F(AvmExecutionTests, kernelOutputHashExistsOpcodes) // hash exists from a value that has not previously been written to will require a hint to process std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - "03" // U32 - "01" // value 1 - "01" // dst_offset 1 + + to_hex(AvmMemoryTag::U32) + + "01" // value 1 + "01" // dst_offset 1 // Cast set to field - + to_hex(OpCode::CAST_8) + // opcode CAST - "00" // Indirect flag - "06" // tag field + + to_hex(OpCode::CAST_8) + // opcode CAST + "00" // Indirect flag + + to_hex(AvmMemoryTag::FF) + "01" // dst 1 "01" // dst 1 + to_hex(OpCode::NOTEHASHEXISTS) + // opcode NOTEHASHEXISTS @@ -2142,49 +2210,49 @@ TEST_F(AvmExecutionTests, opCallOpcodes) // Set up Gas offsets bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET for gas offset indirect "00" // Indirect flag - "03" // U32 - "00" // val 0 (address where gas tuple is located) - "11"; // dst_offset 17 + + to_hex(AvmMemoryTag::U32) + + "00" // val 0 (address where gas tuple is located) + "11"; // dst_offset 17 // Set up contract address offset bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET for args offset indirect "00" // Indirect flag - "03" // U32 - "02" // val 2 (where contract address is located) - "12"; // dst_offset 18 + + to_hex(AvmMemoryTag::U32) + + "02" // val 2 (where contract address is located) + "12"; // dst_offset 18 // Set up args offset bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET for ret offset indirect "00" // Indirect flag - "03" // U32 - "03" // val 3 (the start of the args array) - "13"; // dst_offset 19 + + to_hex(AvmMemoryTag::U32) + + "03" // val 3 (the start of the args array) + "13"; // dst_offset 19 // Set up args size offset bytecode_preamble += to_hex(OpCode::SET_8) + // opcode SET for ret offset indirect "00" // Indirect flag - "03" // U32 - "04" // val 4 (the length of the args array) - "14"; // dst_offset 20 + + to_hex(AvmMemoryTag::U32) + + "04" // val 4 (the length of the args array) + "14"; // dst_offset 20 // Set up the ret offset bytecode_preamble += to_hex(OpCode::SET_16) + // opcode SET for ret offset indirect "00" // Indirect flag - "03" // U32 - "0100" // val 256 (the start of where to write the return data) - "0015"; // dst_offset 21 + + to_hex(AvmMemoryTag::U32) + + "0100" // val 256 (the start of where to write the return data) + "0015"; // dst_offset 21 // Set up the success offset bytecode_preamble += to_hex(OpCode::SET_16) + // opcode SET for ret offset indirect "00" // Indirect flag - "03" // U32 - "0102" // val 258 (write the success flag at ret_offset + ret_size) - "0016"; // dst_offset 22 + + to_hex(AvmMemoryTag::U32) + + "0102" // val 258 (write the success flag at ret_offset + ret_size) + "0016"; // dst_offset 22 - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "00" // val "00" // dst_offset + to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - "03" // U32 - "07" // val + + to_hex(AvmMemoryTag::U32) + + "07" // val "01" + to_hex(OpCode::CALLDATACOPY) + // opcode CALLDATACOPY "00" // Indirect flag @@ -2229,24 +2297,24 @@ TEST_F(AvmExecutionTests, opCallOpcodes) TEST_F(AvmExecutionTests, opGetContractInstanceOpcodes) { - std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET - "00" // Indirect flag - "03" // U32 + std::string bytecode_hex = to_hex(OpCode::SET_8) + // opcode SET + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "00" // val "00" // dst_offset + to_hex(OpCode::SET_8) + // opcode SET "00" // Indirect flag - "03" // U32 - "01" // val + + to_hex(AvmMemoryTag::U32) + + "01" // val "01" + - to_hex(OpCode::CALLDATACOPY) + // opcode CALLDATACOPY for addr - "00" // Indirect flag - "00000000" // cd_offset - "00000001" // copy_size - "00000001" // dst_offset, (i.e. where we store the addr) - + to_hex(OpCode::SET_8) + // opcode SET for the indirect dst offset - "00" // Indirect flag - "03" // U32 + to_hex(OpCode::CALLDATACOPY) + // opcode CALLDATACOPY for addr + "00" // Indirect flag + "00000000" // cd_offset + "00000001" // copy_size + "00000001" // dst_offset, (i.e. where we store the addr) + + to_hex(OpCode::SET_8) + // opcode SET for the indirect dst offset + "00" // Indirect flag + + to_hex(AvmMemoryTag::U32) + "03" // val i "02" + // dst_offset 2 to_hex(OpCode::GETCONTRACTINSTANCE) + // opcode CALL @@ -2280,13 +2348,13 @@ TEST_F(AvmExecutionTests, invalidOpcode) { std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD "00" // Indirect flag - "02" // U16 - "0007" // addr a 7 - "0009" // addr b 9 - "0001" // addr c 1 - "AB" // Invalid opcode byte - "00000000" // ret offset 0 - "00000000"; // ret size 0 + + to_hex(AvmMemoryTag::U16) + + "0007" // addr a 7 + "0009" // addr b 9 + "0001" // addr c 1 + "AB" // Invalid opcode byte + "00000000" // ret offset 0 + "00000000"; // ret size 0 auto bytecode = hex_to_bytes(bytecode_hex); EXPECT_THROW_WITH_MESSAGE(Deserialization::parse(bytecode), "Invalid opcode"); @@ -2315,7 +2383,7 @@ TEST_F(AvmExecutionTests, truncatedInstructionNoTag) { std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD "00" // Indirect flag - "02" // U16 + + to_hex(AvmMemoryTag::U16) + "0007" // addr a 7 "0009" // addr b 9 "0001" // addr c 1 @@ -2328,17 +2396,17 @@ TEST_F(AvmExecutionTests, truncatedInstructionNoTag) // Negative test detecting an incomplete instruction: instruction tag present but an operand is missing TEST_F(AvmExecutionTests, truncatedInstructionNoOperand) { - std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD - "00" // Indirect flag - "02" // U16 + std::string bytecode_hex = to_hex(OpCode::ADD_16) + // opcode ADD + "00" // Indirect flag + + to_hex(AvmMemoryTag::U16) + "0007" // addr a 7 "0009" // addr b 9 "0001" // addr c 1 + to_hex(OpCode::SUB_8) + // opcode SUB "00" // Indirect flag - "04" // U64 - "AB" // addr a - "FF"; // addr b and missing address for c = a-b + + to_hex(AvmMemoryTag::U64) + + "AB" // addr a + "FF"; // addr b and missing address for c = a-b auto bytecode = hex_to_bytes(bytecode_hex); EXPECT_THROW_WITH_MESSAGE(Deserialization::parse(bytecode), "Operand is missing"); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp index a4111e0b6c7..39d812a85d0 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/alu_trace.cpp @@ -25,6 +25,8 @@ std::tuple decompose(uint256_t const& a, uint8_t const b) uint8_t mem_tag_bits(AvmMemoryTag in_tag) { switch (in_tag) { + case AvmMemoryTag::U1: + return 1; case AvmMemoryTag::U8: return 8; case AvmMemoryTag::U16: @@ -48,6 +50,8 @@ uint8_t mem_tag_bits(AvmMemoryTag in_tag) FF cast_to_mem_tag(uint256_t input, AvmMemoryTag in_tag) { switch (in_tag) { + case AvmMemoryTag::U1: + return FF{ static_cast(input & 1) }; case AvmMemoryTag::U8: return FF{ static_cast(input) }; case AvmMemoryTag::U16: @@ -194,8 +198,10 @@ FF AvmAluTraceBuilder::op_mul(FF const& a, FF const& b, AvmMemoryTag in_tag, uin FF c = cast_to_mem_tag(c_u256, in_tag); - uint8_t limb_bits = mem_tag_bits(in_tag) / 2; - uint8_t num_bits = mem_tag_bits(in_tag); + uint8_t bits = mem_tag_bits(in_tag); + // limbs are size 1 for u1 + uint8_t limb_bits = bits == 1 ? 1 : bits / 2; + uint8_t num_bits = bits; // Decompose a auto [alu_a_lo, alu_a_hi] = decompose(a_u256, limb_bits); @@ -247,7 +253,7 @@ FF AvmAluTraceBuilder::op_div(FF const& a, FF const& b, AvmMemoryTag in_tag, uin if (b_u256 == 0) { return 0; } - uint8_t limb_bits = mem_tag_bits(in_tag) / 2; + uint8_t limb_bits = in_tag == AvmMemoryTag::U1 ? 1 : mem_tag_bits(in_tag) / 2; uint8_t num_bits = mem_tag_bits(in_tag); // Decompose a auto [alu_a_lo, alu_a_hi] = decompose(b_u256, limb_bits); @@ -260,7 +266,8 @@ FF AvmAluTraceBuilder::op_div(FF const& a, FF const& b, AvmMemoryTag in_tag, uin // We perform the range checks here if (in_tag != AvmMemoryTag::FF) { - cmp_builder.range_check_builder.assert_range(uint128_t(c_u256), mem_tag_bits(in_tag), EventEmitter::ALU, clk); + cmp_builder.range_check_builder.assert_range( + static_cast(c_u256), mem_tag_bits(in_tag), EventEmitter::ALU, clk); } // Also check the remainder < divisor (i.e. remainder < b) bool is_gt = cmp_builder.constrained_gt(b, rem_u256, clk, EventEmitter::ALU); @@ -653,6 +660,7 @@ void AvmAluTraceBuilder::finalize(std::vector>& main_trace) if (src.tag.has_value()) { dest.alu_ff_tag = FF(src.tag == AvmMemoryTag::FF ? 1 : 0); + dest.alu_u1_tag = FF(src.tag == AvmMemoryTag::U1 ? 1 : 0); dest.alu_u8_tag = FF(src.tag == AvmMemoryTag::U8 ? 1 : 0); dest.alu_u16_tag = FF(src.tag == AvmMemoryTag::U16 ? 1 : 0); dest.alu_u32_tag = FF(src.tag == AvmMemoryTag::U32 ? 1 : 0); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/binary_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/binary_trace.cpp index 1d5aaf6b2d1..3c2729dd029 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/binary_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/binary_trace.cpp @@ -48,7 +48,10 @@ void AvmBinaryTraceBuilder::entry_builder( { // Given the instruction tag, calculate the number of bytes to decompose values into // The number of rows for this entry will be number of bytes + 1 - size_t num_bytes = 1 << (static_cast(instr_tag) - 1); + // Both U1 and U8 are 1 byte. + size_t num_bytes = instr_tag == AvmMemoryTag::U1 + ? 1 + : 1 << (static_cast(instr_tag) - static_cast(AvmMemoryTag::U8)); // Big Endian encoded std::vector a_bytes = bytes_decompose_le(a); @@ -192,17 +195,23 @@ void AvmBinaryTraceBuilder::finalize_lookups(std::vector>& main_t main_trace.at(clk).lookup_byte_operations_counts = count; } - for (uint8_t avm_in_tag = 0; avm_in_tag < 5; avm_in_tag++) { - // The +1 here is because the instruction tags we care about (i.e excl U0 and FF) has the range [1,5] - main_trace.at(avm_in_tag).lookup_byte_lengths_counts = byte_length_counter[avm_in_tag + 1]; + for (uint8_t avm_in_tag = static_cast(AvmMemoryTag::U1); + avm_in_tag <= static_cast(AvmMemoryTag::U128); + avm_in_tag++) { + // lookup indices start at 0 + uint8_t lookup_index = avm_in_tag - static_cast(AvmMemoryTag::U1); + main_trace.at(lookup_index).lookup_byte_lengths_counts = byte_length_counter[avm_in_tag]; } } void AvmBinaryTraceBuilder::finalize_lookups_for_testing(std::vector>& main_trace) { - for (uint8_t avm_in_tag = 0; avm_in_tag < 5; avm_in_tag++) { - // The +1 here is because the instruction tags we care about (i.e excl U0 and FF) has the range [1,5] - main_trace.at(avm_in_tag).lookup_byte_lengths_counts = byte_length_counter[avm_in_tag + 1]; + for (uint8_t avm_in_tag = static_cast(AvmMemoryTag::U1); + avm_in_tag <= static_cast(AvmMemoryTag::U128); + avm_in_tag++) { + // lookup indices start at 0 + uint8_t lookup_index = avm_in_tag - static_cast(AvmMemoryTag::U1); + main_trace.at(lookup_index).lookup_byte_lengths_counts = byte_length_counter[avm_in_tag]; } } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp index 18d7019e229..44b09c31656 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/common.hpp @@ -36,8 +36,18 @@ enum class IntermRegister : uint32_t { IA = 0, IB = 1, IC = 2, ID = 3 }; enum class IndirectRegister : uint32_t { IND_A = 0, IND_B = 1, IND_C = 2, IND_D = 3 }; // Keep following enum in sync with MAX_MEM_TAG below -enum class AvmMemoryTag : uint32_t { U0 = 0, U8 = 1, U16 = 2, U32 = 3, U64 = 4, U128 = 5, FF = 6 }; -static const uint32_t MAX_MEM_TAG = 6; +enum class AvmMemoryTag : uint32_t { + U0 = 0, + U1 = MEM_TAG_U1, + U8 = MEM_TAG_U8, + U16 = MEM_TAG_U16, + U32 = MEM_TAG_U32, + U64 = MEM_TAG_U64, + U128 = MEM_TAG_U128, + FF = MEM_TAG_FF, +}; + +static const uint32_t MAX_MEM_TAG = MEM_TAG_FF; static const size_t NUM_MEM_SPACES = 256; static const uint8_t INTERNAL_CALL_SPACE_ID = 255; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp index d2f83d8baa7..0f18a1ab590 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp @@ -1,6 +1,7 @@ #include "barretenberg/vm/avm/trace/deserialization.hpp" #include "barretenberg/common/throw_or_abort.hpp" #include "barretenberg/vm/avm/trace/common.hpp" +#include "barretenberg/vm/avm/trace/helper.hpp" #include "barretenberg/vm/avm/trace/opcode.hpp" #include @@ -192,7 +193,12 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, // Gadget - Conversion { OpCode::TORADIXLE, - { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, + { OperandType::INDIRECT, + OperandType::UINT32, + OperandType::UINT32, + OperandType::UINT32, + OperandType::UINT32, + OperandType::UINT1 } }, // Gadgets - Unused for now { OpCode::SHA256COMPRESSION, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, @@ -200,8 +206,9 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = }; const std::unordered_map OPERAND_TYPE_SIZE = { - { OperandType::INDIRECT, 1 }, { OperandType::TAG, 1 }, { OperandType::UINT8, 1 }, { OperandType::UINT16, 2 }, - { OperandType::UINT32, 4 }, { OperandType::UINT64, 8 }, { OperandType::UINT128, 16 }, { OperandType::FF, 32 } + { OperandType::INDIRECT, 1 }, { OperandType::TAG, 1 }, { OperandType::UINT1, 1 }, + { OperandType::UINT8, 1 }, { OperandType::UINT16, 2 }, { OperandType::UINT32, 4 }, + { OperandType::UINT64, 8 }, { OperandType::UINT128, 16 }, { OperandType::FF, 32 } }; } // Anonymous namespace @@ -261,6 +268,7 @@ std::vector Deserialization::parse(std::vector const& byte operands.emplace_back(static_cast(tag_u8)); break; } + case OperandType::UINT1: case OperandType::UINT8: operands.emplace_back(bytecode.at(pos)); break; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.hpp index 2a38e836f03..83265fb76ba 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.hpp @@ -11,7 +11,7 @@ namespace bb::avm_trace { // See avm/serialization/instruction_serialization.ts). // Note that the TAG enum value is not supported in TS and is parsed as UINT8. // INDIRECT is parsed as UINT8 where the bits represent the operands that have indirect mem access. -enum class OperandType : uint8_t { INDIRECT, TAG, UINT8, UINT16, UINT32, UINT64, UINT128, FF }; +enum class OperandType : uint8_t { INDIRECT, TAG, UINT1, UINT8, UINT16, UINT32, UINT64, UINT128, FF }; class Deserialization { public: diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp index 9167e8f9886..57b120d08a1 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp @@ -900,7 +900,8 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(1)), std::get(inst.operands.at(2)), std::get(inst.operands.at(3)), - std::get(inst.operands.at(4))); + std::get(inst.operands.at(4)), + std::get(inst.operands.at(5))); break; // Future Gadgets -- pending changes in noir diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_bytes.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_bytes.cpp index a7fa63bb2fc..60428021215 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_bytes.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_bytes.cpp @@ -89,13 +89,18 @@ void FixedBytesTable::finalize_for_testing(std::vector>& main_tra void FixedBytesTable::finalize_byte_length(std::vector>& main_trace) { // Generate ByteLength Lookup table of instruction tags to the number of bytes - // {U8: 1, U16: 2, U32: 4, U64: 8, U128: 16} - for (uint8_t avm_in_tag = 0; avm_in_tag < 5; avm_in_tag++) { - // The +1 here is because the instruction tags we care about (i.e excl U0 and FF) has the range 1,5] - main_trace.at(avm_in_tag).byte_lookup_sel_bin = FF(1); - main_trace.at(avm_in_tag).byte_lookup_table_in_tags = avm_in_tag + 1; - main_trace.at(avm_in_tag).byte_lookup_table_byte_lengths = static_cast(1 << avm_in_tag); + for (uint8_t avm_in_tag = static_cast(AvmMemoryTag::U1); + avm_in_tag <= static_cast(AvmMemoryTag::U128); + avm_in_tag++) { + // lookup indices start at 0 + uint8_t lookup_index = avm_in_tag - static_cast(AvmMemoryTag::U1); + size_t num_bytes = avm_in_tag == static_cast(AvmMemoryTag::U1) + ? 1 + : 1 << (static_cast(avm_in_tag) - static_cast(AvmMemoryTag::U8)); + main_trace.at(lookup_index).byte_lookup_sel_bin = FF(1); + main_trace.at(lookup_index).byte_lookup_table_in_tags = avm_in_tag; + main_trace.at(lookup_index).byte_lookup_table_byte_lengths = num_bytes; } } -} // namespace bb::avm_trace \ No newline at end of file +} // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/conversion_trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/conversion_trace.cpp index b53d04599a8..67a488911b3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/conversion_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/conversion_trace.cpp @@ -19,24 +19,27 @@ void AvmConversionTraceBuilder::reset() * @param a First operand of the TO_RADIX_LE, the value to be converted * @param radix The upper bound for each limbm 0 <= limb < radix * @param num_limbs The number of limbs to the value into. - * @param in_tag Instruction tag defining the number of bits for the LT. + * @param output_bits Should the output be U1s instead of U8s? * @param clk Clock referring to the operation in the main trace. * - * @return std::vector The LE converted values stored as bytes. + * @return std::vector The LE converted values stored as bytes or bits. */ -std::vector AvmConversionTraceBuilder::op_to_radix_le(FF const& a, - uint32_t radix, - uint32_t num_limbs, - uint32_t clk) +std::vector AvmConversionTraceBuilder::op_to_radix_le( + FF const& a, uint32_t radix, uint32_t num_limbs, uint8_t output_bits, uint32_t clk) { - ASSERT(radix <= 256); + ASSERT(radix <= 256); // should never reach here because main trace won't call with bad radix auto a_uint256 = uint256_t(a); auto radix_uint256 = uint256_t(radix); - std::vector bytes; + std::vector bytes_or_bits; for (uint32_t i = 0; i < num_limbs; i++) { - bytes.emplace_back(static_cast(a_uint256 % radix_uint256)); + auto limb = a_uint256 % radix_uint256; + if (output_bits > 0) { + bytes_or_bits.emplace_back(static_cast(limb == 0 ? 0 : 1)); + } else { + bytes_or_bits.emplace_back(static_cast(limb)); + } a_uint256 /= radix_uint256; } @@ -46,10 +49,11 @@ std::vector AvmConversionTraceBuilder::op_to_radix_le(FF const& a, .input = a, .radix = radix, .num_limbs = num_limbs, - .limbs = bytes, + .output_bits = output_bits, + .limbs = bytes_or_bits, }); - return bytes; + return bytes_or_bits; } } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/conversion_trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/conversion_trace.hpp index dd6d16f14c1..cf0ac4723bf 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/conversion_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/conversion_trace.hpp @@ -17,6 +17,7 @@ class AvmConversionTraceBuilder { FF input{}; uint32_t radix = 0; uint32_t num_limbs = 0; + uint8_t output_bits = 0; std::vector limbs; }; @@ -25,7 +26,8 @@ class AvmConversionTraceBuilder { // Finalize the trace std::vector finalize(); - std::vector op_to_radix_le(FF const& a, uint32_t radix, uint32_t num_limbs, uint32_t clk); + std::vector op_to_radix_le( + FF const& a, uint32_t radix, uint32_t num_limbs, uint8_t output_bits, uint32_t clk); private: std::vector conversion_trace; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp index 0380178eda8..588e750a10b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.cpp @@ -103,4 +103,9 @@ std::vector> copy_public_inputs_columns(VmPublicInputs const& pu }; } +std::string to_hex(bb::avm_trace::AvmMemoryTag tag) +{ + return to_hex(static_cast(tag)); +} + } // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp index 7017b2d463e..91979bd4499 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/helper.hpp @@ -21,4 +21,18 @@ std::vector> copy_public_inputs_columns(VmPublicInputs const& pu std::vector const& calldata, std::vector const& returndata); -} // namespace bb::avm_trace \ No newline at end of file +template + requires(std::unsigned_integral) +std::string to_hex(T value) +{ + std::ostringstream stream; + auto num_bytes = static_cast(sizeof(T)); + auto mask = static_cast((static_cast(1) << (num_bytes * 8)) - 1); + auto padding = static_cast(num_bytes * 2); + stream << std::setfill('0') << std::setw(padding) << std::hex << (value & mask); + return stream.str(); +} + +std::string to_hex(bb::avm_trace::AvmMemoryTag tag); + +} // namespace bb::avm_trace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp index 5eece456d0d..b1cdfbb5710 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp @@ -1,6 +1,7 @@ #include "barretenberg/vm/avm/trace/opcode.hpp" #include "barretenberg/common/log.hpp" #include "barretenberg/common/serialize.hpp" +#include "barretenberg/vm/avm/trace/helper.hpp" namespace bb::avm_trace { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp index a60469864fd..1c789c4e9cc 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp @@ -136,18 +136,6 @@ class Bytecode { static bool is_valid(uint8_t byte); }; -// Look into whether we can do something with concepts here to enable OpCode as a parameter -template - requires(std::unsigned_integral) -std::string to_hex(T value) -{ - std::ostringstream stream; - auto num_bytes = static_cast(sizeof(T)); - auto mask = static_cast((static_cast(1) << (num_bytes * 8)) - 1); - auto padding = static_cast(num_bytes * 2); - stream << std::setfill('0') << std::setw(padding) << std::hex << (value & mask); - return stream.str(); -} std::string to_hex(OpCode opcode); std::string to_string(OpCode opcode); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index a7ff0bbb004..7ca1b71853b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -677,8 +677,8 @@ void AvmTraceBuilder::op_eq( auto [resolved_a, resolved_b, resolved_c] = unpack_indirects<3>(indirect, { a_offset, b_offset, dst_offset }); // Reading from memory and loading into ia resp. ib. - auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, AvmMemoryTag::U8, IntermRegister::IA); - auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, in_tag, AvmMemoryTag::U8, IntermRegister::IB); + auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, AvmMemoryTag::U1, IntermRegister::IA); + auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, in_tag, AvmMemoryTag::U1, IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; FF a = read_a.val; @@ -691,7 +691,7 @@ void AvmTraceBuilder::op_eq( // Write into memory value c from intermediate register ic. auto write_c = - constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U8, IntermRegister::IC); + constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U1, IntermRegister::IC); // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::EQ_8); @@ -721,7 +721,7 @@ void AvmTraceBuilder::op_eq( .main_sel_resolve_ind_addr_b = FF(static_cast(read_b.is_indirect)), .main_sel_resolve_ind_addr_c = FF(static_cast(write_c.is_indirect)), .main_tag_err = FF(static_cast(!tag_match)), - .main_w_in_tag = FF(static_cast(AvmMemoryTag::U8)), + .main_w_in_tag = FF(static_cast(AvmMemoryTag::U1)), }); } @@ -732,8 +732,8 @@ void AvmTraceBuilder::op_lt( auto [resolved_a, resolved_b, resolved_c] = unpack_indirects<3>(indirect, { a_offset, b_offset, dst_offset }); - auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, AvmMemoryTag::U8, IntermRegister::IA); - auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, in_tag, AvmMemoryTag::U8, IntermRegister::IB); + auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, AvmMemoryTag::U1, IntermRegister::IA); + auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, in_tag, AvmMemoryTag::U1, IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; FF a = tag_match ? read_a.val : FF(0); @@ -743,7 +743,7 @@ void AvmTraceBuilder::op_lt( // Write into memory value c from intermediate register ic. auto write_c = - constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U8, IntermRegister::IC); + constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U1, IntermRegister::IC); // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::LT_8); @@ -773,7 +773,7 @@ void AvmTraceBuilder::op_lt( .main_sel_resolve_ind_addr_b = FF(static_cast(read_b.is_indirect)), .main_sel_resolve_ind_addr_c = FF(static_cast(write_c.is_indirect)), .main_tag_err = FF(static_cast(!tag_match)), - .main_w_in_tag = FF(static_cast(AvmMemoryTag::U8)), + .main_w_in_tag = FF(static_cast(AvmMemoryTag::U1)), }); } @@ -785,8 +785,8 @@ void AvmTraceBuilder::op_lte( auto [resolved_a, resolved_b, resolved_c] = unpack_indirects<3>(indirect, { a_offset, b_offset, dst_offset }); // Reading from memory and loading into ia resp. ib. - auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, AvmMemoryTag::U8, IntermRegister::IA); - auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, in_tag, AvmMemoryTag::U8, IntermRegister::IB); + auto read_a = constrained_read_from_memory(call_ptr, clk, resolved_a, in_tag, AvmMemoryTag::U1, IntermRegister::IA); + auto read_b = constrained_read_from_memory(call_ptr, clk, resolved_b, in_tag, AvmMemoryTag::U1, IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; FF a = tag_match ? read_a.val : FF(0); @@ -796,7 +796,7 @@ void AvmTraceBuilder::op_lte( // Write into memory value c from intermediate register ic. auto write_c = - constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U8, IntermRegister::IC); + constrained_write_to_memory(call_ptr, clk, resolved_c, c, in_tag, AvmMemoryTag::U1, IntermRegister::IC); // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::LTE_8); @@ -826,7 +826,7 @@ void AvmTraceBuilder::op_lte( .main_sel_resolve_ind_addr_b = FF(static_cast(read_b.is_indirect)), .main_sel_resolve_ind_addr_c = FF(static_cast(write_c.is_indirect)), .main_tag_err = FF(static_cast(!tag_match)), - .main_w_in_tag = FF(static_cast(AvmMemoryTag::U8)), + .main_w_in_tag = FF(static_cast(AvmMemoryTag::U1)), }); } @@ -2070,10 +2070,10 @@ Row AvmTraceBuilder::create_kernel_output_opcode_with_set_metadata_output_from_h auto [resolved_data, resolved_metadata] = unpack_indirects<2>(indirect, { data_offset, metadata_offset }); auto read_a = constrained_read_from_memory( - call_ptr, clk, resolved_data, AvmMemoryTag::FF, AvmMemoryTag::U8, IntermRegister::IA); + call_ptr, clk, resolved_data, AvmMemoryTag::FF, AvmMemoryTag::U1, IntermRegister::IA); auto write_b = constrained_write_to_memory( - call_ptr, clk, resolved_metadata, exists, AvmMemoryTag::FF, AvmMemoryTag::U8, IntermRegister::IB); + call_ptr, clk, resolved_metadata, exists, AvmMemoryTag::FF, AvmMemoryTag::U1, IntermRegister::IB); bool tag_match = read_a.tag_match && write_b.tag_match; return Row{ @@ -2095,7 +2095,7 @@ Row AvmTraceBuilder::create_kernel_output_opcode_with_set_metadata_output_from_h .main_sel_resolve_ind_addr_a = FF(static_cast(read_a.is_indirect)), .main_sel_resolve_ind_addr_b = FF(static_cast(write_b.is_indirect)), .main_tag_err = static_cast(!tag_match), - .main_w_in_tag = static_cast(AvmMemoryTag::U8), + .main_w_in_tag = static_cast(AvmMemoryTag::U1), }; } @@ -2108,10 +2108,10 @@ Row AvmTraceBuilder::create_kernel_output_opcode_for_leaf_index( auto [resolved_data, resolved_metadata] = unpack_indirects<2>(indirect, { data_offset, metadata_offset }); auto read_a = constrained_read_from_memory( - call_ptr, clk, resolved_data, AvmMemoryTag::FF, AvmMemoryTag::U8, IntermRegister::IA); + call_ptr, clk, resolved_data, AvmMemoryTag::FF, AvmMemoryTag::U1, IntermRegister::IA); auto write_b = constrained_write_to_memory( - call_ptr, clk, resolved_metadata, exists, AvmMemoryTag::FF, AvmMemoryTag::U8, IntermRegister::IB); + call_ptr, clk, resolved_metadata, exists, AvmMemoryTag::FF, AvmMemoryTag::U1, IntermRegister::IB); bool tag_match = read_a.tag_match && write_b.tag_match; return Row{ @@ -2133,7 +2133,7 @@ Row AvmTraceBuilder::create_kernel_output_opcode_for_leaf_index( .main_sel_resolve_ind_addr_a = FF(static_cast(read_a.is_indirect)), .main_sel_resolve_ind_addr_b = FF(static_cast(write_b.is_indirect)), .main_tag_err = static_cast(!tag_match), - .main_w_in_tag = static_cast(AvmMemoryTag::U8), + .main_w_in_tag = static_cast(AvmMemoryTag::U1), }; } @@ -2553,7 +2553,7 @@ void AvmTraceBuilder::op_emit_l2_to_l1_msg(uint8_t indirect, uint32_t recipient_ * @param ret_offset An index in memory pointing to where the first value of the external calls return value should * be stored. * @param ret_size The number of values in the return array - * @param success_offset An index in memory pointing to where the success flag (U8) of the external call should be + * @param success_offset An index in memory pointing to where the success flag (U1) of the external call should be * stored * @param function_selector_offset An index in memory pointing to the function selector of the external call (TEMP) */ @@ -2631,7 +2631,7 @@ void AvmTraceBuilder::op_call(uint8_t indirect, // Write the return data to memory write_slice_to_memory(resolved_ret_offset, AvmMemoryTag::FF, hint.return_data); // Write the success flag to memory - write_slice_to_memory(resolved_success_offset, AvmMemoryTag::U8, std::vector{ hint.success }); + write_slice_to_memory(resolved_success_offset, AvmMemoryTag::U1, std::vector{ hint.success }); external_call_counter++; // Adjust the side_effect_counter to the value at the end of the external call. @@ -3218,28 +3218,47 @@ void AvmTraceBuilder::op_pedersen_commit(uint8_t indirect, * @param indirect A byte encoding information about indirect/direct memory access. * @param src_offset An index in memory pointing to the input of the To_Radix_LE conversion. * @param dst_offset An index in memory pointing to the output of the To_Radix_LE conversion. - * @param radix A strict upper bound of each converted limb, i.e., 0 <= limb < radix. + * @param radix_offset An index in memory pointing to the strict upper bound of each converted limb, i.e., 0 <= limb < + * radix. * @param num_limbs The number of limbs to the value into. + * @param output_bits Should the output be U1s instead of U8s? */ -void AvmTraceBuilder::op_to_radix_le( - uint8_t indirect, uint32_t src_offset, uint32_t dst_offset, uint32_t radix, uint32_t num_limbs) +void AvmTraceBuilder::op_to_radix_le(uint8_t indirect, + uint32_t src_offset, + uint32_t dst_offset, + uint32_t radix_offset, + uint32_t num_limbs, + uint8_t output_bits) { auto clk = static_cast(main_trace.size()) + 1; - auto [resolved_src_offset, resolved_dst_offset] = unpack_indirects<2>(indirect, { src_offset, dst_offset }); - auto read_src = constrained_read_from_memory( - call_ptr, clk, resolved_src_offset, AvmMemoryTag::FF, AvmMemoryTag::U8, IntermRegister::IA); + // write output as bits or bytes + AvmMemoryTag w_in_tag = output_bits > 0 ? AvmMemoryTag::U1 // bits mode + : AvmMemoryTag::U8; + + auto [resolved_src_offset, resolved_dst_offset, resolved_radix_offset] = + unpack_indirects<3>(indirect, { src_offset, dst_offset, radix_offset }); - auto read_dst = constrained_read_from_memory( - call_ptr, clk, resolved_dst_offset, AvmMemoryTag::FF, AvmMemoryTag::U8, IntermRegister::IB); + auto read_src = constrained_read_from_memory( + call_ptr, clk, resolved_src_offset, AvmMemoryTag::FF, w_in_tag, IntermRegister::IA); + // TODO:(8603): once instructions can have multiple different tags for reads, constrain the radix's read + // auto read_radix = constrained_read_from_memory( + // call_ptr, clk, resolved_radix_offset, AvmMemoryTag::U32, AvmMemoryTag::U32, IntermRegister::IB); + auto read_radix = unconstrained_read_from_memory(resolved_radix_offset); FF input = read_src.val; + // TODO:(8603): uncomment + // uint32_t radix = static_cast(read_radix.val); + uint32_t radix = static_cast(read_radix); - // In case of a memory tag error, we do not perform the computation. - // Therefore, we do not create any entry in gadget table and return a vector of 0 - std::vector res = read_src.tag_match - ? conversion_trace_builder.op_to_radix_le(input, radix, num_limbs, clk) - : std::vector(num_limbs, 0); + bool radix_out_of_bounds = radix > 256; + bool error = radix_out_of_bounds || !read_src.tag_match; // || !read_radix.tag_match; + + // In case of an error, we do not perform the computation. + // Therefore, we do not create any entry in gadget table and we return a vector of 0. + std::vector res = error + ? std::vector(num_limbs, 0) + : conversion_trace_builder.op_to_radix_le(input, radix, num_limbs, output_bits, clk); // Constrain gas cost gas_trace_builder.constrain_gas(clk, OpCode::TORADIXLE, num_limbs); @@ -3250,25 +3269,30 @@ void AvmTraceBuilder::op_to_radix_le( .main_clk = clk, .main_call_ptr = call_ptr, .main_ia = input, - .main_ib = read_dst.val, - .main_ic = radix, - .main_id = num_limbs, + .main_ib = radix, + .main_ic = num_limbs, + .main_id = output_bits, .main_ind_addr_a = read_src.indirect_address, - .main_ind_addr_b = read_dst.indirect_address, + // TODO:(8603): uncomment + //.main_ind_addr_b = read_radix.indirect_address, .main_internal_return_ptr = FF(internal_return_ptr), .main_mem_addr_a = read_src.direct_address, - .main_mem_addr_b = read_dst.direct_address, + // TODO:(8603): uncomment + //.main_mem_addr_b = read_radix.direct_address, + .main_op_err = error ? FF(1) : FF(0), .main_pc = FF(pc++), .main_r_in_tag = FF(static_cast(AvmMemoryTag::FF)), .main_sel_mem_op_a = FF(1), - .main_sel_mem_op_b = FF(1), + // TODO:(8603): uncomment + //.main_sel_mem_op_b = FF(1), .main_sel_op_radix_le = FF(1), .main_sel_resolve_ind_addr_a = FF(static_cast(read_src.is_indirect)), - .main_sel_resolve_ind_addr_b = FF(static_cast(read_dst.is_indirect)), - .main_w_in_tag = FF(static_cast(AvmMemoryTag::U8)), + // TODO:(8603): uncomment + //.main_sel_resolve_ind_addr_b = FF(static_cast(read_radix.is_indirect)), + .main_w_in_tag = FF(static_cast(w_in_tag)), }); - write_slice_to_memory(resolved_dst_offset, AvmMemoryTag::U8, res); + write_slice_to_memory(resolved_dst_offset, w_in_tag, res); } /************************************************************************************************** @@ -3633,6 +3657,7 @@ std::vector AvmTraceBuilder::finalize(bool range_check_required) dest.conversion_input = src.input; dest.conversion_radix = FF(src.radix); dest.conversion_num_limbs = FF(src.num_limbs); + dest.conversion_output_bits = FF(src.output_bits); } // Add SHA256 Gadget table diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp index 2f43ae5332c..df90fd847e3 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp @@ -178,7 +178,12 @@ class AvmTraceBuilder { uint32_t input_size_offset, uint32_t gen_ctx_offset); // Conversions - void op_to_radix_le(uint8_t indirect, uint32_t src_offset, uint32_t dst_offset, uint32_t radix, uint32_t num_limbs); + void op_to_radix_le(uint8_t indirect, + uint32_t src_offset, + uint32_t dst_offset, + uint32_t radix_offset, + uint32_t num_limbs, + uint8_t output_bits); // Future Gadgets -- pending changes in noir void op_sha256_compression(uint8_t indirect, uint32_t output_offset, uint32_t h_init_offset, uint32_t input_offset); diff --git a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp index 68c5ce65516..356e628ec9f 100644 --- a/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/aztec_constants.hpp @@ -34,6 +34,13 @@ #define PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH 691 #define PUBLIC_CONTEXT_INPUTS_LENGTH 42 #define AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS 66 +#define MEM_TAG_U1 1 +#define MEM_TAG_U8 2 +#define MEM_TAG_U16 3 +#define MEM_TAG_U32 4 +#define MEM_TAG_U64 5 +#define MEM_TAG_U128 6 +#define MEM_TAG_FF 7 #define SENDER_SELECTOR 0 #define ADDRESS_SELECTOR 1 #define STORAGE_ADDRESS_SELECTOR 1 diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 1e1d3606c5c..2efbbcc0701 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -219,6 +219,13 @@ library Constants { uint256 internal constant NESTED_RECURSIVE_PROOF_LENGTH = 439; uint256 internal constant TUBE_PROOF_LENGTH = 439; uint256 internal constant VERIFICATION_KEY_LENGTH_IN_FIELDS = 128; + uint256 internal constant MEM_TAG_U1 = 1; + uint256 internal constant MEM_TAG_U8 = 2; + uint256 internal constant MEM_TAG_U16 = 3; + uint256 internal constant MEM_TAG_U32 = 4; + uint256 internal constant MEM_TAG_U64 = 5; + uint256 internal constant MEM_TAG_U128 = 6; + uint256 internal constant MEM_TAG_FF = 7; uint256 internal constant SENDER_SELECTOR = 0; uint256 internal constant ADDRESS_SELECTOR = 1; uint256 internal constant STORAGE_ADDRESS_SELECTOR = 1; diff --git a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr index 20bbbf81850..15929c22a09 100644 --- a/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr +++ b/noir-projects/noir-protocol-circuits/crates/types/src/constants.nr @@ -363,6 +363,15 @@ global GENERATOR_INDEX__NOTE_NULLIFIER: u32 = 53; global GENERATOR_INDEX__NOTE_HIDING_POINT: u32 = 54; global GENERATOR_INDEX__SYMMETRIC_KEY: u8 = 55; +// AVM memory tags +global MEM_TAG_U1 = 1; +global MEM_TAG_U8 = 2; +global MEM_TAG_U16 = 3; +global MEM_TAG_U32 = 4; +global MEM_TAG_U64 = 5; +global MEM_TAG_U128 = 6; +global MEM_TAG_FF = 7; + global SENDER_SELECTOR: u32 = 0; // "address" actually does not exist in PublicCircuitPublicInputs, // so this is just an alias to "storage address" for now diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index a789a0f0c47..875f076a911 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -462,7 +462,7 @@ namespace Program { struct ToRadix { Program::MemoryAddress input; - uint32_t radix; + Program::MemoryAddress radix; Program::HeapArray output; bool output_bits; diff --git a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs index c3240c6ff1e..7dccfbf677f 100644 --- a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs @@ -130,7 +130,7 @@ pub enum BlackBoxOp { }, ToRadix { input: MemoryAddress, - radix: u32, + radix: MemoryAddress, output: HeapArray, output_bits: bool, }, diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs index 3f1a44b921b..8d1bf3ec2ea 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs @@ -369,9 +369,13 @@ pub(crate) fn evaluate_black_box } BlackBoxOp::ToRadix { input, radix, output, output_bits } => { let input: F = *memory.read(*input).extract_field().expect("ToRadix input not a field"); + let radix = memory + .read(*radix) + .expect_integer_with_bit_size(IntegerBitSize::U32) + .expect("ToRadix opcode's radix bit size does not match expected bit size 32"); let mut input = BigUint::from_bytes_be(&input.to_be_bytes()); - let radix = BigUint::from(*radix); + let radix = BigUint::from_bytes_be(&radix.to_be_bytes()); let mut limbs: Vec> = Vec::with_capacity(output.size); diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs index d92412677ca..c9c31267d7b 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/codegen_intrinsic.rs @@ -78,9 +78,11 @@ impl BrilligContext< let heap_array = self.codegen_brillig_array_to_heap_array(target_array); + let radix_var = self.make_constant_instruction(F::from(radix as u128), 32); + self.black_box_op_instruction(BlackBoxOp::ToRadix { input: source_field.address, - radix, + radix: radix_var.address, output: heap_array, output_bits, }); @@ -91,5 +93,6 @@ impl BrilligContext< self.deallocate_single_addr(items_len); } self.deallocate_register(heap_array.pointer); + self.deallocate_register(radix_var.address); } } diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 18ea558dbba..bcc4e344f04 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -200,6 +200,13 @@ export const NESTED_RECURSIVE_PROOF_LENGTH = 439; export const TUBE_PROOF_LENGTH = 439; export const VERIFICATION_KEY_LENGTH_IN_FIELDS = 128; export const AVM_VERIFICATION_KEY_LENGTH_IN_FIELDS = 66; +export const MEM_TAG_U1 = 1; +export const MEM_TAG_U8 = 2; +export const MEM_TAG_U16 = 3; +export const MEM_TAG_U32 = 4; +export const MEM_TAG_U64 = 5; +export const MEM_TAG_U128 = 6; +export const MEM_TAG_FF = 7; export const SENDER_SELECTOR = 0; export const ADDRESS_SELECTOR = 1; export const STORAGE_ADDRESS_SELECTOR = 1; diff --git a/yarn-project/circuits.js/src/scripts/constants.in.ts b/yarn-project/circuits.js/src/scripts/constants.in.ts index 819f7da934f..6a2a04e95e3 100644 --- a/yarn-project/circuits.js/src/scripts/constants.in.ts +++ b/yarn-project/circuits.js/src/scripts/constants.in.ts @@ -69,6 +69,13 @@ const CPP_CONSTANTS = [ 'END_GLOBAL_VARIABLES', 'START_SIDE_EFFECT_COUNTER', 'TRANSACTION_FEE_SELECTOR', + 'MEM_TAG_U1', + 'MEM_TAG_U8', + 'MEM_TAG_U16', + 'MEM_TAG_U32', + 'MEM_TAG_U64', + 'MEM_TAG_U128', + 'MEM_TAG_FF', ]; const PIL_CONSTANTS = [ @@ -107,6 +114,13 @@ const PIL_CONSTANTS = [ 'END_GLOBAL_VARIABLES', 'START_SIDE_EFFECT_COUNTER', 'TRANSACTION_FEE_SELECTOR', + 'MEM_TAG_U1', + 'MEM_TAG_U8', + 'MEM_TAG_U16', + 'MEM_TAG_U32', + 'MEM_TAG_U64', + 'MEM_TAG_U128', + 'MEM_TAG_FF', ]; /** diff --git a/yarn-project/simulator/src/avm/avm_gas.ts b/yarn-project/simulator/src/avm/avm_gas.ts index 01140e99d32..b0c3c79e3c8 100644 --- a/yarn-project/simulator/src/avm/avm_gas.ts +++ b/yarn-project/simulator/src/avm/avm_gas.ts @@ -265,6 +265,7 @@ export function getGasCostForTypeTag(tag: TypeTag, baseCost: Gas) { /** Returns a multiplier based on the size of the type represented by the tag. Throws on uninitialized or invalid. */ function getGasCostMultiplierFromTypeTag(tag: TypeTag) { switch (tag) { + case TypeTag.UINT1: // same as u8 case TypeTag.UINT8: return 1; case TypeTag.UINT16: diff --git a/yarn-project/simulator/src/avm/avm_memory_types.test.ts b/yarn-project/simulator/src/avm/avm_memory_types.test.ts index f316b2f42a3..c122a05aab6 100644 --- a/yarn-project/simulator/src/avm/avm_memory_types.test.ts +++ b/yarn-project/simulator/src/avm/avm_memory_types.test.ts @@ -2,6 +2,7 @@ import { Field, MeteredTaggedMemory, TaggedMemory, + Uint1, Uint8, Uint16, Uint32, @@ -98,8 +99,105 @@ describe('MeteredTaggedMemory', () => { }); }); -type IntegralClass = typeof Uint8 | typeof Uint16 | typeof Uint32 | typeof Uint64 | typeof Uint128; -describe.each([Uint8, Uint16, Uint32, Uint64, Uint128])('Integral Types', (clsValue: IntegralClass) => { +type IntegralClass = typeof Uint1 | typeof Uint8 | typeof Uint16 | typeof Uint32 | typeof Uint64 | typeof Uint128; + +describe.each([Uint1])('Integral Types (U1 only)', (clsValue: IntegralClass) => { + describe(`${clsValue.name}`, () => { + it(`Should construct a new ${clsValue.name} from a number`, () => { + const x = new clsValue(1); + expect(x.toBigInt()).toStrictEqual(1n); + }); + + it(`Should construct a new ${clsValue.name} from a bigint`, () => { + const x = new clsValue(0n); + expect(x.toBigInt()).toStrictEqual(0n); + }); + + it(`Should build a new ${clsValue.name}`, () => { + const x = new clsValue(0); + const newX = x.build(1n); + expect(newX).toStrictEqual(new clsValue(1n)); + }); + + it(`Should add two ${clsValue.name} correctly`, () => { + const a = new clsValue(0); + const b = new clsValue(1); + const result = a.add(b); + expect(result).toStrictEqual(new clsValue(1n)); + }); + + it(`Should subtract two ${clsValue.name} correctly`, () => { + const a = new clsValue(1); + const b = new clsValue(0); + const result = a.sub(b); + expect(result).toStrictEqual(new clsValue(1n)); + }); + + it(`Should multiply two ${clsValue.name} correctly`, () => { + const a = new clsValue(1); + const b = new clsValue(1); + const result = a.mul(b); + expect(result).toStrictEqual(new clsValue(1n)); + }); + + it(`Should divide two ${clsValue.name} correctly`, () => { + const a = new clsValue(1); + const b = new clsValue(1); + const result = a.div(b); + expect(result).toStrictEqual(new clsValue(1n)); + }); + + it(`Should shift right ${clsValue.name} correctly`, () => { + const uintA = new clsValue(1); + const result = uintA.shr(new clsValue(1n)); + expect(result).toEqual(new clsValue(0n)); + }); + + it(`Should shift left ${clsValue.name} correctly`, () => { + const uintA = new clsValue(1); + const result = uintA.shl(new clsValue(1n)); + expect(result).toEqual(new clsValue(0n)); + }); + + it(`Should and two ${clsValue.name} correctly`, () => { + const uintA = new clsValue(1); + const uintB = new clsValue(1); + const result = uintA.and(uintB); + expect(result).toEqual(new clsValue(1n)); + }); + + it(`Should or two ${clsValue.name} correctly`, () => { + const uintA = new clsValue(0); + const uintB = new clsValue(1); + const result = uintA.or(uintB); + expect(result).toEqual(new clsValue(1n)); + }); + + it(`Should xor two ${clsValue.name} correctly`, () => { + const uintA = new clsValue(1); + const uintB = new clsValue(1); + const result = uintA.xor(uintB); + expect(result).toEqual(new clsValue(0n)); + }); + + it(`Should check equality of two ${clsValue.name} correctly`, () => { + const a = new clsValue(1); + const b = new clsValue(1); + const c = new clsValue(0); + expect(a.equals(b)).toBe(true); + expect(a.equals(c)).toBe(false); + }); + + it(`Should check if one ${clsValue.name} is less than another correctly`, () => { + const a = new clsValue(0); + const b = new clsValue(1); + expect(a.lt(b)).toBe(true); + expect(b.lt(a)).toBe(false); + }); + }); +}); + +describe.each([Uint8, Uint16, Uint32, Uint64, Uint128])('Integral Types (excluding U1)', (clsValue: IntegralClass) => { describe(`${clsValue.name}`, () => { it(`Should construct a new ${clsValue.name} from a number`, () => { const x = new clsValue(5); diff --git a/yarn-project/simulator/src/avm/avm_memory_types.ts b/yarn-project/simulator/src/avm/avm_memory_types.ts index c85f920b7be..f590c6a40cf 100644 --- a/yarn-project/simulator/src/avm/avm_memory_types.ts +++ b/yarn-project/simulator/src/avm/avm_memory_types.ts @@ -1,3 +1,12 @@ +import { + MEM_TAG_FF, + MEM_TAG_U1, + MEM_TAG_U8, + MEM_TAG_U16, + MEM_TAG_U32, + MEM_TAG_U64, + MEM_TAG_U128, +} from '@aztec/circuits.js'; import { toBufferBE } from '@aztec/foundation/bigint-buffer'; import { Fr } from '@aztec/foundation/fields'; import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log'; @@ -128,6 +137,9 @@ function UnsignedIntegerClassFactory(bits: number) { } public toBuffer(): Buffer { + if (bits < 8) { + return toBufferBE(this.n, 1); + } return toBufferBE(this.n, bits / 8); } }; @@ -136,6 +148,7 @@ function UnsignedIntegerClassFactory(bits: number) { // Now we can create the classes for each unsigned integer type. // We extend instead of just assigning so that the class has the right name. // Otherwise they are all called "NewUintClass". +export class Uint1 extends UnsignedIntegerClassFactory(1) {} export class Uint8 extends UnsignedIntegerClassFactory(8) {} export class Uint16 extends UnsignedIntegerClassFactory(16) {} export class Uint32 extends UnsignedIntegerClassFactory(32) {} @@ -196,12 +209,13 @@ export class Field extends MemoryValue { export enum TypeTag { UNINITIALIZED, - UINT8, - UINT16, - UINT32, - UINT64, - UINT128, - FIELD, + UINT1 = MEM_TAG_U1, + UINT8 = MEM_TAG_U8, + UINT16 = MEM_TAG_U16, + UINT32 = MEM_TAG_U32, + UINT64 = MEM_TAG_U64, + UINT128 = MEM_TAG_U128, + FIELD = MEM_TAG_FF, INVALID, } @@ -302,7 +316,9 @@ export class TaggedMemory implements TaggedMemoryInterface { } public static checkIsIntegralTag(tag: TypeTag) { - if (![TypeTag.UINT8, TypeTag.UINT16, TypeTag.UINT32, TypeTag.UINT64, TypeTag.UINT128].includes(tag)) { + if ( + ![TypeTag.UINT1, TypeTag.UINT8, TypeTag.UINT16, TypeTag.UINT32, TypeTag.UINT64, TypeTag.UINT128].includes(tag) + ) { throw TagCheckError.forTag(TypeTag[tag], 'integral'); } } @@ -332,8 +348,8 @@ export class TaggedMemory implements TaggedMemoryInterface { if (v === undefined) { tag = TypeTag.UNINITIALIZED; - } else if (v instanceof Field) { - tag = TypeTag.FIELD; + } else if (v instanceof Uint1) { + tag = TypeTag.UINT1; } else if (v instanceof Uint8) { tag = TypeTag.UINT8; } else if (v instanceof Uint16) { @@ -344,6 +360,8 @@ export class TaggedMemory implements TaggedMemoryInterface { tag = TypeTag.UINT64; } else if (v instanceof Uint128) { tag = TypeTag.UINT128; + } else if (v instanceof Field) { + tag = TypeTag.FIELD; } return tag; @@ -353,6 +371,8 @@ export class TaggedMemory implements TaggedMemoryInterface { public static buildFromTagTruncating(v: bigint | number, tag: TypeTag): MemoryValue { v = BigInt(v); switch (tag) { + case TypeTag.UINT1: + return new Uint1(v & 1n); case TypeTag.UINT8: return new Uint8(v & ((1n << 8n) - 1n)); case TypeTag.UINT16: @@ -373,6 +393,8 @@ export class TaggedMemory implements TaggedMemoryInterface { // Does not truncate. Type constructor will check that it fits. public static buildFromTagOrDie(v: bigint | number, tag: TypeTag): MemoryValue { switch (tag) { + case TypeTag.UINT1: + return new Uint1(v); case TypeTag.UINT8: return new Uint8(v); case TypeTag.UINT16: diff --git a/yarn-project/simulator/src/avm/opcodes/comparators.ts b/yarn-project/simulator/src/avm/opcodes/comparators.ts index be0b5c69c09..9ffca75e9b5 100644 --- a/yarn-project/simulator/src/avm/opcodes/comparators.ts +++ b/yarn-project/simulator/src/avm/opcodes/comparators.ts @@ -1,5 +1,5 @@ import type { AvmContext } from '../avm_context.js'; -import { type MemoryValue, Uint8 } from '../avm_memory_types.js'; +import { type MemoryValue, Uint1 } from '../avm_memory_types.js'; import { Opcode } from '../serialization/instruction_serialization.js'; import { Addressing } from './addressing_mode.js'; import { ThreeOperandInstruction } from './instruction_impl.js'; @@ -19,7 +19,7 @@ abstract class ComparatorInstruction extends ThreeOperandInstruction { const a = memory.get(aOffset); const b = memory.get(bOffset); - const dest = new Uint8(this.compare(a, b) ? 1 : 0); + const dest = new Uint1(this.compare(a, b) ? 1 : 0); memory.set(dstOffset, dest); memory.assert(memoryOperations); diff --git a/yarn-project/simulator/src/avm/opcodes/conversion.test.ts b/yarn-project/simulator/src/avm/opcodes/conversion.test.ts index d3278b0871f..4903af1992c 100644 --- a/yarn-project/simulator/src/avm/opcodes/conversion.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/conversion.test.ts @@ -1,5 +1,5 @@ import { type AvmContext } from '../avm_context.js'; -import { Field, type Uint8, Uint32 } from '../avm_memory_types.js'; +import { Field, type Uint1, type Uint8, Uint32 } from '../avm_memory_types.js'; import { initContext } from '../fixtures/index.js'; import { Addressing, AddressingMode } from './addressing_mode.js'; import { ToRadixLE } from './conversion.js'; @@ -18,31 +18,36 @@ describe('Conversion Opcodes', () => { 1, // indirect ...Buffer.from('12345678', 'hex'), // inputStateOffset ...Buffer.from('23456789', 'hex'), // outputStateOffset - ...Buffer.from('00000002', 'hex'), // radix + ...Buffer.from('3456789A', 'hex'), // radixOffset ...Buffer.from('00000100', 'hex'), // numLimbs + ...Buffer.from('01', 'hex'), // outputBits ]); const inst = new ToRadixLE( /*indirect=*/ 1, /*srcOffset=*/ 0x12345678, /*dstOffset=*/ 0x23456789, - /*radix=*/ 2, + /*radixOffset=*/ 0x3456789a, /*numLimbs=*/ 256, + /*outputBits=*/ 1, ); expect(ToRadixLE.deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); - it('Should decompose correctly - direct', async () => { + it('Should decompose correctly to bytes - direct', async () => { const arg = new Field(0b1011101010100n); + const radix = new Uint32(2); // Bit decomposition const indirect = 0; const srcOffset = 0; - const radix = 2; // Bit decomposition - const numLimbs = 10; // only the first 10 bits const dstOffset = 20; + const radixOffset = 1; + const numLimbs = 10; // only the first 10 bits + const outputBits = 0; // false, output as bytes context.machineState.memory.set(srcOffset, arg); + context.machineState.memory.set(radixOffset, radix); - await new ToRadixLE(indirect, srcOffset, dstOffset, radix, numLimbs).execute(context); + await new ToRadixLE(indirect, srcOffset, dstOffset, radixOffset, numLimbs, outputBits).execute(context); const resultBuffer: Buffer = Buffer.concat( context.machineState.memory.getSliceAs(dstOffset, numLimbs).map(byte => byte.toBuffer()), @@ -54,23 +59,54 @@ describe('Conversion Opcodes', () => { } }); + it('Should decompose correctly to bits - direct', async () => { + const arg = new Field(0b1011101010100n); + const radix = new Uint32(2); // Bit decomposition + const indirect = 0; + const srcOffset = 0; + const dstOffset = 20; + const radixOffset = 1; + const numLimbs = 10; // only the first 10 bits + const outputBits = 1; // true, output as bits + context.machineState.memory.set(srcOffset, arg); + context.machineState.memory.set(radixOffset, radix); + + await new ToRadixLE(indirect, srcOffset, dstOffset, radixOffset, numLimbs, outputBits).execute(context); + + const resultBuffer: Buffer = Buffer.concat( + context.machineState.memory.getSliceAs(dstOffset, numLimbs).map(byte => byte.toBuffer()), + ); + // The expected result is the first 10 bits of the input, reversed + const expectedResults = '1011101010100'.split('').reverse().slice(0, numLimbs).map(Number); + for (let i = 0; i < numLimbs; i++) { + expect(resultBuffer.readUInt8(i)).toEqual(expectedResults[i]); + } + }); + it('Should decompose correctly - indirect', async () => { const arg = new Field(Buffer.from('1234567890abcdef', 'hex')); const indirect = new Addressing([ /*srcOffset=*/ AddressingMode.INDIRECT, /*dstOffset*/ AddressingMode.INDIRECT, + /*radixOffset*/ AddressingMode.INDIRECT, ]).toWire(); const srcOffset = 0; const srcOffsetReal = 10; const dstOffset = 2; const dstOffsetReal = 30; + const radixOffset = 3; + const radix = new Uint32(1 << 8); // Byte decomposition + const radixOffsetReal = 50; + context.machineState.memory.set(srcOffset, new Uint32(srcOffsetReal)); context.machineState.memory.set(dstOffset, new Uint32(dstOffsetReal)); + context.machineState.memory.set(radixOffset, new Uint32(radixOffsetReal)); context.machineState.memory.set(srcOffsetReal, arg); + context.machineState.memory.set(radixOffsetReal, radix); - const radix = 1 << 8; // Byte decomposition const numLimbs = 32; // 256-bit decomposition - await new ToRadixLE(indirect, srcOffset, dstOffset, radix, numLimbs).execute(context); + const outputBits = 0; // false, output as bytes + await new ToRadixLE(indirect, srcOffset, dstOffset, radixOffset, numLimbs, outputBits).execute(context); const resultBuffer: Buffer = Buffer.concat( context.machineState.memory.getSliceAs(dstOffsetReal, numLimbs).map(byte => byte.toBuffer()), diff --git a/yarn-project/simulator/src/avm/opcodes/conversion.ts b/yarn-project/simulator/src/avm/opcodes/conversion.ts index 70e29969973..5a7d80d2ded 100644 --- a/yarn-project/simulator/src/avm/opcodes/conversion.ts +++ b/yarn-project/simulator/src/avm/opcodes/conversion.ts @@ -1,7 +1,6 @@ -import { strict as assert } from 'assert'; - import { type AvmContext } from '../avm_context.js'; -import { TypeTag, Uint8 } from '../avm_memory_types.js'; +import { TypeTag, Uint1, Uint8 } from '../avm_memory_types.js'; +import { InstructionExecutionError } from '../errors.js'; import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; import { Addressing } from './addressing_mode.js'; import { Instruction } from './instruction.js'; @@ -16,32 +15,41 @@ export class ToRadixLE extends Instruction { OperandType.UINT8, // Indirect OperandType.UINT32, // src memory address OperandType.UINT32, // dst memory address - OperandType.UINT32, // radix (immediate) + OperandType.UINT32, // radix memory address OperandType.UINT32, // number of limbs (Immediate) + OperandType.UINT1, // output is in "bits" mode (Immediate - Uint1 still takes up a whole byte) ]; constructor( private indirect: number, private srcOffset: number, private dstOffset: number, - private radix: number, + private radixOffset: number, private numLimbs: number, + private outputBits: number, // effectively a bool ) { - assert(radix <= 256, 'Radix cannot be greater than 256'); super(); } public async execute(context: AvmContext): Promise { const memory = context.machineState.memory.track(this.type); - const [srcOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.srcOffset, this.dstOffset], memory); - const memoryOperations = { reads: 1, writes: this.numLimbs, indirect: this.indirect }; + const [srcOffset, dstOffset, radixOffset] = Addressing.fromWire(this.indirect).resolve( + [this.srcOffset, this.dstOffset, this.radixOffset], + memory, + ); + const memoryOperations = { reads: 2, writes: this.numLimbs, indirect: this.indirect }; context.machineState.consumeGas(this.gasCost({ ...memoryOperations, dynMultiplier: this.numLimbs })); // The radix gadget only takes in a Field memory.checkTag(TypeTag.FIELD, srcOffset); + memory.checkTag(TypeTag.UINT32, radixOffset); let value: bigint = memory.get(srcOffset).toBigInt(); - const radixBN: bigint = BigInt(this.radix); + const radix: bigint = memory.get(radixOffset).toBigInt(); + if (radix > 256) { + throw new InstructionExecutionError(`ToRadixLE instruction's radix should be <= 256 (was ${radix})`); + } + const radixBN: bigint = BigInt(radix); const limbArray = []; for (let i = 0; i < this.numLimbs; i++) { @@ -50,7 +58,8 @@ export class ToRadixLE extends Instruction { value /= radixBN; } - const res = limbArray.map(byte => new Uint8(byte)); + const outputType = this.outputBits != 0 ? Uint1 : Uint8; + const res = limbArray.map(byte => new outputType(byte)); memory.setSlice(dstOffset, res); memory.assert(memoryOperations); diff --git a/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.test.ts b/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.test.ts index 133f215dfad..098a0dcd889 100644 --- a/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.test.ts @@ -2,7 +2,7 @@ import { Fq, Fr } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { type AvmContext } from '../avm_context.js'; -import { Field, type MemoryValue, Uint8, Uint32 } from '../avm_memory_types.js'; +import { Field, type MemoryValue, Uint1, Uint32 } from '../avm_memory_types.js'; import { initContext } from '../fixtures/index.js'; import { MultiScalarMul } from './multi_scalar_mul.js'; @@ -50,7 +50,7 @@ describe('MultiScalarMul Opcode', () => { // Points are stored as [x1, y1, inf1, x2, y2, inf2, ...] where the types are [Field, Field, Uint8, Field, Field, Uint8, ...] const storedPoints: MemoryValue[] = points .map(p => p.toFields()) - .flatMap(([x, y, inf]) => [new Field(x), new Field(y), new Uint8(inf.toNumber())]); + .flatMap(([x, y, inf]) => [new Field(x), new Field(y), new Uint1(inf.toNumber())]); const pointsOffset = 0; context.machineState.memory.setSlice(pointsOffset, storedPoints); // Store scalars @@ -90,7 +90,7 @@ describe('MultiScalarMul Opcode', () => { // Points are stored as [x1, y1, inf1, x2, y2, inf2, ...] where the types are [Field, Field, Uint8, Field, Field, Uint8, ...] const storedPoints: MemoryValue[] = points .map(p => p.toFields()) - .flatMap(([x, y, inf]) => [new Field(x), new Field(y), new Uint8(inf.toNumber())]); + .flatMap(([x, y, inf]) => [new Field(x), new Field(y), new Uint1(inf.toNumber())]); const pointsOffset = 0; context.machineState.memory.setSlice(pointsOffset, storedPoints); // Store scalars diff --git a/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.ts b/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.ts index c89301ee134..3ac9223c185 100644 --- a/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.ts +++ b/yarn-project/simulator/src/avm/opcodes/multi_scalar_mul.ts @@ -54,8 +54,8 @@ export class MultiScalarMul extends Instruction { const offset = pointsOffset + i * 3; // Check (Field, Field) memory.checkTagsRange(TypeTag.FIELD, offset, 2); - // Check Uint8 (inf flag) - memory.checkTag(TypeTag.UINT8, offset + 2); + // Check Uint1 (inf flag) + memory.checkTag(TypeTag.UINT1, offset + 2); } // Get the unrolled (x, y, inf) representing the points const pointsVector = memory.getSlice(pointsOffset, pointsReadLength); diff --git a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts index 140a586f5ec..8dc7047d3c6 100644 --- a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts @@ -109,6 +109,7 @@ export enum Opcode { // Note that cpp code introduced an additional enum value TAG to express the instruction tag. In TS, // this one is parsed as UINT8. export enum OperandType { + UINT1, UINT8, UINT16, UINT32, @@ -122,6 +123,7 @@ type OperandWriter = (value: any) => void; // Specifies how to read and write each operand type. const OPERAND_SPEC = new Map OperandNativeType, OperandWriter]>([ + [OperandType.UINT1, [1, Buffer.prototype.readUint8, Buffer.prototype.writeUint8]], [OperandType.UINT8, [1, Buffer.prototype.readUint8, Buffer.prototype.writeUint8]], [OperandType.UINT16, [2, Buffer.prototype.readUint16BE, Buffer.prototype.writeUint16BE]], [OperandType.UINT32, [4, Buffer.prototype.readUint32BE, Buffer.prototype.writeUint32BE]],