diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index a5ca11a5a470..2a25f8242f9e 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -62,6 +62,7 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { lhs, rhs, } => { + assert!(is_integral_bit_size(*bit_size), "BinaryIntOp::{:?} bit_size must be integral, got {:?}", op, bit_size); let avm_opcode = match op { BinaryIntOp::Add => AvmOpcode::ADD, BinaryIntOp::Sub => AvmOpcode::SUB, @@ -913,6 +914,13 @@ fn map_brillig_pcs_to_avm_pcs(initial_offset: usize, brillig: &Brillig) -> Vec bool { + match bit_size { + 1 | 8 | 16 | 32 | 64 | 128 => true, + _ => false, + } +} + fn tag_from_bit_size(bit_size: u32) -> AvmTypeTag { match bit_size { 1 => AvmTypeTag::UINT8, // temp workaround diff --git a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr index cba141f907e1..f57bc9411238 100644 --- a/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/app_subscription_contract/src/main.nr @@ -31,7 +31,7 @@ contract AppSubscription { global SUBSCRIPTION_DURATION_IN_BLOCKS = 5; global SUBSCRIPTION_TXS = 5; - global CANONICAL_GAS_TOKEN_ADDRESS = AztecAddress::from_field(0x22a29a9544c0cbdbc35bb21caa78b6f08903be4b390a65319e33afd7443f3499); + global CANONICAL_GAS_TOKEN_ADDRESS = AztecAddress::from_field(10518537853519909204957666322334442672584410385979059968848104222965977783517); #[aztec(private)] fn entrypoint(payload: pub DAppPayload, user_address: pub AztecAddress) { diff --git a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr index fe871b6afe42..636390cdb3e5 100644 --- a/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/fpc_contract/src/main.nr @@ -11,7 +11,7 @@ contract FPC { gas_token_address: SharedImmutable, } - global CANONICAL_GAS_TOKEN_ADDRESS = AztecAddress::from_field(0x22a29a9544c0cbdbc35bb21caa78b6f08903be4b390a65319e33afd7443f3499); + global CANONICAL_GAS_TOKEN_ADDRESS = AztecAddress::from_field(10518537853519909204957666322334442672584410385979059968848104222965977783517); #[aztec(public)] #[aztec(initializer)] diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index c04d8475f087..0189a499d49b 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -831,16 +831,10 @@ impl<'block> BrilligBlock<'block> { _ => unreachable!("ICE: array set on non-array"), }; + // Here we want to compare the reference count against 1. let one = self.brillig_context.make_usize_constant(1_usize.into()); let condition = self.brillig_context.allocate_register(); - - self.brillig_context.binary_instruction( - reference_count, - one, - condition, - BrilligBinaryOp::Field { op: BinaryFieldOp::Equals }, - ); - + self.brillig_context.memory_op(reference_count, one, condition, BinaryIntOp::Equals); self.brillig_context.branch_instruction(condition, |ctx, cond| { if cond { // Reference count is 1, we can mutate the array directly diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index 662dc074d980..b66efa4da278 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -27,7 +27,6 @@ use acvm::{ FieldElement, }; use debug_show::DebugShow; -use num_bigint::BigUint; /// The Brillig VM does not apply a limit to the memory address space, /// As a convention, we take use 64 bits. This means that we assume that @@ -213,13 +212,7 @@ impl BrilligContext { self.debug_show.array_get(array_ptr, index, result); // Computes array_ptr + index, ie array[index] let index_of_element_in_memory = self.allocate_register(); - self.binary_instruction( - array_ptr, - index, - index_of_element_in_memory, - BrilligBinaryOp::Field { op: BinaryFieldOp::Add }, - ); - + self.memory_op(array_ptr, index, index_of_element_in_memory, BinaryIntOp::Add); self.load_instruction(result, index_of_element_in_memory); // Free up temporary register self.deallocate_register(index_of_element_in_memory); @@ -239,7 +232,10 @@ impl BrilligContext { array_ptr, index, index_of_element_in_memory, - BrilligBinaryOp::Field { op: BinaryFieldOp::Add }, + BrilligBinaryOp::Integer { + op: BinaryIntOp::Add, + bit_size: BRILLIG_MEMORY_ADDRESSING_BIT_SIZE, + }, ); self.store_instruction(index_of_element_in_memory, value); @@ -726,6 +722,8 @@ impl BrilligContext { /// Instead truncation instructions are emitted as to when a /// truncation should be done. /// For Brillig, all integer operations will overflow as its cheap. + /// We currently use cast to truncate: we cast to the required bit size + /// and back to the original bit size. pub(crate) fn truncate_instruction( &mut self, destination_of_truncated_value: SingleAddrVariable, @@ -744,20 +742,12 @@ impl BrilligContext { value_to_truncate.bit_size ); - let mask = BigUint::from(2_u32).pow(bit_size) - BigUint::from(1_u32); - let mask_constant = self.make_constant( - FieldElement::from_be_bytes_reduce(&mask.to_bytes_be()).into(), - value_to_truncate.bit_size, - ); - - self.binary_instruction( - value_to_truncate.address, - mask_constant, - destination_of_truncated_value.address, - BrilligBinaryOp::Integer { op: BinaryIntOp::And, bit_size: value_to_truncate.bit_size }, - ); - - self.deallocate_register(mask_constant); + // We cast back and forth to ensure that the value is truncated. + let intermediate_register = + SingleAddrVariable { address: self.allocate_register(), bit_size }; + self.cast_instruction(intermediate_register, value_to_truncate); + self.cast_instruction(destination_of_truncated_value, intermediate_register); + self.deallocate_register(intermediate_register.address); } /// Emits a stop instruction diff --git a/yarn-project/protocol-contracts/src/gas-token/__snapshots__/index.test.ts.snap b/yarn-project/protocol-contracts/src/gas-token/__snapshots__/index.test.ts.snap index 4e3dcb411555..79c161f0dcb6 100644 --- a/yarn-project/protocol-contracts/src/gas-token/__snapshots__/index.test.ts.snap +++ b/yarn-project/protocol-contracts/src/gas-token/__snapshots__/index.test.ts.snap @@ -3,122 +3,122 @@ exports[`GasToken returns canonical protocol contract 1`] = ` { "address": AztecAddress { - "asBigInt": 15665932969535162258465850005057765068325313178683719227533369271008947549337n, + "asBigInt": 10518537853519909204957666322334442672584410385979059968848104222965977783517n, "asBuffer": { "data": [ + 23, + 65, + 72, + 13, + 6, + 111, + 233, + 124, + 40, + 151, + 239, + 36, + 144, + 234, 34, - 162, - 154, + 48, 149, - 68, - 192, + 204, + 24, + 108, + 103, + 5, + 224, + 47, + 181, + 106, + 33, + 6, + 27, 203, - 219, - 195, - 91, - 178, 28, - 170, - 120, - 182, - 240, - 137, - 3, - 190, - 75, - 57, - 10, - 101, - 49, - 158, - 51, - 175, - 215, - 68, - 63, - 52, - 153, + 221, ], "type": "Buffer", }, }, "instance": { "address": AztecAddress { - "asBigInt": 15665932969535162258465850005057765068325313178683719227533369271008947549337n, + "asBigInt": 10518537853519909204957666322334442672584410385979059968848104222965977783517n, "asBuffer": { "data": [ + 23, + 65, + 72, + 13, + 6, + 111, + 233, + 124, + 40, + 151, + 239, + 36, + 144, + 234, 34, - 162, - 154, + 48, 149, - 68, - 192, + 204, + 24, + 108, + 103, + 5, + 224, + 47, + 181, + 106, + 33, + 6, + 27, 203, - 219, - 195, - 91, - 178, 28, - 170, - 120, - 182, - 240, - 137, - 3, - 190, - 75, - 57, - 10, - 101, - 49, - 158, - 51, - 175, - 215, - 68, - 63, - 52, - 153, + 221, ], "type": "Buffer", }, }, "contractClassId": Fr { - "asBigInt": 8048474924228513577213811692516857993138982652659338793381794528774172095058n, + "asBigInt": 1081288800764539456992515725727545013194509212534089179832398000157107722146n, "asBuffer": { "data": [ - 17, - 203, - 70, - 126, - 237, - 15, - 145, - 124, - 146, - 221, - 105, - 27, - 232, - 251, - 187, - 118, - 53, - 135, - 128, - 177, - 24, - 140, - 248, - 116, - 36, + 2, + 99, + 252, + 222, + 180, + 100, + 28, + 30, + 214, + 18, + 131, + 72, 114, - 207, - 163, + 250, + 186, + 113, + 101, + 40, + 14, + 133, + 193, + 94, + 154, + 6, + 203, + 103, + 189, 107, - 206, - 178, - 82, + 88, + 212, + 151, + 162, ], "type": "Buffer", }, @@ -318,41 +318,41 @@ exports[`GasToken returns canonical protocol contract 2`] = ` }, }, "id": Fr { - "asBigInt": 8048474924228513577213811692516857993138982652659338793381794528774172095058n, + "asBigInt": 1081288800764539456992515725727545013194509212534089179832398000157107722146n, "asBuffer": { "data": [ - 17, - 203, - 70, - 126, - 237, - 15, - 145, - 124, - 146, - 221, - 105, - 27, - 232, - 251, - 187, - 118, - 53, - 135, - 128, - 177, - 24, - 140, - 248, - 116, - 36, + 2, + 99, + 252, + 222, + 180, + 100, + 28, + 30, + 214, + 18, + 131, + 72, 114, - 207, - 163, + 250, + 186, + 113, + 101, + 40, + 14, + 133, + 193, + 94, + 154, + 6, + 203, + 103, + 189, 107, - 206, - 178, - 82, + 88, + 212, + 151, + 162, ], "type": "Buffer", }, @@ -446,41 +446,41 @@ exports[`GasToken returns canonical protocol contract 2`] = ` }, }, "publicBytecodeCommitment": Fr { - "asBigInt": 17070200264896729278819077147914995144552691471904174679230466337970801154331n, + "asBigInt": 11070879835458647599904872869544251898416073411427356569372185618409843299916n, "asBuffer": { "data": [ - 37, - 189, - 100, - 22, - 41, - 3, - 133, - 115, - 227, + 24, + 121, + 229, + 91, + 202, + 195, + 128, + 170, + 238, + 201, + 145, + 159, + 246, 6, - 2, - 151, - 250, - 15, - 99, - 123, + 245, + 115, + 211, + 60, + 229, + 130, + 225, + 76, + 234, 38, - 241, - 249, - 80, - 125, - 120, - 249, - 174, - 143, - 146, - 118, - 52, - 51, - 25, - 25, - 27, + 46, + 15, + 108, + 202, + 129, + 107, + 150, + 76, ], "type": "Buffer", },