From b2a000e5f366721b514653456db804a704242b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Mon, 5 Feb 2024 13:19:40 +0100 Subject: [PATCH] feat: Add bit size to const opcode (#4385) --- avm-transpiler/src/transpile.rs | 2 +- .../dsl/acir_format/serde/acir.hpp | 6 ++ noir/acvm-repo/acir/codegen/acir.cpp | 4 + .../acir/tests/test_program_serialization.rs | 89 ++++++++++--------- .../compiler/optimizers/redundant_range.rs | 1 + .../acvm-repo/acvm_js/test/shared/addition.ts | 10 +-- .../test/shared/complex_foreign_call.ts | 13 +-- .../test/shared/fixed_base_scalar_mul.ts | 6 +- .../acvm_js/test/shared/foreign_call.ts | 6 +- .../acvm_js/test/shared/memory_op.ts | 8 +- .../acvm-repo/acvm_js/test/shared/pedersen.ts | 4 +- .../acvm_js/test/shared/schnorr_verify.ts | 24 ++--- noir/acvm-repo/brillig/src/opcodes.rs | 1 + noir/acvm-repo/brillig_vm/src/lib.rs | 62 ++++++++----- .../src/brillig/brillig_gen/brillig_block.rs | 50 ++++++----- .../brillig/brillig_gen/brillig_directive.rs | 11 ++- .../brillig/brillig_gen/brillig_slice_ops.rs | 24 ++--- .../noirc_evaluator/src/brillig/brillig_ir.rs | 46 ++++++---- .../src/brillig/brillig_ir/entry_point.rs | 21 ++--- noir/tooling/debugger/src/context.rs | 1 + 20 files changed, 223 insertions(+), 166 deletions(-) diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index e4f112f9ee8..04af018da1d 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -141,7 +141,7 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { ..Default::default() }); } - BrilligOpcode::Const { destination, value } => { + BrilligOpcode::Const { destination, value, bit_size:_ } => { avm_instrs.push(AvmInstruction { opcode: AvmOpcode::SET, indirect: Some(0), 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 02adc0e63e6..fe9c4e9f340 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -845,6 +845,7 @@ struct BrilligOpcode { struct Const { Circuit::MemoryAddress destination; + uint32_t bit_size; Circuit::Value value; friend bool operator==(const Const&, const Const&); @@ -5336,6 +5337,9 @@ inline bool operator==(const BrilligOpcode::Const& lhs, const BrilligOpcode::Con if (!(lhs.destination == rhs.destination)) { return false; } + if (!(lhs.bit_size == rhs.bit_size)) { + return false; + } if (!(lhs.value == rhs.value)) { return false; } @@ -5367,6 +5371,7 @@ void serde::Serializable::serialize(const Circuit Serializer& serializer) { serde::Serializable::serialize(obj.destination, serializer); + serde::Serializable::serialize(obj.bit_size, serializer); serde::Serializable::serialize(obj.value, serializer); } @@ -5377,6 +5382,7 @@ Circuit::BrilligOpcode::Const serde::Deserializable::deserialize(deserializer); + obj.bit_size = serde::Deserializable::deserialize(deserializer); obj.value = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/noir/acvm-repo/acir/codegen/acir.cpp b/noir/acvm-repo/acir/codegen/acir.cpp index bdee08794e6..b65dfd45030 100644 --- a/noir/acvm-repo/acir/codegen/acir.cpp +++ b/noir/acvm-repo/acir/codegen/acir.cpp @@ -800,6 +800,7 @@ namespace Circuit { struct Const { Circuit::MemoryAddress destination; + uint32_t bit_size; Circuit::Value value; friend bool operator==(const Const&, const Const&); @@ -4410,6 +4411,7 @@ namespace Circuit { inline bool operator==(const BrilligOpcode::Const &lhs, const BrilligOpcode::Const &rhs) { if (!(lhs.destination == rhs.destination)) { return false; } + if (!(lhs.bit_size == rhs.bit_size)) { return false; } if (!(lhs.value == rhs.value)) { return false; } return true; } @@ -4435,6 +4437,7 @@ template <> template void serde::Serializable::serialize(const Circuit::BrilligOpcode::Const &obj, Serializer &serializer) { serde::Serializable::serialize(obj.destination, serializer); + serde::Serializable::serialize(obj.bit_size, serializer); serde::Serializable::serialize(obj.value, serializer); } @@ -4443,6 +4446,7 @@ template Circuit::BrilligOpcode::Const serde::Deserializable::deserialize(Deserializer &deserializer) { Circuit::BrilligOpcode::Const obj; obj.destination = serde::Deserializable::deserialize(deserializer); + obj.bit_size = serde::Deserializable::deserialize(deserializer); obj.value = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/noir/acvm-repo/acir/tests/test_program_serialization.rs b/noir/acvm-repo/acir/tests/test_program_serialization.rs index c94c5ae66b0..9387c7c4f77 100644 --- a/noir/acvm-repo/acir/tests/test_program_serialization.rs +++ b/noir/acvm-repo/acir/tests/test_program_serialization.rs @@ -45,12 +45,12 @@ fn addition_circuit() { let bytes = Circuit::serialize_circuit(&circuit); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 187, 13, 192, 32, 12, 68, 249, 100, 32, 27, - 219, 96, 119, 89, 37, 40, 176, 255, 8, 17, 18, 5, 74, 202, 240, 154, 235, 158, 238, 238, - 112, 206, 121, 247, 37, 206, 60, 103, 194, 63, 208, 111, 116, 133, 197, 69, 144, 153, 91, - 73, 13, 9, 47, 72, 86, 85, 128, 165, 102, 69, 69, 81, 185, 147, 18, 53, 101, 45, 86, 173, - 128, 33, 83, 195, 46, 70, 125, 202, 226, 190, 94, 16, 166, 103, 108, 13, 203, 151, 254, - 245, 233, 224, 1, 1, 52, 166, 127, 120, 1, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 59, 18, 128, 32, 12, 68, 249, 120, 160, 132, + 36, 144, 116, 94, 69, 70, 184, 255, 17, 28, 29, 10, 70, 75, 121, 205, 118, 111, 118, 119, + 115, 206, 121, 247, 37, 142, 220, 71, 194, 63, 208, 47, 116, 133, 201, 69, 144, 153, 91, + 73, 13, 9, 15, 72, 86, 85, 128, 165, 102, 69, 69, 81, 57, 147, 18, 53, 101, 45, 86, 173, + 128, 33, 83, 195, 46, 70, 125, 200, 226, 186, 94, 16, 134, 231, 222, 26, 166, 47, 253, 235, + 211, 135, 11, 47, 121, 122, 165, 121, 1, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -75,9 +75,9 @@ fn fixed_base_scalar_mul_circuit() { let bytes = Circuit::serialize_circuit(&circuit); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 138, 91, 10, 0, 48, 12, 194, 178, 215, 215, 46, 189, - 163, 175, 165, 10, 21, 36, 10, 57, 192, 160, 146, 188, 226, 139, 78, 113, 69, 183, 190, 61, - 111, 218, 182, 231, 124, 122, 8, 177, 65, 92, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 138, 91, 10, 0, 32, 12, 195, 226, 235, 203, 75, 123, + 116, 39, 182, 99, 133, 146, 22, 178, 128, 198, 207, 227, 22, 79, 180, 139, 35, 58, 245, + 237, 121, 83, 182, 189, 204, 5, 167, 198, 147, 98, 93, 0, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -103,8 +103,8 @@ fn pedersen_circuit() { let expected_serialization: Vec = vec![ 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 138, 9, 10, 0, 64, 8, 2, 103, 15, 232, 255, 31, 142, - 138, 10, 34, 65, 84, 198, 15, 28, 82, 145, 178, 182, 86, 191, 238, 183, 24, 131, 205, 79, - 203, 0, 166, 242, 158, 93, 92, 0, 0, 0, + 138, 34, 34, 65, 84, 198, 15, 28, 82, 145, 178, 182, 86, 191, 238, 183, 24, 131, 205, 79, + 203, 0, 162, 119, 234, 237, 93, 0, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -143,22 +143,22 @@ fn schnorr_verify_circuit() { let bytes = Circuit::serialize_circuit(&circuit); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 210, 87, 78, 2, 1, 20, 134, 209, 177, 247, 222, 123, - 71, 68, 68, 68, 68, 68, 68, 68, 68, 68, 221, 133, 251, 95, 130, 145, 27, 206, 36, 78, 50, - 57, 16, 94, 200, 253, 191, 159, 36, 73, 134, 146, 193, 19, 142, 243, 183, 255, 14, 179, - 233, 247, 145, 254, 59, 217, 127, 71, 57, 198, 113, 78, 48, 125, 167, 56, 205, 25, 206, - 114, 142, 243, 92, 224, 34, 151, 184, 204, 21, 174, 114, 141, 235, 220, 224, 38, 183, 184, - 205, 29, 238, 114, 143, 251, 60, 224, 33, 143, 120, 204, 19, 158, 242, 140, 25, 158, 51, - 203, 11, 230, 120, 201, 60, 175, 88, 224, 53, 139, 188, 97, 137, 183, 44, 243, 142, 21, - 222, 179, 202, 7, 214, 248, 200, 58, 159, 216, 224, 51, 155, 124, 97, 235, 223, 142, 241, - 188, 250, 222, 230, 27, 59, 124, 103, 151, 31, 236, 241, 147, 95, 252, 246, 57, 158, 104, - 47, 186, 139, 214, 162, 179, 104, 44, 250, 74, 219, 154, 242, 63, 162, 165, 232, 40, 26, - 138, 126, 162, 157, 232, 38, 154, 137, 94, 162, 149, 232, 36, 26, 137, 62, 162, 141, 232, - 34, 154, 136, 30, 162, 133, 232, 32, 26, 136, 253, 99, 251, 195, 100, 176, 121, 236, 29, - 91, 159, 218, 56, 99, 219, 172, 77, 115, 182, 204, 219, 176, 96, 187, 162, 205, 74, 182, - 42, 219, 168, 98, 155, 170, 77, 106, 182, 168, 219, 160, 225, 246, 77, 55, 111, 185, 113, - 219, 109, 59, 110, 218, 117, 203, 158, 27, 166, 55, 75, 239, 150, 184, 101, 250, 252, 1, - 55, 204, 92, 74, 220, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 210, 233, 50, 66, 1, 24, 199, 225, 99, 223, 247, + 125, 223, 146, 36, 73, 146, 36, 73, 146, 132, 187, 112, 255, 151, 96, 244, 78, 79, 198, + 153, 57, 243, 212, 244, 165, 121, 255, 191, 239, 36, 73, 134, 146, 254, 19, 142, 243, 167, + 247, 14, 179, 225, 247, 145, 222, 59, 217, 123, 71, 57, 198, 113, 78, 112, 240, 78, 113, + 154, 51, 156, 229, 28, 231, 185, 192, 69, 46, 113, 153, 43, 92, 229, 26, 215, 185, 193, 77, + 110, 113, 155, 59, 220, 229, 30, 247, 121, 192, 67, 30, 241, 152, 39, 76, 241, 148, 105, + 158, 49, 195, 115, 102, 121, 193, 28, 47, 153, 231, 21, 11, 188, 102, 145, 55, 44, 241, + 150, 101, 222, 177, 194, 123, 86, 249, 192, 26, 31, 89, 231, 19, 27, 124, 102, 243, 223, + 142, 241, 188, 248, 222, 226, 43, 219, 124, 99, 135, 239, 236, 242, 131, 159, 252, 242, 57, + 158, 104, 47, 186, 139, 214, 162, 179, 104, 44, 250, 26, 180, 53, 229, 127, 68, 75, 209, + 81, 52, 20, 253, 68, 59, 209, 77, 52, 19, 189, 68, 43, 209, 73, 52, 18, 125, 68, 27, 209, + 69, 52, 17, 61, 68, 11, 209, 65, 52, 16, 251, 199, 246, 135, 73, 127, 243, 216, 59, 182, + 78, 217, 56, 109, 219, 140, 77, 179, 182, 204, 217, 48, 111, 187, 130, 205, 138, 182, 42, + 217, 168, 108, 155, 138, 77, 170, 182, 168, 217, 160, 238, 246, 13, 55, 111, 186, 113, 203, + 109, 219, 110, 218, 113, 203, 174, 27, 14, 110, 54, 184, 91, 226, 150, 127, 207, 47, 78, + 22, 245, 106, 221, 3, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -205,10 +205,10 @@ fn simple_brillig_foreign_call() { let expected_serialization: Vec = vec![ 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 143, 177, 10, 192, 32, 12, 68, 207, 148, 150, 118, - 234, 175, 216, 63, 232, 207, 116, 232, 210, 161, 136, 223, 175, 98, 132, 27, 212, 69, 31, - 132, 28, 23, 8, 119, 59, 0, 131, 204, 66, 154, 41, 222, 173, 219, 142, 113, 153, 121, 191, - 44, 231, 21, 237, 144, 88, 43, 249, 11, 71, 156, 77, 245, 251, 249, 231, 119, 189, 214, - 204, 89, 187, 11, 25, 130, 54, 1, 36, 1, 124, 242, 107, 1, 0, 0, + 234, 175, 216, 63, 232, 207, 116, 232, 226, 32, 226, 247, 171, 24, 225, 6, 113, 209, 7, 33, + 199, 5, 194, 221, 9, 192, 160, 178, 145, 102, 154, 247, 234, 182, 115, 60, 102, 221, 47, + 203, 121, 69, 59, 20, 246, 78, 254, 198, 149, 231, 80, 253, 187, 248, 249, 48, 106, 205, + 220, 189, 187, 144, 33, 24, 144, 0, 93, 119, 243, 238, 108, 1, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -258,6 +258,7 @@ fn complex_brillig_foreign_call() { brillig::Opcode::Const { destination: MemoryAddress(0), value: brillig::Value::from(32_usize), + bit_size: 32, }, brillig::Opcode::CalldataCopy { destination_address: MemoryAddress(1), @@ -293,14 +294,14 @@ fn complex_brillig_foreign_call() { let bytes = Circuit::serialize_circuit(&circuit); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 65, 10, 132, 48, 12, 76, 218, 237, 174, 123, - 242, 11, 130, 62, 160, 250, 2, 255, 34, 222, 20, 61, 250, 124, 11, 78, 49, 4, 193, 131, 21, - 52, 16, 210, 132, 105, 50, 77, 210, 140, 136, 152, 54, 177, 65, 13, 206, 12, 95, 74, 196, - 181, 176, 254, 154, 212, 156, 46, 151, 191, 139, 163, 121, 1, 71, 123, 3, 199, 184, 15, 15, - 157, 119, 202, 185, 36, 237, 159, 61, 248, 63, 159, 160, 46, 232, 23, 254, 15, 54, 67, 156, - 96, 11, 213, 119, 82, 248, 116, 179, 104, 188, 163, 125, 15, 89, 213, 253, 139, 154, 221, - 52, 206, 67, 191, 88, 5, 213, 52, 75, 113, 174, 96, 205, 201, 157, 24, 207, 197, 211, 157, - 6, 50, 18, 233, 158, 72, 89, 1, 53, 215, 75, 175, 196, 4, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 81, 10, 131, 48, 12, 125, 105, 215, 205, 125, + 237, 10, 131, 237, 0, 221, 78, 224, 93, 196, 63, 69, 63, 61, 190, 5, 95, 177, 6, 193, 15, + 43, 104, 32, 164, 9, 175, 201, 107, 146, 22, 0, 4, 147, 216, 160, 134, 103, 161, 159, 74, + 196, 149, 180, 126, 159, 252, 36, 95, 46, 127, 20, 71, 115, 1, 142, 246, 0, 142, 113, 31, + 78, 58, 239, 156, 115, 201, 218, 63, 187, 242, 127, 110, 65, 93, 208, 59, 253, 7, 109, 193, + 56, 104, 223, 170, 239, 80, 120, 16, 83, 102, 225, 250, 247, 14, 243, 46, 138, 170, 253, + 76, 234, 86, 93, 219, 55, 245, 96, 21, 84, 83, 253, 36, 231, 47, 173, 217, 184, 19, 227, + 47, 204, 207, 119, 26, 40, 76, 164, 251, 178, 144, 17, 127, 189, 34, 151, 201, 4, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -332,11 +333,11 @@ fn memory_op_circuit() { let bytes = Circuit::serialize_circuit(&circuit); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 146, 49, 14, 0, 32, 8, 3, 139, 192, 127, 240, 7, - 254, 255, 85, 198, 136, 9, 131, 155, 48, 216, 165, 76, 77, 57, 80, 0, 140, 45, 117, 111, - 238, 228, 179, 224, 174, 225, 110, 111, 234, 213, 185, 148, 156, 203, 121, 89, 86, 13, 215, - 126, 131, 43, 153, 187, 115, 40, 185, 62, 153, 3, 136, 83, 60, 30, 96, 2, 12, 235, 225, - 124, 14, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 146, 193, 13, 0, 32, 8, 3, 171, 192, 62, 184, 129, + 251, 79, 101, 140, 152, 96, 226, 79, 120, 216, 79, 121, 53, 229, 64, 0, 16, 150, 196, 188, + 154, 23, 155, 25, 119, 117, 115, 125, 83, 203, 206, 45, 193, 185, 20, 151, 165, 217, 112, + 245, 55, 184, 28, 185, 59, 185, 146, 243, 147, 201, 129, 216, 197, 143, 3, 12, 77, 66, 200, + 219, 15, 3, 0, 0, ]; assert_eq!(bytes, expected_serialization) diff --git a/noir/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs b/noir/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs index ecabd98b3b1..c7561298d4a 100644 --- a/noir/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs +++ b/noir/acvm-repo/acvm/src/compiler/optimizers/redundant_range.rs @@ -172,6 +172,7 @@ mod tests { public_parameters: PublicInputs::default(), return_values: PublicInputs::default(), assert_messages: Default::default(), + recursive: false, } } diff --git a/noir/acvm-repo/acvm_js/test/shared/addition.ts b/noir/acvm-repo/acvm_js/test/shared/addition.ts index 982b9b685ce..ae3a2e2c35b 100644 --- a/noir/acvm-repo/acvm_js/test/shared/addition.ts +++ b/noir/acvm-repo/acvm_js/test/shared/addition.ts @@ -2,11 +2,11 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `addition_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 187, 13, 192, 32, 12, 68, 249, 100, 32, 27, 219, 96, 119, 89, 37, 40, - 176, 255, 8, 17, 18, 5, 74, 202, 240, 154, 235, 158, 238, 238, 112, 206, 121, 247, 37, 206, 60, 103, 194, 63, 208, - 111, 116, 133, 197, 69, 144, 153, 91, 73, 13, 9, 47, 72, 86, 85, 128, 165, 102, 69, 69, 81, 185, 147, 18, 53, 101, 45, - 86, 173, 128, 33, 83, 195, 46, 70, 125, 202, 226, 190, 94, 16, 166, 103, 108, 13, 203, 151, 254, 245, 233, 224, 1, 1, - 52, 166, 127, 120, 1, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 144, 59, 18, 128, 32, 12, 68, 249, 120, 160, 132, 36, 144, 116, 94, 69, 70, + 184, 255, 17, 28, 29, 10, 70, 75, 121, 205, 118, 111, 118, 119, 115, 206, 121, 247, 37, 142, 220, 71, 194, 63, 208, + 47, 116, 133, 201, 69, 144, 153, 91, 73, 13, 9, 15, 72, 86, 85, 128, 165, 102, 69, 69, 81, 57, 147, 18, 53, 101, 45, + 86, 173, 128, 33, 83, 195, 46, 70, 125, 200, 226, 186, 94, 16, 134, 231, 222, 26, 166, 47, 253, 235, 211, 135, 11, 47, + 121, 122, 165, 121, 1, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ diff --git a/noir/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts b/noir/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts index faae98bcf47..d30413212c5 100644 --- a/noir/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts +++ b/noir/acvm-repo/acvm_js/test/shared/complex_foreign_call.ts @@ -2,12 +2,13 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `complex_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 65, 10, 132, 48, 12, 76, 218, 237, 174, 123, 242, 11, 130, 62, 160, 250, - 2, 255, 34, 222, 20, 61, 250, 124, 11, 78, 49, 4, 193, 131, 21, 52, 16, 210, 132, 105, 50, 77, 210, 140, 136, 152, 54, - 177, 65, 13, 206, 12, 95, 74, 196, 181, 176, 254, 154, 212, 156, 46, 151, 191, 139, 163, 121, 1, 71, 123, 3, 199, 184, - 15, 15, 157, 119, 202, 185, 36, 237, 159, 61, 248, 63, 159, 160, 46, 232, 23, 254, 15, 54, 67, 156, 96, 11, 213, 119, - 82, 248, 116, 179, 104, 188, 163, 125, 15, 89, 213, 253, 139, 154, 221, 52, 206, 67, 191, 88, 5, 213, 52, 75, 113, - 174, 96, 205, 201, 157, 24, 207, 197, 211, 157, 6, 50, 18, 233, 158, 72, 89, 1, 53, 215, 75, 175, 196, 4, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 83, 81, 10, 131, 48, 12, 125, 105, 215, 205, 125, 237, 10, 131, 237, 0, 221, + 78, 224, 93, 196, 63, 69, 63, 61, 190, 5, 95, 177, 6, 193, 15, 43, 104, 32, 164, 9, 175, 201, 107, 146, 22, 0, 4, 147, + 216, 160, 134, 103, 161, 159, 74, 196, 149, 180, 126, 159, 252, 36, 95, 46, 127, 20, 71, 115, 1, 142, 246, 0, 142, + 113, 31, 78, 58, 239, 156, 115, 201, 218, 63, 187, 242, 127, 110, 65, 93, 208, 59, 253, 7, 109, 193, 56, 104, 223, + 170, 239, 80, 120, 16, 83, 102, 225, 250, 247, 14, 243, 46, 138, 170, 253, 76, 234, 86, 93, 219, 55, 245, 96, 21, 84, + 83, 253, 36, 231, 47, 173, 217, 184, 19, 227, 47, 204, 207, 119, 26, 40, 76, 164, 251, 178, 144, 17, 127, 189, 34, + 151, 201, 4, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], diff --git a/noir/acvm-repo/acvm_js/test/shared/fixed_base_scalar_mul.ts b/noir/acvm-repo/acvm_js/test/shared/fixed_base_scalar_mul.ts index 0437bebc369..2f643578518 100644 --- a/noir/acvm-repo/acvm_js/test/shared/fixed_base_scalar_mul.ts +++ b/noir/acvm-repo/acvm_js/test/shared/fixed_base_scalar_mul.ts @@ -1,8 +1,8 @@ // See `fixed_base_scalar_mul_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 138, 91, 10, 0, 48, 12, 194, 178, 215, 215, 46, 189, 163, 175, 165, 10, 21, 36, - 10, 57, 192, 160, 146, 188, 226, 139, 78, 113, 69, 183, 190, 61, 111, 218, 182, 231, 124, 122, 8, 177, 65, 92, 0, 0, - 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 138, 91, 10, 0, 32, 12, 195, 226, 235, 203, 75, 123, 116, 39, 182, 99, 133, + 146, 22, 178, 128, 198, 207, 227, 22, 79, 180, 139, 35, 58, 245, 237, 121, 83, 182, 189, 204, 5, 167, 198, 147, 98, + 93, 0, 0, 0, ]); export const initialWitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], diff --git a/noir/acvm-repo/acvm_js/test/shared/foreign_call.ts b/noir/acvm-repo/acvm_js/test/shared/foreign_call.ts index 7a65f29117c..817356ccfc5 100644 --- a/noir/acvm-repo/acvm_js/test/shared/foreign_call.ts +++ b/noir/acvm-repo/acvm_js/test/shared/foreign_call.ts @@ -3,9 +3,9 @@ import { WitnessMap } from '@noir-lang/acvm_js'; // See `simple_brillig_foreign_call` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 143, 177, 10, 192, 32, 12, 68, 207, 148, 150, 118, 234, 175, 216, 63, 232, - 207, 116, 232, 210, 161, 136, 223, 175, 98, 132, 27, 212, 69, 31, 132, 28, 23, 8, 119, 59, 0, 131, 204, 66, 154, 41, - 222, 173, 219, 142, 113, 153, 121, 191, 44, 231, 21, 237, 144, 88, 43, 249, 11, 71, 156, 77, 245, 251, 249, 231, 119, - 189, 214, 204, 89, 187, 11, 25, 130, 54, 1, 36, 1, 124, 242, 107, 1, 0, 0, + 207, 116, 232, 226, 32, 226, 247, 171, 24, 225, 6, 113, 209, 7, 33, 199, 5, 194, 221, 9, 192, 160, 178, 145, 102, 154, + 247, 234, 182, 115, 60, 102, 221, 47, 203, 121, 69, 59, 20, 246, 78, 254, 198, 149, 231, 80, 253, 187, 248, 249, 48, + 106, 205, 220, 189, 187, 144, 33, 24, 144, 0, 93, 119, 243, 238, 108, 1, 0, 0, ]); export const initialWitnessMap: WitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000005'], diff --git a/noir/acvm-repo/acvm_js/test/shared/memory_op.ts b/noir/acvm-repo/acvm_js/test/shared/memory_op.ts index ce88f491893..8c21e00b4a7 100644 --- a/noir/acvm-repo/acvm_js/test/shared/memory_op.ts +++ b/noir/acvm-repo/acvm_js/test/shared/memory_op.ts @@ -1,9 +1,9 @@ // See `memory_op_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 146, 49, 14, 0, 32, 8, 3, 139, 192, 127, 240, 7, 254, 255, 85, 198, 136, 9, - 131, 155, 48, 216, 165, 76, 77, 57, 80, 0, 140, 45, 117, 111, 238, 228, 179, 224, 174, 225, 110, 111, 234, 213, 185, - 148, 156, 203, 121, 89, 86, 13, 215, 126, 131, 43, 153, 187, 115, 40, 185, 62, 153, 3, 136, 83, 60, 30, 96, 2, 12, - 235, 225, 124, 14, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 146, 193, 13, 0, 32, 8, 3, 171, 192, 62, 184, 129, 251, 79, 101, 140, 152, 96, + 226, 79, 120, 216, 79, 121, 53, 229, 64, 0, 16, 150, 196, 188, 154, 23, 155, 25, 119, 117, 115, 125, 83, 203, 206, 45, + 193, 185, 20, 151, 165, 217, 112, 245, 55, 184, 28, 185, 59, 185, 146, 243, 147, 201, 129, 216, 197, 143, 3, 12, 77, + 66, 200, 219, 15, 3, 0, 0, ]); export const initialWitnessMap = new Map([ diff --git a/noir/acvm-repo/acvm_js/test/shared/pedersen.ts b/noir/acvm-repo/acvm_js/test/shared/pedersen.ts index e35893fc355..2d5ce62b4c2 100644 --- a/noir/acvm-repo/acvm_js/test/shared/pedersen.ts +++ b/noir/acvm-repo/acvm_js/test/shared/pedersen.ts @@ -1,7 +1,7 @@ // See `pedersen_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 138, 9, 10, 0, 64, 8, 2, 103, 15, 232, 255, 31, 142, 138, 10, 34, 65, 84, 198, - 15, 28, 82, 145, 178, 182, 86, 191, 238, 183, 24, 131, 205, 79, 203, 0, 166, 242, 158, 93, 92, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 138, 9, 10, 0, 64, 8, 2, 103, 15, 232, 255, 31, 142, 138, 34, 34, 65, 84, 198, + 15, 28, 82, 145, 178, 182, 86, 191, 238, 183, 24, 131, 205, 79, 203, 0, 162, 119, 234, 237, 93, 0, 0, 0, ]); export const initialWitnessMap = new Map([[1, '0x0000000000000000000000000000000000000000000000000000000000000001']]); diff --git a/noir/acvm-repo/acvm_js/test/shared/schnorr_verify.ts b/noir/acvm-repo/acvm_js/test/shared/schnorr_verify.ts index 5716cbd30f8..92b0f4fb0b5 100644 --- a/noir/acvm-repo/acvm_js/test/shared/schnorr_verify.ts +++ b/noir/acvm-repo/acvm_js/test/shared/schnorr_verify.ts @@ -1,17 +1,17 @@ // See `schnorr_verify_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 210, 87, 78, 2, 1, 20, 134, 209, 177, 247, 222, 123, 71, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 221, 133, 251, 95, 130, 145, 27, 206, 36, 78, 50, 57, 16, 94, 200, 253, 191, 159, 36, 73, 134, 146, - 193, 19, 142, 243, 183, 255, 14, 179, 233, 247, 145, 254, 59, 217, 127, 71, 57, 198, 113, 78, 48, 125, 167, 56, 205, - 25, 206, 114, 142, 243, 92, 224, 34, 151, 184, 204, 21, 174, 114, 141, 235, 220, 224, 38, 183, 184, 205, 29, 238, 114, - 143, 251, 60, 224, 33, 143, 120, 204, 19, 158, 242, 140, 25, 158, 51, 203, 11, 230, 120, 201, 60, 175, 88, 224, 53, - 139, 188, 97, 137, 183, 44, 243, 142, 21, 222, 179, 202, 7, 214, 248, 200, 58, 159, 216, 224, 51, 155, 124, 97, 235, - 223, 142, 241, 188, 250, 222, 230, 27, 59, 124, 103, 151, 31, 236, 241, 147, 95, 252, 246, 57, 158, 104, 47, 186, 139, - 214, 162, 179, 104, 44, 250, 74, 219, 154, 242, 63, 162, 165, 232, 40, 26, 138, 126, 162, 157, 232, 38, 154, 137, 94, - 162, 149, 232, 36, 26, 137, 62, 162, 141, 232, 34, 154, 136, 30, 162, 133, 232, 32, 26, 136, 253, 99, 251, 195, 100, - 176, 121, 236, 29, 91, 159, 218, 56, 99, 219, 172, 77, 115, 182, 204, 219, 176, 96, 187, 162, 205, 74, 182, 42, 219, - 168, 98, 155, 170, 77, 106, 182, 168, 219, 160, 225, 246, 77, 55, 111, 185, 113, 219, 109, 59, 110, 218, 117, 203, - 158, 27, 166, 55, 75, 239, 150, 184, 101, 250, 252, 1, 55, 204, 92, 74, 220, 3, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 210, 233, 50, 66, 1, 24, 199, 225, 99, 223, 247, 125, 223, 146, 36, 73, 146, + 36, 73, 146, 132, 187, 112, 255, 151, 96, 244, 78, 79, 198, 153, 57, 243, 212, 244, 165, 121, 255, 191, 239, 36, 73, + 134, 146, 254, 19, 142, 243, 167, 247, 14, 179, 225, 247, 145, 222, 59, 217, 123, 71, 57, 198, 113, 78, 112, 240, 78, + 113, 154, 51, 156, 229, 28, 231, 185, 192, 69, 46, 113, 153, 43, 92, 229, 26, 215, 185, 193, 77, 110, 113, 155, 59, + 220, 229, 30, 247, 121, 192, 67, 30, 241, 152, 39, 76, 241, 148, 105, 158, 49, 195, 115, 102, 121, 193, 28, 47, 153, + 231, 21, 11, 188, 102, 145, 55, 44, 241, 150, 101, 222, 177, 194, 123, 86, 249, 192, 26, 31, 89, 231, 19, 27, 124, + 102, 243, 223, 142, 241, 188, 248, 222, 226, 43, 219, 124, 99, 135, 239, 236, 242, 131, 159, 252, 242, 57, 158, 104, + 47, 186, 139, 214, 162, 179, 104, 44, 250, 26, 180, 53, 229, 127, 68, 75, 209, 81, 52, 20, 253, 68, 59, 209, 77, 52, + 19, 189, 68, 43, 209, 73, 52, 18, 125, 68, 27, 209, 69, 52, 17, 61, 68, 11, 209, 65, 52, 16, 251, 199, 246, 135, 73, + 127, 243, 216, 59, 182, 78, 217, 56, 109, 219, 140, 77, 179, 182, 204, 217, 48, 111, 187, 130, 205, 138, 182, 42, 217, + 168, 108, 155, 138, 77, 170, 182, 168, 217, 160, 238, 246, 13, 55, 111, 186, 113, 203, 109, 219, 110, 218, 113, 203, + 174, 27, 14, 110, 54, 184, 91, 226, 150, 127, 207, 47, 78, 22, 245, 106, 221, 3, 0, 0, ]); export const initialWitnessMap = new Map([ diff --git a/noir/acvm-repo/brillig/src/opcodes.rs b/noir/acvm-repo/brillig/src/opcodes.rs index 9a6f11c463f..9304b82bfa1 100644 --- a/noir/acvm-repo/brillig/src/opcodes.rs +++ b/noir/acvm-repo/brillig/src/opcodes.rs @@ -104,6 +104,7 @@ pub enum BrilligOpcode { }, Const { destination: MemoryAddress, + bit_size: u32, value: Value, }, Return, diff --git a/noir/acvm-repo/brillig_vm/src/lib.rs b/noir/acvm-repo/brillig_vm/src/lib.rs index 0c90fcb1416..93093ab65f9 100644 --- a/noir/acvm-repo/brillig_vm/src/lib.rs +++ b/noir/acvm-repo/brillig_vm/src/lib.rs @@ -316,7 +316,7 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.call_stack.push(Value::from(self.program_counter)); self.set_program_counter(*location) } - Opcode::Const { destination, value } => { + Opcode::Const { destination, value, bit_size: _ } => { self.memory.write(*destination, *value); self.increment_program_counter() } @@ -737,17 +737,21 @@ mod tests { let start = [ // i = 0 - Opcode::Const { destination: r_i, value: 0u128.into() }, + Opcode::Const { destination: r_i, value: 0u128.into(), bit_size: 32 }, // len = memory.len() (approximation) - Opcode::Const { destination: r_len, value: Value::from(item_count as u128) }, + Opcode::Const { + destination: r_len, + value: Value::from(item_count as u128), + bit_size: 32, + }, // pointer = free_memory_ptr - Opcode::Const { destination: r_pointer, value: 4u128.into() }, + Opcode::Const { destination: r_pointer, value: 4u128.into(), bit_size: 32 }, ]; let loop_body = [ // *i = i Opcode::Store { destination_pointer: r_pointer, source: r_i }, // tmp = 1 - Opcode::Const { destination: r_tmp, value: 1u128.into() }, + Opcode::Const { destination: r_tmp, value: 1u128.into(), bit_size: 32 }, // i = i + 1 (tmp) Opcode::BinaryIntOp { destination: r_i, @@ -816,13 +820,17 @@ mod tests { let start = [ // sum = 0 - Opcode::Const { destination: r_sum, value: 0u128.into() }, + Opcode::Const { destination: r_sum, value: 0u128.into(), bit_size: 32 }, // i = 0 - Opcode::Const { destination: r_i, value: 0u128.into() }, + Opcode::Const { destination: r_i, value: 0u128.into(), bit_size: 32 }, // len = array.len() (approximation) - Opcode::Const { destination: r_len, value: Value::from(memory.len() as u128) }, + Opcode::Const { + destination: r_len, + value: Value::from(memory.len() as u128), + bit_size: 32, + }, // pointer = array_ptr - Opcode::Const { destination: r_pointer, value: 5u128.into() }, + Opcode::Const { destination: r_pointer, value: 5u128.into(), bit_size: 32 }, Opcode::CalldataCopy { destination_address: MemoryAddress(5), size: memory.len(), @@ -841,7 +849,7 @@ mod tests { bit_size, }, // tmp = 1 - Opcode::Const { destination: r_tmp, value: 1u128.into() }, + Opcode::Const { destination: r_tmp, value: 1u128.into(), bit_size: 32 }, // i = i + 1 (tmp) Opcode::BinaryIntOp { destination: r_i, @@ -908,11 +916,11 @@ mod tests { let start = [ // i = 0 - Opcode::Const { destination: r_i, value: 0u128.into() }, + Opcode::Const { destination: r_i, value: 0u128.into(), bit_size: 32 }, // len = size - Opcode::Const { destination: r_len, value: size.into() }, + Opcode::Const { destination: r_len, value: size.into(), bit_size: 32 }, // pointer = free_memory_ptr - Opcode::Const { destination: r_pointer, value: 4u128.into() }, + Opcode::Const { destination: r_pointer, value: 4u128.into(), bit_size: 32 }, // call recursive_fn Opcode::Call { location: 5, // Call after 'start' @@ -938,7 +946,7 @@ mod tests { // *i = i Opcode::Store { destination_pointer: r_pointer, source: r_i }, // tmp = 1 - Opcode::Const { destination: r_tmp, value: 1u128.into() }, + Opcode::Const { destination: r_tmp, value: 1u128.into(), bit_size: 32 }, // i = i + 1 (tmp) Opcode::BinaryIntOp { destination: r_i, @@ -1008,7 +1016,7 @@ mod tests { let double_program = vec![ // Load input address with value 5 - Opcode::Const { destination: r_input, value: Value::from(5u128) }, + Opcode::Const { destination: r_input, value: Value::from(5u128), bit_size: 32 }, // Call foreign function "double" with the input address Opcode::ForeignCall { function: "double".into(), @@ -1067,9 +1075,9 @@ mod tests { offset: 0, }, // input = 0 - Opcode::Const { destination: r_input, value: 2_usize.into() }, + Opcode::Const { destination: r_input, value: 2_usize.into(), bit_size: 32 }, // output = 0 - Opcode::Const { destination: r_output, value: 2_usize.into() }, + Opcode::Const { destination: r_output, value: 2_usize.into(), bit_size: 32 }, // *output = matrix_2x2_transpose(*input) Opcode::ForeignCall { function: "matrix_2x2_transpose".into(), @@ -1138,18 +1146,24 @@ mod tests { offset: 0, }, // input_pointer = 4 - Opcode::Const { destination: r_input_pointer, value: Value::from(4u128) }, + Opcode::Const { destination: r_input_pointer, value: Value::from(4u128), bit_size: 32 }, // input_size = input_string.len() (constant here) - Opcode::Const { destination: r_input_size, value: Value::from(input_string.len()) }, + Opcode::Const { + destination: r_input_size, + value: Value::from(input_string.len()), + bit_size: 32, + }, // output_pointer = 4 + input_size Opcode::Const { destination: r_output_pointer, value: Value::from(4 + input_string.len()), + bit_size: 32, }, // output_size = input_size * 2 Opcode::Const { destination: r_output_size, value: Value::from(input_string.len() * 2), + bit_size: 32, }, // output_pointer[0..output_size] = string_double(input_pointer[0...input_size]) Opcode::ForeignCall { @@ -1218,9 +1232,9 @@ mod tests { offset: 0, }, // input = 0 - Opcode::Const { destination: r_input, value: Value::from(2u128) }, + Opcode::Const { destination: r_input, value: Value::from(2u128), bit_size: 32 }, // output = 0 - Opcode::Const { destination: r_output, value: Value::from(6u128) }, + Opcode::Const { destination: r_output, value: Value::from(6u128), bit_size: 32 }, // *output = matrix_2x2_transpose(*input) Opcode::ForeignCall { function: "matrix_2x2_transpose".into(), @@ -1299,11 +1313,11 @@ mod tests { offset: 0, }, // input = 3 - Opcode::Const { destination: r_input_a, value: Value::from(3u128) }, + Opcode::Const { destination: r_input_a, value: Value::from(3u128), bit_size: 32 }, // input = 7 - Opcode::Const { destination: r_input_b, value: Value::from(7u128) }, + Opcode::Const { destination: r_input_b, value: Value::from(7u128), bit_size: 32 }, // output = 0 - Opcode::Const { destination: r_output, value: Value::from(0u128) }, + Opcode::Const { destination: r_output, value: Value::from(0u128), bit_size: 32 }, // *output = matrix_2x2_transpose(*input) Opcode::ForeignCall { function: "matrix_2x2_transpose".into(), diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index ae8adeb10ec..4051b8cebcd 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -85,10 +85,10 @@ impl<'block> BrilligBlock<'block> { self.convert_ssa_terminator(terminator_instruction, dfg); } - fn get_bit_size_from_ssa_type(typ: Type) -> u32 { + fn get_bit_size_from_ssa_type(typ: &Type) -> u32 { match typ { Type::Numeric(num_type) => match num_type { - NumericType::Signed { bit_size } | NumericType::Unsigned { bit_size } => bit_size, + NumericType::Signed { bit_size } | NumericType::Unsigned { bit_size } => *bit_size, NumericType::NativeField => FieldElement::max_num_bits(), }, _ => unreachable!("ICE bitwise not on a non numeric type"), @@ -322,7 +322,7 @@ impl<'block> BrilligBlock<'block> { dfg.instruction_results(instruction_id)[0], dfg, ); - let bit_size = Self::get_bit_size_from_ssa_type(dfg.type_of_value(*value)); + let bit_size = Self::get_bit_size_from_ssa_type(&dfg.type_of_value(*value)); self.brillig_context.not_instruction(condition_register, bit_size, result_register); } Instruction::Call { func, arguments } => match &dfg[*func] { @@ -499,7 +499,9 @@ impl<'block> BrilligBlock<'block> { BrilligVariable::Simple(..) => unreachable!("ICE: ToBits on non-array"), }; - let radix = self.brillig_context.make_constant(2_usize.into()); + let radix = self + .brillig_context + .make_constant(2_usize.into(), FieldElement::max_num_bits()); // Update the user-facing slice length self.brillig_context.mov_instruction(target_len, limb_count); @@ -596,6 +598,7 @@ impl<'block> BrilligBlock<'block> { self.brillig_context.const_instruction( right, FieldElement::from_be_bytes_reduce(&max.to_bytes_be()).into(), + FieldElement::max_num_bits(), ); let brillig_binary_op = BrilligBinaryOp::Integer { @@ -696,7 +699,7 @@ impl<'block> BrilligBlock<'block> { ) { let (size_as_register, should_deallocate_size) = match array_variable { BrilligVariable::BrilligArray(BrilligArray { size, .. }) => { - (self.brillig_context.make_constant(size.into()), true) + (self.brillig_context.make_usize_constant(size.into()), true) } BrilligVariable::BrilligVector(BrilligVector { size, .. }) => (size, false), _ => unreachable!("ICE: validate array index on non-array"), @@ -763,7 +766,7 @@ impl<'block> BrilligBlock<'block> { let (source_pointer, source_size_as_register) = match source_variable { BrilligVariable::BrilligArray(BrilligArray { size, pointer, rc: _ }) => { let source_size_register = self.brillig_context.allocate_register(); - self.brillig_context.const_instruction(source_size_register, size.into()); + self.brillig_context.usize_const(source_size_register, size.into()); (pointer, source_size_register) } BrilligVariable::BrilligVector(BrilligVector { size, pointer, rc: _ }) => { @@ -774,7 +777,7 @@ impl<'block> BrilligBlock<'block> { _ => unreachable!("ICE: array set on non-array"), }; - let one = self.brillig_context.make_constant(1_usize.into()); + let one = self.brillig_context.make_usize_constant(1_usize.into()); let condition = self.brillig_context.allocate_register(); self.brillig_context.binary_instruction( @@ -802,7 +805,7 @@ impl<'block> BrilligBlock<'block> { match destination_variable { BrilligVariable::BrilligArray(BrilligArray { rc: target_rc, .. }) => { - self.brillig_context.const_instruction(target_rc, 1_usize.into()); + self.brillig_context.usize_const(target_rc, 1_usize.into()); } BrilligVariable::BrilligVector(BrilligVector { size: target_size, @@ -810,7 +813,7 @@ impl<'block> BrilligBlock<'block> { .. }) => { self.brillig_context.mov_instruction(target_size, source_size_as_register); - self.brillig_context.const_instruction(target_rc, 1_usize.into()); + self.brillig_context.usize_const(target_rc, 1_usize.into()); } _ => unreachable!("ICE: array set on non-array"), } @@ -1022,7 +1025,7 @@ impl<'block> BrilligBlock<'block> { // https://github.com/noir-lang/noir/issues/1889#issuecomment-1668048587 let user_index = self.convert_ssa_register_value(arguments[2], dfg); - let converted_index = self.brillig_context.make_constant(element_size.into()); + let converted_index = self.brillig_context.make_usize_constant(element_size.into()); self.brillig_context.memory_op( converted_index, @@ -1065,7 +1068,7 @@ impl<'block> BrilligBlock<'block> { // https://github.com/noir-lang/noir/issues/1889#issuecomment-1668048587 let user_index = self.convert_ssa_register_value(arguments[2], dfg); - let converted_index = self.brillig_context.make_constant(element_size.into()); + let converted_index = self.brillig_context.make_usize_constant(element_size.into()); self.brillig_context.memory_op( converted_index, user_index, @@ -1158,7 +1161,7 @@ impl<'block> BrilligBlock<'block> { // converted to registers so we fetch from the cache. self.variables.get_allocation(self.function_context, value_id, dfg) } - Value::NumericConstant { constant, .. } => { + Value::NumericConstant { constant, typ } => { // Constants might have been converted previously or not, so we get or create and // (re)initialize the value inside. if let Some(variable) = self.variables.get_constant(value_id, dfg) { @@ -1168,7 +1171,11 @@ impl<'block> BrilligBlock<'block> { self.variables.allocate_constant(self.brillig_context, value_id, dfg); let register_index = new_variable.extract_register(); - self.brillig_context.const_instruction(register_index, (*constant).into()); + self.brillig_context.const_instruction( + register_index, + (*constant).into(), + Self::get_bit_size_from_ssa_type(typ), + ); new_variable } } @@ -1184,16 +1191,15 @@ impl<'block> BrilligBlock<'block> { BrilligVariable::BrilligArray(brillig_array) => { self.brillig_context .allocate_fixed_length_array(brillig_array.pointer, array.len()); - self.brillig_context - .const_instruction(brillig_array.rc, 1_usize.into()); + self.brillig_context.usize_const(brillig_array.rc, 1_usize.into()); brillig_array.pointer } BrilligVariable::BrilligVector(vector) => { - self.brillig_context.const_instruction(vector.size, array.len().into()); + self.brillig_context.usize_const(vector.size, array.len().into()); self.brillig_context .allocate_array_instruction(vector.pointer, vector.size); - self.brillig_context.const_instruction(vector.rc, 1_usize.into()); + self.brillig_context.usize_const(vector.rc, 1_usize.into()); vector.pointer } @@ -1205,7 +1211,8 @@ impl<'block> BrilligBlock<'block> { // Write the items // Allocate a register for the iterator - let iterator_register = self.brillig_context.make_constant(0_usize.into()); + let iterator_register = + self.brillig_context.make_usize_constant(0_usize.into()); for element_id in array.iter() { let element_variable = self.convert_ssa_value(*element_id, dfg); @@ -1263,7 +1270,7 @@ impl<'block> BrilligBlock<'block> { ); let array = variable.extract_array(); self.brillig_context.allocate_fixed_length_array(array.pointer, array.size); - self.brillig_context.const_instruction(array.rc, 1_usize.into()); + self.brillig_context.usize_const(array.rc, 1_usize.into()); variable } @@ -1280,7 +1287,7 @@ impl<'block> BrilligBlock<'block> { // The stack pointer will then be updated by the caller of this method // once the external call is resolved and the array size is known self.brillig_context.set_array_pointer(vector.pointer); - self.brillig_context.const_instruction(vector.rc, 1_usize.into()); + self.brillig_context.usize_const(vector.rc, 1_usize.into()); variable } @@ -1304,8 +1311,7 @@ impl<'block> BrilligBlock<'block> { match array_variable { BrilligVariable::BrilligArray(BrilligArray { size, .. }) => { - self.brillig_context - .const_instruction(result_register, (size / element_size).into()); + self.brillig_context.usize_const(result_register, (size / element_size).into()); } BrilligVariable::BrilligVector(BrilligVector { size, .. }) => { self.brillig_context.usize_op( diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs index 5ac2ecf06be..93c4b1a5042 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs @@ -1,5 +1,6 @@ -use acvm::acir::brillig::{ - BinaryFieldOp, BinaryIntOp, MemoryAddress, Opcode as BrilligOpcode, Value, +use acvm::{ + acir::brillig::{BinaryFieldOp, BinaryIntOp, MemoryAddress, Opcode as BrilligOpcode, Value}, + FieldElement, }; use crate::brillig::brillig_ir::artifact::GeneratedBrillig; @@ -24,7 +25,11 @@ pub(crate) fn directive_invert() -> GeneratedBrillig { // If the input is zero, then we jump to the stop opcode BrilligOpcode::JumpIfNot { condition: input, location: stop_location }, // Put value one in register (1) - BrilligOpcode::Const { destination: one_const, value: Value::from(1_usize) }, + BrilligOpcode::Const { + destination: one_const, + value: Value::from(1_usize), + bit_size: FieldElement::max_num_bits(), + }, // Divide 1 by the input, and set the result of the division into register (0) BrilligOpcode::BinaryFieldOp { op: BinaryFieldOp::Div, diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs index 981a16a01b2..3fed8ee91d9 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_slice_ops.rs @@ -20,7 +20,7 @@ impl<'block> BrilligBlock<'block> { ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); // We initialize the RC of the target vector to 1 - self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); + self.brillig_context.usize_const(target_vector.rc, 1_usize.into()); // Now we copy the source vector into the target vector self.brillig_context.copy_array_instruction( @@ -30,7 +30,7 @@ impl<'block> BrilligBlock<'block> { ); for (index, variable) in variables_to_insert.iter().enumerate() { - let target_index = self.brillig_context.make_constant(index.into()); + let target_index = self.brillig_context.make_usize_constant(index.into()); self.brillig_context.memory_op( target_index, source_vector.size, @@ -57,7 +57,7 @@ impl<'block> BrilligBlock<'block> { ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); // We initialize the RC of the target vector to 1 - self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); + self.brillig_context.usize_const(target_vector.rc, 1_usize.into()); // Now we offset the target pointer by variables_to_insert.len() let destination_copy_pointer = self.brillig_context.allocate_register(); @@ -77,7 +77,7 @@ impl<'block> BrilligBlock<'block> { // Then we write the items to insert at the start for (index, variable) in variables_to_insert.iter().enumerate() { - let target_index = self.brillig_context.make_constant(index.into()); + let target_index = self.brillig_context.make_usize_constant(index.into()); self.store_variable_in_array(target_vector.pointer, target_index, *variable); self.brillig_context.deallocate_register(target_index); } @@ -100,7 +100,7 @@ impl<'block> BrilligBlock<'block> { ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); // We initialize the RC of the target vector to 1 - self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); + self.brillig_context.usize_const(target_vector.rc, 1_usize.into()); // Now we offset the source pointer by removed_items.len() let source_copy_pointer = self.brillig_context.allocate_register(); @@ -119,7 +119,7 @@ impl<'block> BrilligBlock<'block> { ); for (index, variable) in removed_items.iter().enumerate() { - let target_index = self.brillig_context.make_constant(index.into()); + let target_index = self.brillig_context.make_usize_constant(index.into()); self.retrieve_variable_from_array(source_vector.pointer, target_index, *variable); self.brillig_context.deallocate_register(target_index); } @@ -142,7 +142,7 @@ impl<'block> BrilligBlock<'block> { ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); // We initialize the RC of the target vector to 1 - self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); + self.brillig_context.usize_const(target_vector.rc, 1_usize.into()); // Now we copy all elements except the last items into the target vector self.brillig_context.copy_array_instruction( @@ -152,7 +152,7 @@ impl<'block> BrilligBlock<'block> { ); for (index, variable) in removed_items.iter().enumerate() { - let target_index = self.brillig_context.make_constant(index.into()); + let target_index = self.brillig_context.make_usize_constant(index.into()); self.brillig_context.memory_op( target_index, target_vector.size, @@ -180,7 +180,7 @@ impl<'block> BrilligBlock<'block> { ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); // We initialize the RC of the target vector to 1 - self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); + self.brillig_context.usize_const(target_vector.rc, 1_usize.into()); // Copy the elements to the left of the index self.brillig_context.copy_array_instruction( @@ -225,7 +225,7 @@ impl<'block> BrilligBlock<'block> { // Write the items to insert starting at the index for (subitem_index, variable) in items.iter().enumerate() { - let target_index = self.brillig_context.make_constant(subitem_index.into()); + let target_index = self.brillig_context.make_usize_constant(subitem_index.into()); self.brillig_context.memory_op(target_index, index, target_index, BinaryIntOp::Add); self.store_variable_in_array(target_vector.pointer, target_index, *variable); self.brillig_context.deallocate_register(target_index); @@ -252,7 +252,7 @@ impl<'block> BrilligBlock<'block> { ); self.brillig_context.allocate_array_instruction(target_vector.pointer, target_vector.size); // We initialize the RC of the target vector to 1 - self.brillig_context.const_instruction(target_vector.rc, 1_usize.into()); + self.brillig_context.usize_const(target_vector.rc, 1_usize.into()); // Copy the elements to the left of the index self.brillig_context.copy_array_instruction( @@ -298,7 +298,7 @@ impl<'block> BrilligBlock<'block> { // Get the removed items for (subitem_index, variable) in removed_items.iter().enumerate() { - let target_index = self.brillig_context.make_constant(subitem_index.into()); + let target_index = self.brillig_context.make_usize_constant(subitem_index.into()); self.brillig_context.memory_op(target_index, index, target_index, BinaryIntOp::Add); self.retrieve_variable_from_array(source_vector.pointer, target_index, *variable); self.brillig_context.deallocate_register(target_index); diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index b094ff9c4c0..70aeff1e5d7 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -41,7 +41,7 @@ pub(crate) const BRILLIG_INTEGER_ARITHMETIC_BIT_SIZE: u32 = 127; /// 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 /// memory has 2^64 memory slots. -pub(crate) const BRILLIG_MEMORY_ADDRESSING_BIT_SIZE: u32 = 64; +pub(crate) const BRILLIG_MEMORY_ADDRESSING_BIT_SIZE: u32 = 32; // Registers reserved in runtime for special purposes. pub(crate) enum ReservedRegisters { @@ -131,7 +131,7 @@ impl BrilligContext { size: usize, ) { // debug_show handled by allocate_array_instruction - let size_register = self.make_constant(size.into()); + let size_register = self.make_usize_constant(size.into()); self.allocate_array_instruction(pointer_register, size_register); self.deallocate_register(size_register); } @@ -174,7 +174,7 @@ impl BrilligContext { ) { self.debug_show.allocate_instruction(pointer_register); // A variable can be stored in up to three values, so we reserve three values for that. - let size_register = self.make_constant(size.into()); + let size_register = self.make_usize_constant(size.into()); self.push_opcode(BrilligOpcode::Mov { destination: pointer_register, source: ReservedRegisters::stack_pointer(), @@ -286,7 +286,7 @@ impl BrilligContext { where F: FnOnce(&mut BrilligContext, MemoryAddress), { - let iterator_register = self.make_constant(0_u128.into()); + let iterator_register = self.make_usize_constant(0_u128.into()); let (loop_section, loop_label) = self.reserve_next_section_label(); self.enter_section(loop_section); @@ -529,9 +529,18 @@ impl BrilligContext { } /// Stores the value of `constant` in the `result` register - pub(crate) fn const_instruction(&mut self, result: MemoryAddress, constant: Value) { + pub(crate) fn const_instruction( + &mut self, + result: MemoryAddress, + constant: Value, + bit_size: u32, + ) { self.debug_show.const_instruction(result, constant); - self.push_opcode(BrilligOpcode::Const { destination: result, value: constant }); + self.push_opcode(BrilligOpcode::Const { destination: result, value: constant, bit_size }); + } + + pub(crate) fn usize_const(&mut self, result: MemoryAddress, constant: Value) { + self.const_instruction(result, constant, BRILLIG_MEMORY_ADDRESSING_BIT_SIZE); } /// Processes a not instruction. @@ -548,7 +557,7 @@ impl BrilligContext { // Compile !x as ((-1) - x) let u_max = FieldElement::from(2_i128).pow(&FieldElement::from(bit_size as i128)) - FieldElement::one(); - let max = self.make_constant(Value::from(u_max)); + let max = self.make_constant(Value::from(u_max), bit_size); let opcode = BrilligOpcode::BinaryIntOp { destination: result, op: BinaryIntOp::Sub, @@ -704,7 +713,7 @@ impl BrilligContext { // The brillig VM performs all arithmetic operations modulo 2**bit_size // So to truncate any value to a target bit size we can just issue a no-op arithmetic operation // With bit size equal to target_bit_size - let zero_register = self.make_constant(Value::from(FieldElement::zero())); + let zero_register = self.make_constant(Value::from(FieldElement::zero()), bit_size); self.binary_instruction( value_to_truncate, zero_register, @@ -721,9 +730,16 @@ impl BrilligContext { } /// Returns a register which holds the value of a constant - pub(crate) fn make_constant(&mut self, constant: Value) -> MemoryAddress { + pub(crate) fn make_constant(&mut self, constant: Value, bit_size: u32) -> MemoryAddress { + let register = self.allocate_register(); + self.const_instruction(register, constant, bit_size); + register + } + + /// Returns a register which holds the value of an usize constant + pub(crate) fn make_usize_constant(&mut self, constant: Value) -> MemoryAddress { let register = self.allocate_register(); - self.const_instruction(register, constant); + self.usize_const(register, constant); register } @@ -856,7 +872,7 @@ impl BrilligContext { op: BinaryIntOp, constant: usize, ) { - let const_register = self.make_constant(Value::from(constant)); + let const_register = self.make_usize_constant(Value::from(constant)); self.memory_op(operand, const_register, destination, op); // Mark as no longer used for this purpose, frees for reuse self.deallocate_register(const_register); @@ -926,7 +942,7 @@ impl BrilligContext { /// Utility method to transform a HeapArray to a HeapVector by making a runtime constant with the size. pub(crate) fn array_to_vector(&mut self, array: &BrilligArray) -> BrilligVector { - let size_register = self.make_constant(array.size.into()); + let size_register = self.make_usize_constant(array.size.into()); BrilligVector { size: size_register, pointer: array.pointer, rc: array.rc } } @@ -947,7 +963,7 @@ impl BrilligContext { big_endian: bool, ) { self.mov_instruction(target_vector.size, limb_count); - self.const_instruction(target_vector.rc, 1_usize.into()); + self.usize_const(target_vector.rc, 1_usize.into()); self.allocate_array_instruction(target_vector.pointer, target_vector.size); let shifted_register = self.allocate_register(); @@ -1148,12 +1164,12 @@ pub(crate) mod tests { let mut context = BrilligContext::new(true); let r_stack = ReservedRegisters::stack_pointer(); // Start stack pointer at 0 - context.const_instruction(r_stack, Value::from(ReservedRegisters::len() + 3)); + context.usize_const(r_stack, Value::from(ReservedRegisters::len() + 3)); let r_input_size = MemoryAddress::from(ReservedRegisters::len()); let r_array_ptr = MemoryAddress::from(ReservedRegisters::len() + 1); let r_output_size = MemoryAddress::from(ReservedRegisters::len() + 2); let r_equality = MemoryAddress::from(ReservedRegisters::len() + 3); - context.const_instruction(r_input_size, Value::from(12_usize)); + context.usize_const(r_input_size, Value::from(12_usize)); // copy our stack frame to r_array_ptr context.mov_instruction(r_array_ptr, r_stack); context.foreign_call_instruction( diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs index b9d95788b80..fc4ac36d7fd 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/entry_point.rs @@ -3,7 +3,7 @@ use super::{ brillig_variable::{BrilligArray, BrilligVariable}, debug_show::DebugShow, registers::BrilligRegistersContext, - BrilligContext, ReservedRegisters, + BrilligContext, ReservedRegisters, BRILLIG_MEMORY_ADDRESSING_BIT_SIZE, }; use acvm::acir::brillig::{MemoryAddress, Opcode as BrilligOpcode}; @@ -48,6 +48,7 @@ impl BrilligContext { self.push_opcode(BrilligOpcode::Const { destination: ReservedRegisters::stack_pointer(), value: (MAX_STACK_SIZE + calldata_size + return_data_size).into(), + bit_size: BRILLIG_MEMORY_ADDRESSING_BIT_SIZE, }); // Copy calldata @@ -72,8 +73,8 @@ impl BrilligContext { } BrilligParameter::Array(_, _) => { let pointer_to_the_array_in_calldata = - self.make_constant(current_calldata_pointer.into()); - let rc_register = self.make_constant(1_usize.into()); + self.make_usize_constant(current_calldata_pointer.into()); + let rc_register = self.make_usize_constant(1_usize.into()); let flattened_size = BrilligContext::flattened_size(argument); let var = BrilligVariable::BrilligArray(BrilligArray { pointer: pointer_to_the_array_in_calldata, @@ -158,10 +159,10 @@ impl BrilligContext { for (subitem_index, subitem) in item_type.iter().enumerate() { let source_index = - self.make_constant((source_item_base_index + source_offset).into()); + self.make_usize_constant((source_item_base_index + source_offset).into()); let target_index = - self.make_constant((target_item_base_index + subitem_index).into()); + self.make_usize_constant((target_item_base_index + subitem_index).into()); match subitem { BrilligParameter::Simple => { @@ -196,7 +197,7 @@ impl BrilligContext { ); let reference = self.allocate_register(); let rc = self.allocate_register(); - self.const_instruction(rc, 1_usize.into()); + self.usize_const(rc, 1_usize.into()); self.allocate_array_reference_instruction(reference); let array_variable = BrilligVariable::BrilligArray(BrilligArray { @@ -280,7 +281,7 @@ impl BrilligContext { } BrilligParameter::Array(item_type, item_count) => { let returned_pointer = returned_variable.extract_array().pointer; - let pointer_to_return_data = self.make_constant(return_data_index.into()); + let pointer_to_return_data = self.make_usize_constant(return_data_index.into()); self.flatten_array( item_type, @@ -324,9 +325,9 @@ impl BrilligContext { for (subitem_index, subitem) in item_type.iter().enumerate() { let source_index = - self.make_constant((source_item_base_index + subitem_index).into()); + self.make_usize_constant((source_item_base_index + subitem_index).into()); let target_index = - self.make_constant((target_item_base_index + target_offset).into()); + self.make_usize_constant((target_item_base_index + target_offset).into()); match subitem { BrilligParameter::Simple => { @@ -405,7 +406,7 @@ impl BrilligContext { self.deallocate_register(movement_register); } else { - let item_count = self.make_constant((item_count * item_type.len()).into()); + let item_count = self.make_usize_constant((item_count * item_type.len()).into()); self.copy_array_instruction( deflattened_array_pointer, flattened_array_pointer, diff --git a/noir/tooling/debugger/src/context.rs b/noir/tooling/debugger/src/context.rs index 8e5c1dacf2c..0231158ed28 100644 --- a/noir/tooling/debugger/src/context.rs +++ b/noir/tooling/debugger/src/context.rs @@ -459,6 +459,7 @@ mod tests { BrilligOpcode::Const { destination: MemoryAddress::from(1), value: Value::from(fe_0), + bit_size: 32, }, BrilligOpcode::ForeignCall { function: "clear_mock".into(),