From bbfa3374d20b44c49870e21c61cbb2ab5f7ae117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Wed, 7 Feb 2024 15:05:39 +0100 Subject: [PATCH] feat: Allow nested arrays and vectors in Brillig foreign calls (#4478) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR mirrors the changes of https://github.com/AztecProtocol/aztec-packages/pull/4404 to make them easier to merge --------- Co-authored-by: Gustavo Giráldez --- avm-transpiler/src/transpile.rs | 2 +- .../dsl/acir_format/serde/acir.hpp | 1332 ++++++++++------- noir/acvm-repo/acir/codegen/acir.cpp | 1256 +++++++++------- .../acir/src/circuit/black_box_functions.rs | 2 +- noir/acvm-repo/acir/src/circuit/brillig.rs | 4 +- noir/acvm-repo/acir/src/lib.rs | 6 +- .../acir/tests/test_program_serialization.rs | 105 +- noir/acvm-repo/acvm/src/pwg/brillig.rs | 15 +- noir/acvm-repo/acvm/src/pwg/mod.rs | 16 +- noir/acvm-repo/acvm/tests/solver.rs | 13 + .../acvm-repo/acvm_js/test/shared/addition.ts | 10 +- .../test/shared/complex_foreign_call.ts | 14 +- .../test/shared/fixed_base_scalar_mul.ts | 6 +- .../acvm_js/test/shared/foreign_call.ts | 8 +- .../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/lib.rs | 4 +- noir/acvm-repo/brillig/src/opcodes.rs | 26 + noir/acvm-repo/brillig_vm/src/lib.rs | 342 ++++- .../src/brillig/brillig_gen/brillig_block.rs | 14 +- .../noirc_evaluator/src/brillig/brillig_ir.rs | 12 +- .../brillig/brillig_ir/brillig_variable.rs | 19 +- .../src/brillig/brillig_ir/debug_show.rs | 2 +- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 2 +- .../execution_success/debug_logs/src/main.nr | 6 + noir/tooling/debugger/src/context.rs | 4 +- 27 files changed, 2031 insertions(+), 1225 deletions(-) diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index 4a9da4b8f65..62dceb654c6 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -253,7 +253,7 @@ pub fn brillig_to_avm(brillig: &Brillig) -> Vec { ..Default::default() }); }, - BrilligOpcode::ForeignCall { function, destinations, inputs } => { + BrilligOpcode::ForeignCall { function, destinations, inputs, destination_value_types:_, input_value_types:_ } => { handle_foreign_call(&mut avm_instrs, function, destinations, inputs); }, _ => panic!( 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 5d9a5b6a5a6..da1c0ddb68a 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -5,65 +5,172 @@ namespace Circuit { -struct Witness { - uint32_t value; +struct BinaryFieldOp { - friend bool operator==(const Witness&, const Witness&); - std::vector bincodeSerialize() const; - static Witness bincodeDeserialize(std::vector); -}; + struct Add { + friend bool operator==(const Add&, const Add&); + std::vector bincodeSerialize() const; + static Add bincodeDeserialize(std::vector); + }; -struct FunctionInput { - Circuit::Witness witness; - uint32_t num_bits; + struct Sub { + friend bool operator==(const Sub&, const Sub&); + std::vector bincodeSerialize() const; + static Sub bincodeDeserialize(std::vector); + }; - friend bool operator==(const FunctionInput&, const FunctionInput&); + struct Mul { + friend bool operator==(const Mul&, const Mul&); + std::vector bincodeSerialize() const; + static Mul bincodeDeserialize(std::vector); + }; + + struct Div { + friend bool operator==(const Div&, const Div&); + std::vector bincodeSerialize() const; + static Div bincodeDeserialize(std::vector); + }; + + struct Equals { + friend bool operator==(const Equals&, const Equals&); + std::vector bincodeSerialize() const; + static Equals bincodeDeserialize(std::vector); + }; + + std::variant value; + + friend bool operator==(const BinaryFieldOp&, const BinaryFieldOp&); std::vector bincodeSerialize() const; - static FunctionInput bincodeDeserialize(std::vector); + static BinaryFieldOp bincodeDeserialize(std::vector); }; -struct BlackBoxFuncCall { +struct BinaryIntOp { - struct AND { - Circuit::FunctionInput lhs; - Circuit::FunctionInput rhs; - Circuit::Witness output; + struct Add { + friend bool operator==(const Add&, const Add&); + std::vector bincodeSerialize() const; + static Add bincodeDeserialize(std::vector); + }; - friend bool operator==(const AND&, const AND&); + struct Sub { + friend bool operator==(const Sub&, const Sub&); std::vector bincodeSerialize() const; - static AND bincodeDeserialize(std::vector); + static Sub bincodeDeserialize(std::vector); }; - struct XOR { - Circuit::FunctionInput lhs; - Circuit::FunctionInput rhs; - Circuit::Witness output; + struct Mul { + friend bool operator==(const Mul&, const Mul&); + std::vector bincodeSerialize() const; + static Mul bincodeDeserialize(std::vector); + }; - friend bool operator==(const XOR&, const XOR&); + struct SignedDiv { + friend bool operator==(const SignedDiv&, const SignedDiv&); std::vector bincodeSerialize() const; - static XOR bincodeDeserialize(std::vector); + static SignedDiv bincodeDeserialize(std::vector); }; - struct RANGE { - Circuit::FunctionInput input; + struct UnsignedDiv { + friend bool operator==(const UnsignedDiv&, const UnsignedDiv&); + std::vector bincodeSerialize() const; + static UnsignedDiv bincodeDeserialize(std::vector); + }; - friend bool operator==(const RANGE&, const RANGE&); + struct Equals { + friend bool operator==(const Equals&, const Equals&); std::vector bincodeSerialize() const; - static RANGE bincodeDeserialize(std::vector); + static Equals bincodeDeserialize(std::vector); }; - struct SHA256 { - std::vector inputs; - std::vector outputs; + struct LessThan { + friend bool operator==(const LessThan&, const LessThan&); + std::vector bincodeSerialize() const; + static LessThan bincodeDeserialize(std::vector); + }; - friend bool operator==(const SHA256&, const SHA256&); + struct LessThanEquals { + friend bool operator==(const LessThanEquals&, const LessThanEquals&); std::vector bincodeSerialize() const; - static SHA256 bincodeDeserialize(std::vector); + static LessThanEquals bincodeDeserialize(std::vector); + }; + + struct And { + friend bool operator==(const And&, const And&); + std::vector bincodeSerialize() const; + static And bincodeDeserialize(std::vector); + }; + + struct Or { + friend bool operator==(const Or&, const Or&); + std::vector bincodeSerialize() const; + static Or bincodeDeserialize(std::vector); + }; + + struct Xor { + friend bool operator==(const Xor&, const Xor&); + std::vector bincodeSerialize() const; + static Xor bincodeDeserialize(std::vector); + }; + + struct Shl { + friend bool operator==(const Shl&, const Shl&); + std::vector bincodeSerialize() const; + static Shl bincodeDeserialize(std::vector); + }; + + struct Shr { + friend bool operator==(const Shr&, const Shr&); + std::vector bincodeSerialize() const; + static Shr bincodeDeserialize(std::vector); + }; + + std::variant value; + + friend bool operator==(const BinaryIntOp&, const BinaryIntOp&); + std::vector bincodeSerialize() const; + static BinaryIntOp bincodeDeserialize(std::vector); +}; + +struct MemoryAddress { + uint64_t value; + + friend bool operator==(const MemoryAddress&, const MemoryAddress&); + std::vector bincodeSerialize() const; + static MemoryAddress bincodeDeserialize(std::vector); +}; + +struct HeapArray { + Circuit::MemoryAddress pointer; + uint64_t size; + + friend bool operator==(const HeapArray&, const HeapArray&); + std::vector bincodeSerialize() const; + static HeapArray bincodeDeserialize(std::vector); +}; + +struct HeapVector { + Circuit::MemoryAddress pointer; + Circuit::MemoryAddress size; + + friend bool operator==(const HeapVector&, const HeapVector&); + std::vector bincodeSerialize() const; + static HeapVector bincodeDeserialize(std::vector); +}; + +struct BlackBoxOp { + + struct Sha256 { + Circuit::HeapVector message; + Circuit::HeapArray output; + + friend bool operator==(const Sha256&, const Sha256&); + std::vector bincodeSerialize() const; + static Sha256 bincodeDeserialize(std::vector); }; struct Blake2s { - std::vector inputs; - std::vector outputs; + Circuit::HeapVector message; + Circuit::HeapArray output; friend bool operator==(const Blake2s&, const Blake2s&); std::vector bincodeSerialize() const; @@ -71,52 +178,38 @@ struct BlackBoxFuncCall { }; struct Blake3 { - std::vector inputs; - std::vector outputs; + Circuit::HeapVector message; + Circuit::HeapArray output; friend bool operator==(const Blake3&, const Blake3&); std::vector bincodeSerialize() const; static Blake3 bincodeDeserialize(std::vector); }; - struct SchnorrVerify { - Circuit::FunctionInput public_key_x; - Circuit::FunctionInput public_key_y; - std::vector signature; - std::vector message; - Circuit::Witness output; - - friend bool operator==(const SchnorrVerify&, const SchnorrVerify&); - std::vector bincodeSerialize() const; - static SchnorrVerify bincodeDeserialize(std::vector); - }; - - struct PedersenCommitment { - std::vector inputs; - uint32_t domain_separator; - std::array outputs; + struct Keccak256 { + Circuit::HeapVector message; + Circuit::HeapArray output; - friend bool operator==(const PedersenCommitment&, const PedersenCommitment&); + friend bool operator==(const Keccak256&, const Keccak256&); std::vector bincodeSerialize() const; - static PedersenCommitment bincodeDeserialize(std::vector); + static Keccak256 bincodeDeserialize(std::vector); }; - struct PedersenHash { - std::vector inputs; - uint32_t domain_separator; - Circuit::Witness output; + struct Keccakf1600 { + Circuit::HeapVector message; + Circuit::HeapArray output; - friend bool operator==(const PedersenHash&, const PedersenHash&); + friend bool operator==(const Keccakf1600&, const Keccakf1600&); std::vector bincodeSerialize() const; - static PedersenHash bincodeDeserialize(std::vector); + static Keccakf1600 bincodeDeserialize(std::vector); }; struct EcdsaSecp256k1 { - std::vector public_key_x; - std::vector public_key_y; - std::vector signature; - std::vector hashed_message; - Circuit::Witness output; + Circuit::HeapVector hashed_msg; + Circuit::HeapArray public_key_x; + Circuit::HeapArray public_key_y; + Circuit::HeapArray signature; + Circuit::MemoryAddress result; friend bool operator==(const EcdsaSecp256k1&, const EcdsaSecp256k1&); std::vector bincodeSerialize() const; @@ -124,82 +217,75 @@ struct BlackBoxFuncCall { }; struct EcdsaSecp256r1 { - std::vector public_key_x; - std::vector public_key_y; - std::vector signature; - std::vector hashed_message; - Circuit::Witness output; + Circuit::HeapVector hashed_msg; + Circuit::HeapArray public_key_x; + Circuit::HeapArray public_key_y; + Circuit::HeapArray signature; + Circuit::MemoryAddress result; friend bool operator==(const EcdsaSecp256r1&, const EcdsaSecp256r1&); std::vector bincodeSerialize() const; static EcdsaSecp256r1 bincodeDeserialize(std::vector); }; - struct FixedBaseScalarMul { - Circuit::FunctionInput low; - Circuit::FunctionInput high; - std::array outputs; - - friend bool operator==(const FixedBaseScalarMul&, const FixedBaseScalarMul&); - std::vector bincodeSerialize() const; - static FixedBaseScalarMul bincodeDeserialize(std::vector); - }; - - struct EmbeddedCurveAdd { - Circuit::FunctionInput input1_x; - Circuit::FunctionInput input1_y; - Circuit::FunctionInput input2_x; - Circuit::FunctionInput input2_y; - std::array outputs; + struct SchnorrVerify { + Circuit::MemoryAddress public_key_x; + Circuit::MemoryAddress public_key_y; + Circuit::HeapVector message; + Circuit::HeapVector signature; + Circuit::MemoryAddress result; - friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); + friend bool operator==(const SchnorrVerify&, const SchnorrVerify&); std::vector bincodeSerialize() const; - static EmbeddedCurveAdd bincodeDeserialize(std::vector); + static SchnorrVerify bincodeDeserialize(std::vector); }; - struct Keccak256 { - std::vector inputs; - std::vector outputs; + struct PedersenCommitment { + Circuit::HeapVector inputs; + Circuit::MemoryAddress domain_separator; + Circuit::HeapArray output; - friend bool operator==(const Keccak256&, const Keccak256&); + friend bool operator==(const PedersenCommitment&, const PedersenCommitment&); std::vector bincodeSerialize() const; - static Keccak256 bincodeDeserialize(std::vector); + static PedersenCommitment bincodeDeserialize(std::vector); }; - struct Keccak256VariableLength { - std::vector inputs; - Circuit::FunctionInput var_message_size; - std::vector outputs; + struct PedersenHash { + Circuit::HeapVector inputs; + Circuit::MemoryAddress domain_separator; + Circuit::MemoryAddress output; - friend bool operator==(const Keccak256VariableLength&, const Keccak256VariableLength&); + friend bool operator==(const PedersenHash&, const PedersenHash&); std::vector bincodeSerialize() const; - static Keccak256VariableLength bincodeDeserialize(std::vector); + static PedersenHash bincodeDeserialize(std::vector); }; - struct Keccakf1600 { - std::vector inputs; - std::vector outputs; + struct FixedBaseScalarMul { + Circuit::MemoryAddress low; + Circuit::MemoryAddress high; + Circuit::HeapArray result; - friend bool operator==(const Keccakf1600&, const Keccakf1600&); + friend bool operator==(const FixedBaseScalarMul&, const FixedBaseScalarMul&); std::vector bincodeSerialize() const; - static Keccakf1600 bincodeDeserialize(std::vector); + static FixedBaseScalarMul bincodeDeserialize(std::vector); }; - struct RecursiveAggregation { - std::vector verification_key; - std::vector proof; - std::vector public_inputs; - Circuit::FunctionInput key_hash; + struct EmbeddedCurveAdd { + Circuit::MemoryAddress input1_x; + Circuit::MemoryAddress input1_y; + Circuit::MemoryAddress input2_x; + Circuit::MemoryAddress input2_y; + Circuit::HeapArray result; - friend bool operator==(const RecursiveAggregation&, const RecursiveAggregation&); + friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); std::vector bincodeSerialize() const; - static RecursiveAggregation bincodeDeserialize(std::vector); + static EmbeddedCurveAdd bincodeDeserialize(std::vector); }; struct BigIntAdd { - uint32_t lhs; - uint32_t rhs; - uint32_t output; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + Circuit::MemoryAddress output; friend bool operator==(const BigIntAdd&, const BigIntAdd&); std::vector bincodeSerialize() const; @@ -207,9 +293,9 @@ struct BlackBoxFuncCall { }; struct BigIntSub { - uint32_t lhs; - uint32_t rhs; - uint32_t output; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + Circuit::MemoryAddress output; friend bool operator==(const BigIntSub&, const BigIntSub&); std::vector bincodeSerialize() const; @@ -217,9 +303,9 @@ struct BlackBoxFuncCall { }; struct BigIntMul { - uint32_t lhs; - uint32_t rhs; - uint32_t output; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + Circuit::MemoryAddress output; friend bool operator==(const BigIntMul&, const BigIntMul&); std::vector bincodeSerialize() const; @@ -227,9 +313,9 @@ struct BlackBoxFuncCall { }; struct BigIntDiv { - uint32_t lhs; - uint32_t rhs; - uint32_t output; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + Circuit::MemoryAddress output; friend bool operator==(const BigIntDiv&, const BigIntDiv&); std::vector bincodeSerialize() const; @@ -237,9 +323,9 @@ struct BlackBoxFuncCall { }; struct BigIntFromLeBytes { - std::vector inputs; - std::vector modulus; - uint32_t output; + Circuit::HeapVector inputs; + Circuit::HeapVector modulus; + Circuit::MemoryAddress output; friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); std::vector bincodeSerialize() const; @@ -247,8 +333,8 @@ struct BlackBoxFuncCall { }; struct BigIntToLeBytes { - uint32_t input; - std::vector outputs; + Circuit::MemoryAddress input; + Circuit::HeapVector output; friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); std::vector bincodeSerialize() const; @@ -256,9 +342,9 @@ struct BlackBoxFuncCall { }; struct Poseidon2Permutation { - std::vector inputs; - std::vector outputs; - uint32_t len; + Circuit::HeapVector message; + Circuit::HeapArray output; + Circuit::MemoryAddress len; friend bool operator==(const Poseidon2Permutation&, const Poseidon2Permutation&); std::vector bincodeSerialize() const; @@ -266,32 +352,27 @@ struct BlackBoxFuncCall { }; struct Sha256Compression { - std::vector inputs; - std::vector hash_values; - std::vector outputs; + Circuit::HeapVector input; + Circuit::HeapVector hash_values; + Circuit::HeapArray output; friend bool operator==(const Sha256Compression&, const Sha256Compression&); std::vector bincodeSerialize() const; static Sha256Compression bincodeDeserialize(std::vector); }; - std::variant value; - friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&); - std::vector bincodeSerialize() const; - static BlackBoxFuncCall bincodeDeserialize(std::vector); -}; - -struct BlockId { - uint32_t value; - - friend bool operator==(const BlockId&, const BlockId&); - std::vector bincodeSerialize() const; - static BlockId bincodeDeserialize(std::vector); -}; - -struct Expression { - std::vector> mul_terms; - std::vector> linear_combinations; - std::string q_c; - - friend bool operator==(const Expression&, const Expression&); + friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); std::vector bincodeSerialize() const; - static Expression bincodeDeserialize(std::vector); + static BlackBoxOp bincodeDeserialize(std::vector); }; -struct BrilligInputs { +struct HeapValueType; - struct Single { - Circuit::Expression value; +struct HeapValueType { - friend bool operator==(const Single&, const Single&); + struct Simple { + friend bool operator==(const Simple&, const Simple&); std::vector bincodeSerialize() const; - static Single bincodeDeserialize(std::vector); + static Simple bincodeDeserialize(std::vector); }; struct Array { - std::vector value; + std::vector value_types; + uint64_t size; friend bool operator==(const Array&, const Array&); std::vector bincodeSerialize() const; static Array bincodeDeserialize(std::vector); }; - struct MemoryArray { - Circuit::BlockId value; + struct Vector { + std::vector value_types; - friend bool operator==(const MemoryArray&, const MemoryArray&); + friend bool operator==(const Vector&, const Vector&); std::vector bincodeSerialize() const; - static MemoryArray bincodeDeserialize(std::vector); + static Vector bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; - friend bool operator==(const BrilligInputs&, const BrilligInputs&); + friend bool operator==(const HeapValueType&, const HeapValueType&); std::vector bincodeSerialize() const; - static BrilligInputs bincodeDeserialize(std::vector); + static HeapValueType bincodeDeserialize(std::vector); }; -struct BinaryFieldOp { +struct Value { + std::string inner; - struct Add { - friend bool operator==(const Add&, const Add&); + friend bool operator==(const Value&, const Value&); + std::vector bincodeSerialize() const; + static Value bincodeDeserialize(std::vector); +}; + +struct ValueOrArray { + + struct MemoryAddress { + Circuit::MemoryAddress value; + + friend bool operator==(const MemoryAddress&, const MemoryAddress&); std::vector bincodeSerialize() const; - static Add bincodeDeserialize(std::vector); + static MemoryAddress bincodeDeserialize(std::vector); }; - struct Sub { - friend bool operator==(const Sub&, const Sub&); + struct HeapArray { + Circuit::HeapArray value; + + friend bool operator==(const HeapArray&, const HeapArray&); std::vector bincodeSerialize() const; - static Sub bincodeDeserialize(std::vector); + static HeapArray bincodeDeserialize(std::vector); }; - struct Mul { - friend bool operator==(const Mul&, const Mul&); + struct HeapVector { + Circuit::HeapVector value; + + friend bool operator==(const HeapVector&, const HeapVector&); std::vector bincodeSerialize() const; - static Mul bincodeDeserialize(std::vector); + static HeapVector bincodeDeserialize(std::vector); }; - struct Div { - friend bool operator==(const Div&, const Div&); + std::variant value; + + friend bool operator==(const ValueOrArray&, const ValueOrArray&); + std::vector bincodeSerialize() const; + static ValueOrArray bincodeDeserialize(std::vector); +}; + +struct BrilligOpcode { + + struct BinaryFieldOp { + Circuit::MemoryAddress destination; + Circuit::BinaryFieldOp op; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + + friend bool operator==(const BinaryFieldOp&, const BinaryFieldOp&); std::vector bincodeSerialize() const; - static Div bincodeDeserialize(std::vector); + static BinaryFieldOp bincodeDeserialize(std::vector); }; - struct Equals { - friend bool operator==(const Equals&, const Equals&); + struct BinaryIntOp { + Circuit::MemoryAddress destination; + Circuit::BinaryIntOp op; + uint32_t bit_size; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + + friend bool operator==(const BinaryIntOp&, const BinaryIntOp&); std::vector bincodeSerialize() const; - static Equals bincodeDeserialize(std::vector); + static BinaryIntOp bincodeDeserialize(std::vector); }; - std::variant value; + struct JumpIfNot { + Circuit::MemoryAddress condition; + uint64_t location; - friend bool operator==(const BinaryFieldOp&, const BinaryFieldOp&); - std::vector bincodeSerialize() const; - static BinaryFieldOp bincodeDeserialize(std::vector); -}; + friend bool operator==(const JumpIfNot&, const JumpIfNot&); + std::vector bincodeSerialize() const; + static JumpIfNot bincodeDeserialize(std::vector); + }; -struct BinaryIntOp { + struct JumpIf { + Circuit::MemoryAddress condition; + uint64_t location; - struct Add { - friend bool operator==(const Add&, const Add&); + friend bool operator==(const JumpIf&, const JumpIf&); std::vector bincodeSerialize() const; - static Add bincodeDeserialize(std::vector); + static JumpIf bincodeDeserialize(std::vector); }; - struct Sub { - friend bool operator==(const Sub&, const Sub&); + struct Jump { + uint64_t location; + + friend bool operator==(const Jump&, const Jump&); std::vector bincodeSerialize() const; - static Sub bincodeDeserialize(std::vector); + static Jump bincodeDeserialize(std::vector); }; - struct Mul { - friend bool operator==(const Mul&, const Mul&); + struct CalldataCopy { + Circuit::MemoryAddress destination_address; + uint64_t size; + uint64_t offset; + + friend bool operator==(const CalldataCopy&, const CalldataCopy&); std::vector bincodeSerialize() const; - static Mul bincodeDeserialize(std::vector); + static CalldataCopy bincodeDeserialize(std::vector); }; - struct SignedDiv { - friend bool operator==(const SignedDiv&, const SignedDiv&); + struct Call { + uint64_t location; + + friend bool operator==(const Call&, const Call&); std::vector bincodeSerialize() const; - static SignedDiv bincodeDeserialize(std::vector); + static Call bincodeDeserialize(std::vector); }; - struct UnsignedDiv { - friend bool operator==(const UnsignedDiv&, const UnsignedDiv&); + struct Const { + Circuit::MemoryAddress destination; + uint32_t bit_size; + Circuit::Value value; + + friend bool operator==(const Const&, const Const&); std::vector bincodeSerialize() const; - static UnsignedDiv bincodeDeserialize(std::vector); + static Const bincodeDeserialize(std::vector); }; - struct Equals { - friend bool operator==(const Equals&, const Equals&); + struct Return { + friend bool operator==(const Return&, const Return&); std::vector bincodeSerialize() const; - static Equals bincodeDeserialize(std::vector); + static Return bincodeDeserialize(std::vector); }; - struct LessThan { - friend bool operator==(const LessThan&, const LessThan&); + struct ForeignCall { + std::string function; + std::vector destinations; + std::vector destination_value_types; + std::vector inputs; + std::vector input_value_types; + + friend bool operator==(const ForeignCall&, const ForeignCall&); std::vector bincodeSerialize() const; - static LessThan bincodeDeserialize(std::vector); + static ForeignCall bincodeDeserialize(std::vector); }; - struct LessThanEquals { - friend bool operator==(const LessThanEquals&, const LessThanEquals&); + struct Mov { + Circuit::MemoryAddress destination; + Circuit::MemoryAddress source; + + friend bool operator==(const Mov&, const Mov&); std::vector bincodeSerialize() const; - static LessThanEquals bincodeDeserialize(std::vector); + static Mov bincodeDeserialize(std::vector); }; - struct And { - friend bool operator==(const And&, const And&); + struct Load { + Circuit::MemoryAddress destination; + Circuit::MemoryAddress source_pointer; + + friend bool operator==(const Load&, const Load&); std::vector bincodeSerialize() const; - static And bincodeDeserialize(std::vector); + static Load bincodeDeserialize(std::vector); }; - struct Or { - friend bool operator==(const Or&, const Or&); + struct Store { + Circuit::MemoryAddress destination_pointer; + Circuit::MemoryAddress source; + + friend bool operator==(const Store&, const Store&); std::vector bincodeSerialize() const; - static Or bincodeDeserialize(std::vector); + static Store bincodeDeserialize(std::vector); }; - struct Xor { - friend bool operator==(const Xor&, const Xor&); + struct BlackBox { + Circuit::BlackBoxOp value; + + friend bool operator==(const BlackBox&, const BlackBox&); std::vector bincodeSerialize() const; - static Xor bincodeDeserialize(std::vector); + static BlackBox bincodeDeserialize(std::vector); }; - struct Shl { - friend bool operator==(const Shl&, const Shl&); + struct Trap { + friend bool operator==(const Trap&, const Trap&); std::vector bincodeSerialize() const; - static Shl bincodeDeserialize(std::vector); + static Trap bincodeDeserialize(std::vector); }; - struct Shr { - friend bool operator==(const Shr&, const Shr&); + struct Stop { + uint64_t return_data_offset; + uint64_t return_data_size; + + friend bool operator==(const Stop&, const Stop&); std::vector bincodeSerialize() const; - static Shr bincodeDeserialize(std::vector); + static Stop bincodeDeserialize(std::vector); }; - std::variant value; + std::variant + value; - friend bool operator==(const BinaryIntOp&, const BinaryIntOp&); + friend bool operator==(const BrilligOpcode&, const BrilligOpcode&); std::vector bincodeSerialize() const; - static BinaryIntOp bincodeDeserialize(std::vector); + static BrilligOpcode bincodeDeserialize(std::vector); }; -struct MemoryAddress { - uint64_t value; +struct Witness { + uint32_t value; - friend bool operator==(const MemoryAddress&, const MemoryAddress&); + friend bool operator==(const Witness&, const Witness&); std::vector bincodeSerialize() const; - static MemoryAddress bincodeDeserialize(std::vector); + static Witness bincodeDeserialize(std::vector); }; -struct HeapArray { - Circuit::MemoryAddress pointer; - uint64_t size; +struct FunctionInput { + Circuit::Witness witness; + uint32_t num_bits; - friend bool operator==(const HeapArray&, const HeapArray&); + friend bool operator==(const FunctionInput&, const FunctionInput&); std::vector bincodeSerialize() const; - static HeapArray bincodeDeserialize(std::vector); + static FunctionInput bincodeDeserialize(std::vector); }; -struct HeapVector { - Circuit::MemoryAddress pointer; - Circuit::MemoryAddress size; +struct BlackBoxFuncCall { - friend bool operator==(const HeapVector&, const HeapVector&); - std::vector bincodeSerialize() const; - static HeapVector bincodeDeserialize(std::vector); -}; + struct AND { + Circuit::FunctionInput lhs; + Circuit::FunctionInput rhs; + Circuit::Witness output; -struct BlackBoxOp { + friend bool operator==(const AND&, const AND&); + std::vector bincodeSerialize() const; + static AND bincodeDeserialize(std::vector); + }; - struct Sha256 { - Circuit::HeapVector message; - Circuit::HeapArray output; + struct XOR { + Circuit::FunctionInput lhs; + Circuit::FunctionInput rhs; + Circuit::Witness output; - friend bool operator==(const Sha256&, const Sha256&); + friend bool operator==(const XOR&, const XOR&); std::vector bincodeSerialize() const; - static Sha256 bincodeDeserialize(std::vector); + static XOR bincodeDeserialize(std::vector); + }; + + struct RANGE { + Circuit::FunctionInput input; + + friend bool operator==(const RANGE&, const RANGE&); + std::vector bincodeSerialize() const; + static RANGE bincodeDeserialize(std::vector); + }; + + struct SHA256 { + std::vector inputs; + std::vector outputs; + + friend bool operator==(const SHA256&, const SHA256&); + std::vector bincodeSerialize() const; + static SHA256 bincodeDeserialize(std::vector); }; struct Blake2s { - Circuit::HeapVector message; - Circuit::HeapArray output; + std::vector inputs; + std::vector outputs; friend bool operator==(const Blake2s&, const Blake2s&); std::vector bincodeSerialize() const; @@ -531,38 +699,52 @@ struct BlackBoxOp { }; struct Blake3 { - Circuit::HeapVector message; - Circuit::HeapArray output; + std::vector inputs; + std::vector outputs; friend bool operator==(const Blake3&, const Blake3&); std::vector bincodeSerialize() const; static Blake3 bincodeDeserialize(std::vector); }; - struct Keccak256 { - Circuit::HeapVector message; - Circuit::HeapArray output; + struct SchnorrVerify { + Circuit::FunctionInput public_key_x; + Circuit::FunctionInput public_key_y; + std::vector signature; + std::vector message; + Circuit::Witness output; - friend bool operator==(const Keccak256&, const Keccak256&); + friend bool operator==(const SchnorrVerify&, const SchnorrVerify&); std::vector bincodeSerialize() const; - static Keccak256 bincodeDeserialize(std::vector); + static SchnorrVerify bincodeDeserialize(std::vector); }; - struct Keccakf1600 { - Circuit::HeapVector message; - Circuit::HeapArray output; + struct PedersenCommitment { + std::vector inputs; + uint32_t domain_separator; + std::array outputs; - friend bool operator==(const Keccakf1600&, const Keccakf1600&); + friend bool operator==(const PedersenCommitment&, const PedersenCommitment&); std::vector bincodeSerialize() const; - static Keccakf1600 bincodeDeserialize(std::vector); + static PedersenCommitment bincodeDeserialize(std::vector); + }; + + struct PedersenHash { + std::vector inputs; + uint32_t domain_separator; + Circuit::Witness output; + + friend bool operator==(const PedersenHash&, const PedersenHash&); + std::vector bincodeSerialize() const; + static PedersenHash bincodeDeserialize(std::vector); }; struct EcdsaSecp256k1 { - Circuit::HeapVector hashed_msg; - Circuit::HeapArray public_key_x; - Circuit::HeapArray public_key_y; - Circuit::HeapArray signature; - Circuit::MemoryAddress result; + std::vector public_key_x; + std::vector public_key_y; + std::vector signature; + std::vector hashed_message; + Circuit::Witness output; friend bool operator==(const EcdsaSecp256k1&, const EcdsaSecp256k1&); std::vector bincodeSerialize() const; @@ -570,75 +752,82 @@ struct BlackBoxOp { }; struct EcdsaSecp256r1 { - Circuit::HeapVector hashed_msg; - Circuit::HeapArray public_key_x; - Circuit::HeapArray public_key_y; - Circuit::HeapArray signature; - Circuit::MemoryAddress result; + std::vector public_key_x; + std::vector public_key_y; + std::vector signature; + std::vector hashed_message; + Circuit::Witness output; friend bool operator==(const EcdsaSecp256r1&, const EcdsaSecp256r1&); std::vector bincodeSerialize() const; static EcdsaSecp256r1 bincodeDeserialize(std::vector); }; - struct SchnorrVerify { - Circuit::MemoryAddress public_key_x; - Circuit::MemoryAddress public_key_y; - Circuit::HeapVector message; - Circuit::HeapVector signature; - Circuit::MemoryAddress result; + struct FixedBaseScalarMul { + Circuit::FunctionInput low; + Circuit::FunctionInput high; + std::array outputs; + + friend bool operator==(const FixedBaseScalarMul&, const FixedBaseScalarMul&); + std::vector bincodeSerialize() const; + static FixedBaseScalarMul bincodeDeserialize(std::vector); + }; + + struct EmbeddedCurveAdd { + Circuit::FunctionInput input1_x; + Circuit::FunctionInput input1_y; + Circuit::FunctionInput input2_x; + Circuit::FunctionInput input2_y; + std::array outputs; - friend bool operator==(const SchnorrVerify&, const SchnorrVerify&); + friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); std::vector bincodeSerialize() const; - static SchnorrVerify bincodeDeserialize(std::vector); + static EmbeddedCurveAdd bincodeDeserialize(std::vector); }; - struct PedersenCommitment { - Circuit::HeapVector inputs; - Circuit::MemoryAddress domain_separator; - Circuit::HeapArray output; + struct Keccak256 { + std::vector inputs; + std::vector outputs; - friend bool operator==(const PedersenCommitment&, const PedersenCommitment&); + friend bool operator==(const Keccak256&, const Keccak256&); std::vector bincodeSerialize() const; - static PedersenCommitment bincodeDeserialize(std::vector); + static Keccak256 bincodeDeserialize(std::vector); }; - struct PedersenHash { - Circuit::HeapVector inputs; - Circuit::MemoryAddress domain_separator; - Circuit::MemoryAddress output; + struct Keccak256VariableLength { + std::vector inputs; + Circuit::FunctionInput var_message_size; + std::vector outputs; - friend bool operator==(const PedersenHash&, const PedersenHash&); + friend bool operator==(const Keccak256VariableLength&, const Keccak256VariableLength&); std::vector bincodeSerialize() const; - static PedersenHash bincodeDeserialize(std::vector); + static Keccak256VariableLength bincodeDeserialize(std::vector); }; - struct FixedBaseScalarMul { - Circuit::MemoryAddress low; - Circuit::MemoryAddress high; - Circuit::HeapArray result; + struct Keccakf1600 { + std::vector inputs; + std::vector outputs; - friend bool operator==(const FixedBaseScalarMul&, const FixedBaseScalarMul&); + friend bool operator==(const Keccakf1600&, const Keccakf1600&); std::vector bincodeSerialize() const; - static FixedBaseScalarMul bincodeDeserialize(std::vector); + static Keccakf1600 bincodeDeserialize(std::vector); }; - struct EmbeddedCurveAdd { - Circuit::MemoryAddress input1_x; - Circuit::MemoryAddress input1_y; - Circuit::MemoryAddress input2_x; - Circuit::MemoryAddress input2_y; - Circuit::HeapArray result; + struct RecursiveAggregation { + std::vector verification_key; + std::vector proof; + std::vector public_inputs; + Circuit::FunctionInput key_hash; - friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); + friend bool operator==(const RecursiveAggregation&, const RecursiveAggregation&); std::vector bincodeSerialize() const; - static EmbeddedCurveAdd bincodeDeserialize(std::vector); + static RecursiveAggregation bincodeDeserialize(std::vector); }; struct BigIntAdd { - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - Circuit::MemoryAddress output; + uint32_t lhs; + uint32_t rhs; + uint32_t output; friend bool operator==(const BigIntAdd&, const BigIntAdd&); std::vector bincodeSerialize() const; @@ -646,9 +835,9 @@ struct BlackBoxOp { }; struct BigIntSub { - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - Circuit::MemoryAddress output; + uint32_t lhs; + uint32_t rhs; + uint32_t output; friend bool operator==(const BigIntSub&, const BigIntSub&); std::vector bincodeSerialize() const; @@ -656,9 +845,9 @@ struct BlackBoxOp { }; struct BigIntMul { - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - Circuit::MemoryAddress output; + uint32_t lhs; + uint32_t rhs; + uint32_t output; friend bool operator==(const BigIntMul&, const BigIntMul&); std::vector bincodeSerialize() const; @@ -666,9 +855,9 @@ struct BlackBoxOp { }; struct BigIntDiv { - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - Circuit::MemoryAddress output; + uint32_t lhs; + uint32_t rhs; + uint32_t output; friend bool operator==(const BigIntDiv&, const BigIntDiv&); std::vector bincodeSerialize() const; @@ -676,9 +865,9 @@ struct BlackBoxOp { }; struct BigIntFromLeBytes { - Circuit::HeapVector inputs; - Circuit::HeapVector modulus; - Circuit::MemoryAddress output; + std::vector inputs; + std::vector modulus; + uint32_t output; friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); std::vector bincodeSerialize() const; @@ -686,8 +875,8 @@ struct BlackBoxOp { }; struct BigIntToLeBytes { - Circuit::MemoryAddress input; - Circuit::HeapVector output; + uint32_t input; + std::vector outputs; friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); std::vector bincodeSerialize() const; @@ -695,9 +884,9 @@ struct BlackBoxOp { }; struct Poseidon2Permutation { - Circuit::HeapVector message; - Circuit::HeapArray output; - Circuit::MemoryAddress len; + std::vector inputs; + std::vector outputs; + uint32_t len; friend bool operator==(const Poseidon2Permutation&, const Poseidon2Permutation&); std::vector bincodeSerialize() const; @@ -705,249 +894,96 @@ struct BlackBoxOp { }; struct Sha256Compression { - Circuit::HeapVector input; - Circuit::HeapVector hash_values; - Circuit::HeapArray output; + std::vector inputs; + std::vector hash_values; + std::vector outputs; friend bool operator==(const Sha256Compression&, const Sha256Compression&); std::vector bincodeSerialize() const; static Sha256Compression bincodeDeserialize(std::vector); }; - std::variant - value; - - friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); - std::vector bincodeSerialize() const; - static BlackBoxOp bincodeDeserialize(std::vector); -}; - -struct Value { - std::string inner; - - friend bool operator==(const Value&, const Value&); - std::vector bincodeSerialize() const; - static Value bincodeDeserialize(std::vector); -}; - -struct ValueOrArray { - - struct MemoryAddress { - Circuit::MemoryAddress value; - - friend bool operator==(const MemoryAddress&, const MemoryAddress&); - std::vector bincodeSerialize() const; - static MemoryAddress bincodeDeserialize(std::vector); - }; - - struct HeapArray { - Circuit::HeapArray value; - - friend bool operator==(const HeapArray&, const HeapArray&); - std::vector bincodeSerialize() const; - static HeapArray bincodeDeserialize(std::vector); - }; - - struct HeapVector { - Circuit::HeapVector value; - - friend bool operator==(const HeapVector&, const HeapVector&); - std::vector bincodeSerialize() const; - static HeapVector bincodeDeserialize(std::vector); - }; - - std::variant value; - - friend bool operator==(const ValueOrArray&, const ValueOrArray&); - std::vector bincodeSerialize() const; - static ValueOrArray bincodeDeserialize(std::vector); -}; - -struct BrilligOpcode { - - struct BinaryFieldOp { - Circuit::MemoryAddress destination; - Circuit::BinaryFieldOp op; - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - - friend bool operator==(const BinaryFieldOp&, const BinaryFieldOp&); - std::vector bincodeSerialize() const; - static BinaryFieldOp bincodeDeserialize(std::vector); - }; - - struct BinaryIntOp { - Circuit::MemoryAddress destination; - Circuit::BinaryIntOp op; - uint32_t bit_size; - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - - friend bool operator==(const BinaryIntOp&, const BinaryIntOp&); - std::vector bincodeSerialize() const; - static BinaryIntOp bincodeDeserialize(std::vector); - }; - - struct JumpIfNot { - Circuit::MemoryAddress condition; - uint64_t location; - - friend bool operator==(const JumpIfNot&, const JumpIfNot&); - std::vector bincodeSerialize() const; - static JumpIfNot bincodeDeserialize(std::vector); - }; - - struct JumpIf { - Circuit::MemoryAddress condition; - uint64_t location; - - friend bool operator==(const JumpIf&, const JumpIf&); - std::vector bincodeSerialize() const; - static JumpIf bincodeDeserialize(std::vector); - }; - - struct Jump { - uint64_t location; - - friend bool operator==(const Jump&, const Jump&); - std::vector bincodeSerialize() const; - static Jump bincodeDeserialize(std::vector); - }; - - struct CalldataCopy { - Circuit::MemoryAddress destination_address; - uint64_t size; - uint64_t offset; - - friend bool operator==(const CalldataCopy&, const CalldataCopy&); - std::vector bincodeSerialize() const; - static CalldataCopy bincodeDeserialize(std::vector); - }; - - struct Call { - uint64_t location; - - friend bool operator==(const Call&, const Call&); - std::vector bincodeSerialize() const; - static Call bincodeDeserialize(std::vector); - }; - - struct Const { - Circuit::MemoryAddress destination; - uint32_t bit_size; - Circuit::Value value; - - friend bool operator==(const Const&, const Const&); - std::vector bincodeSerialize() const; - static Const bincodeDeserialize(std::vector); - }; - - struct Return { - friend bool operator==(const Return&, const Return&); - std::vector bincodeSerialize() const; - static Return bincodeDeserialize(std::vector); - }; + BigIntDiv, + BigIntFromLeBytes, + BigIntToLeBytes, + Poseidon2Permutation, + Sha256Compression> + value; - struct ForeignCall { - std::string function; - std::vector destinations; - std::vector inputs; + friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&); + std::vector bincodeSerialize() const; + static BlackBoxFuncCall bincodeDeserialize(std::vector); +}; - friend bool operator==(const ForeignCall&, const ForeignCall&); - std::vector bincodeSerialize() const; - static ForeignCall bincodeDeserialize(std::vector); - }; +struct BlockId { + uint32_t value; - struct Mov { - Circuit::MemoryAddress destination; - Circuit::MemoryAddress source; + friend bool operator==(const BlockId&, const BlockId&); + std::vector bincodeSerialize() const; + static BlockId bincodeDeserialize(std::vector); +}; - friend bool operator==(const Mov&, const Mov&); - std::vector bincodeSerialize() const; - static Mov bincodeDeserialize(std::vector); - }; +struct Expression { + std::vector> mul_terms; + std::vector> linear_combinations; + std::string q_c; - struct Load { - Circuit::MemoryAddress destination; - Circuit::MemoryAddress source_pointer; + friend bool operator==(const Expression&, const Expression&); + std::vector bincodeSerialize() const; + static Expression bincodeDeserialize(std::vector); +}; - friend bool operator==(const Load&, const Load&); - std::vector bincodeSerialize() const; - static Load bincodeDeserialize(std::vector); - }; +struct BrilligInputs { - struct Store { - Circuit::MemoryAddress destination_pointer; - Circuit::MemoryAddress source; + struct Single { + Circuit::Expression value; - friend bool operator==(const Store&, const Store&); + friend bool operator==(const Single&, const Single&); std::vector bincodeSerialize() const; - static Store bincodeDeserialize(std::vector); + static Single bincodeDeserialize(std::vector); }; - struct BlackBox { - Circuit::BlackBoxOp value; - - friend bool operator==(const BlackBox&, const BlackBox&); - std::vector bincodeSerialize() const; - static BlackBox bincodeDeserialize(std::vector); - }; + struct Array { + std::vector value; - struct Trap { - friend bool operator==(const Trap&, const Trap&); + friend bool operator==(const Array&, const Array&); std::vector bincodeSerialize() const; - static Trap bincodeDeserialize(std::vector); + static Array bincodeDeserialize(std::vector); }; - struct Stop { - uint64_t return_data_offset; - uint64_t return_data_size; + struct MemoryArray { + Circuit::BlockId value; - friend bool operator==(const Stop&, const Stop&); + friend bool operator==(const MemoryArray&, const MemoryArray&); std::vector bincodeSerialize() const; - static Stop bincodeDeserialize(std::vector); + static MemoryArray bincodeDeserialize(std::vector); }; - std::variant - value; + std::variant value; - friend bool operator==(const BrilligOpcode&, const BrilligOpcode&); + friend bool operator==(const BrilligInputs&, const BrilligInputs&); std::vector bincodeSerialize() const; - static BrilligOpcode bincodeDeserialize(std::vector); + static BrilligInputs bincodeDeserialize(std::vector); }; struct BrilligOutputs { @@ -5517,9 +5553,15 @@ inline bool operator==(const BrilligOpcode::ForeignCall& lhs, const BrilligOpcod if (!(lhs.destinations == rhs.destinations)) { return false; } + if (!(lhs.destination_value_types == rhs.destination_value_types)) { + return false; + } if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.input_value_types == rhs.input_value_types)) { + return false; + } return true; } @@ -5549,7 +5591,9 @@ void serde::Serializable::serialize(const C { serde::Serializable::serialize(obj.function, serializer); serde::Serializable::serialize(obj.destinations, serializer); + serde::Serializable::serialize(obj.destination_value_types, serializer); serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.input_value_types, serializer); } template <> @@ -5560,7 +5604,10 @@ Circuit::BrilligOpcode::ForeignCall serde::Deserializable::deserialize(deserializer); obj.destinations = serde::Deserializable::deserialize(deserializer); + obj.destination_value_types = + serde::Deserializable::deserialize(deserializer); obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.input_value_types = serde::Deserializable::deserialize(deserializer); return obj; } @@ -6561,6 +6608,195 @@ Circuit::HeapArray serde::Deserializable::deserialize(Deseri namespace Circuit { +inline bool operator==(const HeapValueType& lhs, const HeapValueType& rhs) +{ + if (!(lhs.value == rhs.value)) { + return false; + } + return true; +} + +inline std::vector HeapValueType::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline HeapValueType HeapValueType::bincodeDeserialize(std::vector input) +{ + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw_or_abort("Some input bytes were not read"); + } + return value; +} + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::HeapValueType& obj, Serializer& serializer) +{ + serializer.increase_container_depth(); + serde::Serializable::serialize(obj.value, serializer); + serializer.decrease_container_depth(); +} + +template <> +template +Circuit::HeapValueType serde::Deserializable::deserialize(Deserializer& deserializer) +{ + deserializer.increase_container_depth(); + Circuit::HeapValueType obj; + obj.value = serde::Deserializable::deserialize(deserializer); + deserializer.decrease_container_depth(); + return obj; +} + +namespace Circuit { + +inline bool operator==(const HeapValueType::Simple& lhs, const HeapValueType::Simple& rhs) +{ + return true; +} + +inline std::vector HeapValueType::Simple::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline HeapValueType::Simple HeapValueType::Simple::bincodeDeserialize(std::vector input) +{ + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw_or_abort("Some input bytes were not read"); + } + return value; +} + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::HeapValueType::Simple& obj, + Serializer& serializer) +{} + +template <> +template +Circuit::HeapValueType::Simple serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::HeapValueType::Simple obj; + return obj; +} + +namespace Circuit { + +inline bool operator==(const HeapValueType::Array& lhs, const HeapValueType::Array& rhs) +{ + if (!(lhs.value_types == rhs.value_types)) { + return false; + } + if (!(lhs.size == rhs.size)) { + return false; + } + return true; +} + +inline std::vector HeapValueType::Array::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline HeapValueType::Array HeapValueType::Array::bincodeDeserialize(std::vector input) +{ + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw_or_abort("Some input bytes were not read"); + } + return value; +} + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::HeapValueType::Array& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.value_types, serializer); + serde::Serializable::serialize(obj.size, serializer); +} + +template <> +template +Circuit::HeapValueType::Array serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::HeapValueType::Array obj; + obj.value_types = serde::Deserializable::deserialize(deserializer); + obj.size = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const HeapValueType::Vector& lhs, const HeapValueType::Vector& rhs) +{ + if (!(lhs.value_types == rhs.value_types)) { + return false; + } + return true; +} + +inline std::vector HeapValueType::Vector::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline HeapValueType::Vector HeapValueType::Vector::bincodeDeserialize(std::vector input) +{ + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw_or_abort("Some input bytes were not read"); + } + return value; +} + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::HeapValueType::Vector& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.value_types, serializer); +} + +template <> +template +Circuit::HeapValueType::Vector serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::HeapValueType::Vector obj; + obj.value_types = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + inline bool operator==(const HeapVector& lhs, const HeapVector& rhs) { if (!(lhs.pointer == rhs.pointer)) { diff --git a/noir/acvm-repo/acir/codegen/acir.cpp b/noir/acvm-repo/acir/codegen/acir.cpp index 18fc17f6926..b1c0d12272c 100644 --- a/noir/acvm-repo/acir/codegen/acir.cpp +++ b/noir/acvm-repo/acir/codegen/acir.cpp @@ -5,65 +5,172 @@ namespace Circuit { - struct Witness { - uint32_t value; + struct BinaryFieldOp { - friend bool operator==(const Witness&, const Witness&); - std::vector bincodeSerialize() const; - static Witness bincodeDeserialize(std::vector); - }; + struct Add { + friend bool operator==(const Add&, const Add&); + std::vector bincodeSerialize() const; + static Add bincodeDeserialize(std::vector); + }; - struct FunctionInput { - Circuit::Witness witness; - uint32_t num_bits; + struct Sub { + friend bool operator==(const Sub&, const Sub&); + std::vector bincodeSerialize() const; + static Sub bincodeDeserialize(std::vector); + }; - friend bool operator==(const FunctionInput&, const FunctionInput&); + struct Mul { + friend bool operator==(const Mul&, const Mul&); + std::vector bincodeSerialize() const; + static Mul bincodeDeserialize(std::vector); + }; + + struct Div { + friend bool operator==(const Div&, const Div&); + std::vector bincodeSerialize() const; + static Div bincodeDeserialize(std::vector); + }; + + struct Equals { + friend bool operator==(const Equals&, const Equals&); + std::vector bincodeSerialize() const; + static Equals bincodeDeserialize(std::vector); + }; + + std::variant value; + + friend bool operator==(const BinaryFieldOp&, const BinaryFieldOp&); std::vector bincodeSerialize() const; - static FunctionInput bincodeDeserialize(std::vector); + static BinaryFieldOp bincodeDeserialize(std::vector); }; - struct BlackBoxFuncCall { + struct BinaryIntOp { - struct AND { - Circuit::FunctionInput lhs; - Circuit::FunctionInput rhs; - Circuit::Witness output; + struct Add { + friend bool operator==(const Add&, const Add&); + std::vector bincodeSerialize() const; + static Add bincodeDeserialize(std::vector); + }; - friend bool operator==(const AND&, const AND&); + struct Sub { + friend bool operator==(const Sub&, const Sub&); std::vector bincodeSerialize() const; - static AND bincodeDeserialize(std::vector); + static Sub bincodeDeserialize(std::vector); }; - struct XOR { - Circuit::FunctionInput lhs; - Circuit::FunctionInput rhs; - Circuit::Witness output; + struct Mul { + friend bool operator==(const Mul&, const Mul&); + std::vector bincodeSerialize() const; + static Mul bincodeDeserialize(std::vector); + }; - friend bool operator==(const XOR&, const XOR&); + struct SignedDiv { + friend bool operator==(const SignedDiv&, const SignedDiv&); std::vector bincodeSerialize() const; - static XOR bincodeDeserialize(std::vector); + static SignedDiv bincodeDeserialize(std::vector); }; - struct RANGE { - Circuit::FunctionInput input; + struct UnsignedDiv { + friend bool operator==(const UnsignedDiv&, const UnsignedDiv&); + std::vector bincodeSerialize() const; + static UnsignedDiv bincodeDeserialize(std::vector); + }; - friend bool operator==(const RANGE&, const RANGE&); + struct Equals { + friend bool operator==(const Equals&, const Equals&); std::vector bincodeSerialize() const; - static RANGE bincodeDeserialize(std::vector); + static Equals bincodeDeserialize(std::vector); }; - struct SHA256 { - std::vector inputs; - std::vector outputs; + struct LessThan { + friend bool operator==(const LessThan&, const LessThan&); + std::vector bincodeSerialize() const; + static LessThan bincodeDeserialize(std::vector); + }; - friend bool operator==(const SHA256&, const SHA256&); + struct LessThanEquals { + friend bool operator==(const LessThanEquals&, const LessThanEquals&); std::vector bincodeSerialize() const; - static SHA256 bincodeDeserialize(std::vector); + static LessThanEquals bincodeDeserialize(std::vector); + }; + + struct And { + friend bool operator==(const And&, const And&); + std::vector bincodeSerialize() const; + static And bincodeDeserialize(std::vector); + }; + + struct Or { + friend bool operator==(const Or&, const Or&); + std::vector bincodeSerialize() const; + static Or bincodeDeserialize(std::vector); + }; + + struct Xor { + friend bool operator==(const Xor&, const Xor&); + std::vector bincodeSerialize() const; + static Xor bincodeDeserialize(std::vector); + }; + + struct Shl { + friend bool operator==(const Shl&, const Shl&); + std::vector bincodeSerialize() const; + static Shl bincodeDeserialize(std::vector); + }; + + struct Shr { + friend bool operator==(const Shr&, const Shr&); + std::vector bincodeSerialize() const; + static Shr bincodeDeserialize(std::vector); + }; + + std::variant value; + + friend bool operator==(const BinaryIntOp&, const BinaryIntOp&); + std::vector bincodeSerialize() const; + static BinaryIntOp bincodeDeserialize(std::vector); + }; + + struct MemoryAddress { + uint64_t value; + + friend bool operator==(const MemoryAddress&, const MemoryAddress&); + std::vector bincodeSerialize() const; + static MemoryAddress bincodeDeserialize(std::vector); + }; + + struct HeapArray { + Circuit::MemoryAddress pointer; + uint64_t size; + + friend bool operator==(const HeapArray&, const HeapArray&); + std::vector bincodeSerialize() const; + static HeapArray bincodeDeserialize(std::vector); + }; + + struct HeapVector { + Circuit::MemoryAddress pointer; + Circuit::MemoryAddress size; + + friend bool operator==(const HeapVector&, const HeapVector&); + std::vector bincodeSerialize() const; + static HeapVector bincodeDeserialize(std::vector); + }; + + struct BlackBoxOp { + + struct Sha256 { + Circuit::HeapVector message; + Circuit::HeapArray output; + + friend bool operator==(const Sha256&, const Sha256&); + std::vector bincodeSerialize() const; + static Sha256 bincodeDeserialize(std::vector); }; struct Blake2s { - std::vector inputs; - std::vector outputs; + Circuit::HeapVector message; + Circuit::HeapArray output; friend bool operator==(const Blake2s&, const Blake2s&); std::vector bincodeSerialize() const; @@ -71,52 +178,38 @@ namespace Circuit { }; struct Blake3 { - std::vector inputs; - std::vector outputs; + Circuit::HeapVector message; + Circuit::HeapArray output; friend bool operator==(const Blake3&, const Blake3&); std::vector bincodeSerialize() const; static Blake3 bincodeDeserialize(std::vector); }; - struct SchnorrVerify { - Circuit::FunctionInput public_key_x; - Circuit::FunctionInput public_key_y; - std::vector signature; - std::vector message; - Circuit::Witness output; - - friend bool operator==(const SchnorrVerify&, const SchnorrVerify&); - std::vector bincodeSerialize() const; - static SchnorrVerify bincodeDeserialize(std::vector); - }; - - struct PedersenCommitment { - std::vector inputs; - uint32_t domain_separator; - std::array outputs; + struct Keccak256 { + Circuit::HeapVector message; + Circuit::HeapArray output; - friend bool operator==(const PedersenCommitment&, const PedersenCommitment&); + friend bool operator==(const Keccak256&, const Keccak256&); std::vector bincodeSerialize() const; - static PedersenCommitment bincodeDeserialize(std::vector); + static Keccak256 bincodeDeserialize(std::vector); }; - struct PedersenHash { - std::vector inputs; - uint32_t domain_separator; - Circuit::Witness output; + struct Keccakf1600 { + Circuit::HeapVector message; + Circuit::HeapArray output; - friend bool operator==(const PedersenHash&, const PedersenHash&); + friend bool operator==(const Keccakf1600&, const Keccakf1600&); std::vector bincodeSerialize() const; - static PedersenHash bincodeDeserialize(std::vector); + static Keccakf1600 bincodeDeserialize(std::vector); }; struct EcdsaSecp256k1 { - std::vector public_key_x; - std::vector public_key_y; - std::vector signature; - std::vector hashed_message; - Circuit::Witness output; + Circuit::HeapVector hashed_msg; + Circuit::HeapArray public_key_x; + Circuit::HeapArray public_key_y; + Circuit::HeapArray signature; + Circuit::MemoryAddress result; friend bool operator==(const EcdsaSecp256k1&, const EcdsaSecp256k1&); std::vector bincodeSerialize() const; @@ -124,82 +217,75 @@ namespace Circuit { }; struct EcdsaSecp256r1 { - std::vector public_key_x; - std::vector public_key_y; - std::vector signature; - std::vector hashed_message; - Circuit::Witness output; + Circuit::HeapVector hashed_msg; + Circuit::HeapArray public_key_x; + Circuit::HeapArray public_key_y; + Circuit::HeapArray signature; + Circuit::MemoryAddress result; friend bool operator==(const EcdsaSecp256r1&, const EcdsaSecp256r1&); std::vector bincodeSerialize() const; static EcdsaSecp256r1 bincodeDeserialize(std::vector); }; - struct FixedBaseScalarMul { - Circuit::FunctionInput low; - Circuit::FunctionInput high; - std::array outputs; - - friend bool operator==(const FixedBaseScalarMul&, const FixedBaseScalarMul&); - std::vector bincodeSerialize() const; - static FixedBaseScalarMul bincodeDeserialize(std::vector); - }; - - struct EmbeddedCurveAdd { - Circuit::FunctionInput input1_x; - Circuit::FunctionInput input1_y; - Circuit::FunctionInput input2_x; - Circuit::FunctionInput input2_y; - std::array outputs; + struct SchnorrVerify { + Circuit::MemoryAddress public_key_x; + Circuit::MemoryAddress public_key_y; + Circuit::HeapVector message; + Circuit::HeapVector signature; + Circuit::MemoryAddress result; - friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); + friend bool operator==(const SchnorrVerify&, const SchnorrVerify&); std::vector bincodeSerialize() const; - static EmbeddedCurveAdd bincodeDeserialize(std::vector); + static SchnorrVerify bincodeDeserialize(std::vector); }; - struct Keccak256 { - std::vector inputs; - std::vector outputs; + struct PedersenCommitment { + Circuit::HeapVector inputs; + Circuit::MemoryAddress domain_separator; + Circuit::HeapArray output; - friend bool operator==(const Keccak256&, const Keccak256&); + friend bool operator==(const PedersenCommitment&, const PedersenCommitment&); std::vector bincodeSerialize() const; - static Keccak256 bincodeDeserialize(std::vector); + static PedersenCommitment bincodeDeserialize(std::vector); }; - struct Keccak256VariableLength { - std::vector inputs; - Circuit::FunctionInput var_message_size; - std::vector outputs; + struct PedersenHash { + Circuit::HeapVector inputs; + Circuit::MemoryAddress domain_separator; + Circuit::MemoryAddress output; - friend bool operator==(const Keccak256VariableLength&, const Keccak256VariableLength&); + friend bool operator==(const PedersenHash&, const PedersenHash&); std::vector bincodeSerialize() const; - static Keccak256VariableLength bincodeDeserialize(std::vector); + static PedersenHash bincodeDeserialize(std::vector); }; - struct Keccakf1600 { - std::vector inputs; - std::vector outputs; + struct FixedBaseScalarMul { + Circuit::MemoryAddress low; + Circuit::MemoryAddress high; + Circuit::HeapArray result; - friend bool operator==(const Keccakf1600&, const Keccakf1600&); + friend bool operator==(const FixedBaseScalarMul&, const FixedBaseScalarMul&); std::vector bincodeSerialize() const; - static Keccakf1600 bincodeDeserialize(std::vector); + static FixedBaseScalarMul bincodeDeserialize(std::vector); }; - struct RecursiveAggregation { - std::vector verification_key; - std::vector proof; - std::vector public_inputs; - Circuit::FunctionInput key_hash; + struct EmbeddedCurveAdd { + Circuit::MemoryAddress input1_x; + Circuit::MemoryAddress input1_y; + Circuit::MemoryAddress input2_x; + Circuit::MemoryAddress input2_y; + Circuit::HeapArray result; - friend bool operator==(const RecursiveAggregation&, const RecursiveAggregation&); + friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); std::vector bincodeSerialize() const; - static RecursiveAggregation bincodeDeserialize(std::vector); + static EmbeddedCurveAdd bincodeDeserialize(std::vector); }; struct BigIntAdd { - uint32_t lhs; - uint32_t rhs; - uint32_t output; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + Circuit::MemoryAddress output; friend bool operator==(const BigIntAdd&, const BigIntAdd&); std::vector bincodeSerialize() const; @@ -207,9 +293,9 @@ namespace Circuit { }; struct BigIntSub { - uint32_t lhs; - uint32_t rhs; - uint32_t output; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + Circuit::MemoryAddress output; friend bool operator==(const BigIntSub&, const BigIntSub&); std::vector bincodeSerialize() const; @@ -217,9 +303,9 @@ namespace Circuit { }; struct BigIntMul { - uint32_t lhs; - uint32_t rhs; - uint32_t output; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + Circuit::MemoryAddress output; friend bool operator==(const BigIntMul&, const BigIntMul&); std::vector bincodeSerialize() const; @@ -227,9 +313,9 @@ namespace Circuit { }; struct BigIntDiv { - uint32_t lhs; - uint32_t rhs; - uint32_t output; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; + Circuit::MemoryAddress output; friend bool operator==(const BigIntDiv&, const BigIntDiv&); std::vector bincodeSerialize() const; @@ -237,9 +323,9 @@ namespace Circuit { }; struct BigIntFromLeBytes { - std::vector inputs; - std::vector modulus; - uint32_t output; + Circuit::HeapVector inputs; + Circuit::HeapVector modulus; + Circuit::MemoryAddress output; friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); std::vector bincodeSerialize() const; @@ -247,8 +333,8 @@ namespace Circuit { }; struct BigIntToLeBytes { - uint32_t input; - std::vector outputs; + Circuit::MemoryAddress input; + Circuit::HeapVector output; friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); std::vector bincodeSerialize() const; @@ -256,9 +342,9 @@ namespace Circuit { }; struct Poseidon2Permutation { - std::vector inputs; - std::vector outputs; - uint32_t len; + Circuit::HeapVector message; + Circuit::HeapArray output; + Circuit::MemoryAddress len; friend bool operator==(const Poseidon2Permutation&, const Poseidon2Permutation&); std::vector bincodeSerialize() const; @@ -266,627 +352,577 @@ namespace Circuit { }; struct Sha256Compression { - std::vector inputs; - std::vector hash_values; - std::vector outputs; + Circuit::HeapVector input; + Circuit::HeapVector hash_values; + Circuit::HeapArray output; friend bool operator==(const Sha256Compression&, const Sha256Compression&); std::vector bincodeSerialize() const; static Sha256Compression bincodeDeserialize(std::vector); }; - std::variant value; - - friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&); - std::vector bincodeSerialize() const; - static BlackBoxFuncCall bincodeDeserialize(std::vector); - }; - - struct BlockId { - uint32_t value; - - friend bool operator==(const BlockId&, const BlockId&); - std::vector bincodeSerialize() const; - static BlockId bincodeDeserialize(std::vector); - }; - - struct Expression { - std::vector> mul_terms; - std::vector> linear_combinations; - std::string q_c; + std::variant value; - friend bool operator==(const Expression&, const Expression&); + friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); std::vector bincodeSerialize() const; - static Expression bincodeDeserialize(std::vector); + static BlackBoxOp bincodeDeserialize(std::vector); }; - struct BrilligInputs { + struct HeapValueType; - struct Single { - Circuit::Expression value; + struct HeapValueType { - friend bool operator==(const Single&, const Single&); + struct Simple { + friend bool operator==(const Simple&, const Simple&); std::vector bincodeSerialize() const; - static Single bincodeDeserialize(std::vector); + static Simple bincodeDeserialize(std::vector); }; struct Array { - std::vector value; + std::vector value_types; + uint64_t size; friend bool operator==(const Array&, const Array&); std::vector bincodeSerialize() const; static Array bincodeDeserialize(std::vector); }; - struct MemoryArray { - Circuit::BlockId value; + struct Vector { + std::vector value_types; - friend bool operator==(const MemoryArray&, const MemoryArray&); + friend bool operator==(const Vector&, const Vector&); std::vector bincodeSerialize() const; - static MemoryArray bincodeDeserialize(std::vector); + static Vector bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; - friend bool operator==(const BrilligInputs&, const BrilligInputs&); + friend bool operator==(const HeapValueType&, const HeapValueType&); std::vector bincodeSerialize() const; - static BrilligInputs bincodeDeserialize(std::vector); + static HeapValueType bincodeDeserialize(std::vector); }; - struct BinaryFieldOp { + struct Value { + std::string inner; - struct Add { - friend bool operator==(const Add&, const Add&); - std::vector bincodeSerialize() const; - static Add bincodeDeserialize(std::vector); - }; + friend bool operator==(const Value&, const Value&); + std::vector bincodeSerialize() const; + static Value bincodeDeserialize(std::vector); + }; - struct Sub { - friend bool operator==(const Sub&, const Sub&); - std::vector bincodeSerialize() const; - static Sub bincodeDeserialize(std::vector); - }; + struct ValueOrArray { - struct Mul { - friend bool operator==(const Mul&, const Mul&); + struct MemoryAddress { + Circuit::MemoryAddress value; + + friend bool operator==(const MemoryAddress&, const MemoryAddress&); std::vector bincodeSerialize() const; - static Mul bincodeDeserialize(std::vector); + static MemoryAddress bincodeDeserialize(std::vector); }; - struct Div { - friend bool operator==(const Div&, const Div&); + struct HeapArray { + Circuit::HeapArray value; + + friend bool operator==(const HeapArray&, const HeapArray&); std::vector bincodeSerialize() const; - static Div bincodeDeserialize(std::vector); + static HeapArray bincodeDeserialize(std::vector); }; - struct Equals { - friend bool operator==(const Equals&, const Equals&); + struct HeapVector { + Circuit::HeapVector value; + + friend bool operator==(const HeapVector&, const HeapVector&); std::vector bincodeSerialize() const; - static Equals bincodeDeserialize(std::vector); + static HeapVector bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; - friend bool operator==(const BinaryFieldOp&, const BinaryFieldOp&); + friend bool operator==(const ValueOrArray&, const ValueOrArray&); std::vector bincodeSerialize() const; - static BinaryFieldOp bincodeDeserialize(std::vector); + static ValueOrArray bincodeDeserialize(std::vector); }; - struct BinaryIntOp { + struct BrilligOpcode { - struct Add { - friend bool operator==(const Add&, const Add&); - std::vector bincodeSerialize() const; - static Add bincodeDeserialize(std::vector); - }; + struct BinaryFieldOp { + Circuit::MemoryAddress destination; + Circuit::BinaryFieldOp op; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; - struct Sub { - friend bool operator==(const Sub&, const Sub&); + friend bool operator==(const BinaryFieldOp&, const BinaryFieldOp&); std::vector bincodeSerialize() const; - static Sub bincodeDeserialize(std::vector); + static BinaryFieldOp bincodeDeserialize(std::vector); }; - struct Mul { - friend bool operator==(const Mul&, const Mul&); - std::vector bincodeSerialize() const; - static Mul bincodeDeserialize(std::vector); - }; + struct BinaryIntOp { + Circuit::MemoryAddress destination; + Circuit::BinaryIntOp op; + uint32_t bit_size; + Circuit::MemoryAddress lhs; + Circuit::MemoryAddress rhs; - struct SignedDiv { - friend bool operator==(const SignedDiv&, const SignedDiv&); + friend bool operator==(const BinaryIntOp&, const BinaryIntOp&); std::vector bincodeSerialize() const; - static SignedDiv bincodeDeserialize(std::vector); + static BinaryIntOp bincodeDeserialize(std::vector); }; - struct UnsignedDiv { - friend bool operator==(const UnsignedDiv&, const UnsignedDiv&); - std::vector bincodeSerialize() const; - static UnsignedDiv bincodeDeserialize(std::vector); - }; + struct JumpIfNot { + Circuit::MemoryAddress condition; + uint64_t location; - struct Equals { - friend bool operator==(const Equals&, const Equals&); + friend bool operator==(const JumpIfNot&, const JumpIfNot&); std::vector bincodeSerialize() const; - static Equals bincodeDeserialize(std::vector); + static JumpIfNot bincodeDeserialize(std::vector); }; - struct LessThan { - friend bool operator==(const LessThan&, const LessThan&); - std::vector bincodeSerialize() const; - static LessThan bincodeDeserialize(std::vector); - }; + struct JumpIf { + Circuit::MemoryAddress condition; + uint64_t location; - struct LessThanEquals { - friend bool operator==(const LessThanEquals&, const LessThanEquals&); + friend bool operator==(const JumpIf&, const JumpIf&); std::vector bincodeSerialize() const; - static LessThanEquals bincodeDeserialize(std::vector); + static JumpIf bincodeDeserialize(std::vector); }; - struct And { - friend bool operator==(const And&, const And&); - std::vector bincodeSerialize() const; - static And bincodeDeserialize(std::vector); - }; + struct Jump { + uint64_t location; - struct Or { - friend bool operator==(const Or&, const Or&); + friend bool operator==(const Jump&, const Jump&); std::vector bincodeSerialize() const; - static Or bincodeDeserialize(std::vector); + static Jump bincodeDeserialize(std::vector); }; - struct Xor { - friend bool operator==(const Xor&, const Xor&); - std::vector bincodeSerialize() const; - static Xor bincodeDeserialize(std::vector); - }; + struct CalldataCopy { + Circuit::MemoryAddress destination_address; + uint64_t size; + uint64_t offset; - struct Shl { - friend bool operator==(const Shl&, const Shl&); + friend bool operator==(const CalldataCopy&, const CalldataCopy&); std::vector bincodeSerialize() const; - static Shl bincodeDeserialize(std::vector); + static CalldataCopy bincodeDeserialize(std::vector); }; - struct Shr { - friend bool operator==(const Shr&, const Shr&); + struct Call { + uint64_t location; + + friend bool operator==(const Call&, const Call&); std::vector bincodeSerialize() const; - static Shr bincodeDeserialize(std::vector); + static Call bincodeDeserialize(std::vector); }; - std::variant value; - - friend bool operator==(const BinaryIntOp&, const BinaryIntOp&); - std::vector bincodeSerialize() const; - static BinaryIntOp bincodeDeserialize(std::vector); - }; - - struct MemoryAddress { - uint64_t value; - - friend bool operator==(const MemoryAddress&, const MemoryAddress&); - std::vector bincodeSerialize() const; - static MemoryAddress bincodeDeserialize(std::vector); - }; - - struct HeapArray { - Circuit::MemoryAddress pointer; - uint64_t size; - - friend bool operator==(const HeapArray&, const HeapArray&); - std::vector bincodeSerialize() const; - static HeapArray bincodeDeserialize(std::vector); - }; - - struct HeapVector { - Circuit::MemoryAddress pointer; - Circuit::MemoryAddress size; - - friend bool operator==(const HeapVector&, const HeapVector&); - std::vector bincodeSerialize() const; - static HeapVector bincodeDeserialize(std::vector); - }; - - struct BlackBoxOp { - - struct Sha256 { - Circuit::HeapVector message; - Circuit::HeapArray output; + struct Const { + Circuit::MemoryAddress destination; + uint32_t bit_size; + Circuit::Value value; - friend bool operator==(const Sha256&, const Sha256&); + friend bool operator==(const Const&, const Const&); std::vector bincodeSerialize() const; - static Sha256 bincodeDeserialize(std::vector); + static Const bincodeDeserialize(std::vector); }; - struct Blake2s { - Circuit::HeapVector message; - Circuit::HeapArray output; - - friend bool operator==(const Blake2s&, const Blake2s&); + struct Return { + friend bool operator==(const Return&, const Return&); std::vector bincodeSerialize() const; - static Blake2s bincodeDeserialize(std::vector); + static Return bincodeDeserialize(std::vector); }; - struct Blake3 { - Circuit::HeapVector message; - Circuit::HeapArray output; + struct ForeignCall { + std::string function; + std::vector destinations; + std::vector destination_value_types; + std::vector inputs; + std::vector input_value_types; - friend bool operator==(const Blake3&, const Blake3&); + friend bool operator==(const ForeignCall&, const ForeignCall&); std::vector bincodeSerialize() const; - static Blake3 bincodeDeserialize(std::vector); + static ForeignCall bincodeDeserialize(std::vector); }; - struct Keccak256 { - Circuit::HeapVector message; - Circuit::HeapArray output; + struct Mov { + Circuit::MemoryAddress destination; + Circuit::MemoryAddress source; - friend bool operator==(const Keccak256&, const Keccak256&); + friend bool operator==(const Mov&, const Mov&); std::vector bincodeSerialize() const; - static Keccak256 bincodeDeserialize(std::vector); + static Mov bincodeDeserialize(std::vector); }; - struct Keccakf1600 { - Circuit::HeapVector message; - Circuit::HeapArray output; + struct Load { + Circuit::MemoryAddress destination; + Circuit::MemoryAddress source_pointer; - friend bool operator==(const Keccakf1600&, const Keccakf1600&); + friend bool operator==(const Load&, const Load&); std::vector bincodeSerialize() const; - static Keccakf1600 bincodeDeserialize(std::vector); + static Load bincodeDeserialize(std::vector); }; - struct EcdsaSecp256k1 { - Circuit::HeapVector hashed_msg; - Circuit::HeapArray public_key_x; - Circuit::HeapArray public_key_y; - Circuit::HeapArray signature; - Circuit::MemoryAddress result; + struct Store { + Circuit::MemoryAddress destination_pointer; + Circuit::MemoryAddress source; - friend bool operator==(const EcdsaSecp256k1&, const EcdsaSecp256k1&); + friend bool operator==(const Store&, const Store&); std::vector bincodeSerialize() const; - static EcdsaSecp256k1 bincodeDeserialize(std::vector); + static Store bincodeDeserialize(std::vector); }; - struct EcdsaSecp256r1 { - Circuit::HeapVector hashed_msg; - Circuit::HeapArray public_key_x; - Circuit::HeapArray public_key_y; - Circuit::HeapArray signature; - Circuit::MemoryAddress result; + struct BlackBox { + Circuit::BlackBoxOp value; - friend bool operator==(const EcdsaSecp256r1&, const EcdsaSecp256r1&); + friend bool operator==(const BlackBox&, const BlackBox&); std::vector bincodeSerialize() const; - static EcdsaSecp256r1 bincodeDeserialize(std::vector); + static BlackBox bincodeDeserialize(std::vector); }; - struct SchnorrVerify { - Circuit::MemoryAddress public_key_x; - Circuit::MemoryAddress public_key_y; - Circuit::HeapVector message; - Circuit::HeapVector signature; - Circuit::MemoryAddress result; - - friend bool operator==(const SchnorrVerify&, const SchnorrVerify&); + struct Trap { + friend bool operator==(const Trap&, const Trap&); std::vector bincodeSerialize() const; - static SchnorrVerify bincodeDeserialize(std::vector); + static Trap bincodeDeserialize(std::vector); }; - struct PedersenCommitment { - Circuit::HeapVector inputs; - Circuit::MemoryAddress domain_separator; - Circuit::HeapArray output; + struct Stop { + uint64_t return_data_offset; + uint64_t return_data_size; - friend bool operator==(const PedersenCommitment&, const PedersenCommitment&); + friend bool operator==(const Stop&, const Stop&); std::vector bincodeSerialize() const; - static PedersenCommitment bincodeDeserialize(std::vector); + static Stop bincodeDeserialize(std::vector); }; - struct PedersenHash { - Circuit::HeapVector inputs; - Circuit::MemoryAddress domain_separator; - Circuit::MemoryAddress output; + std::variant value; + + friend bool operator==(const BrilligOpcode&, const BrilligOpcode&); + std::vector bincodeSerialize() const; + static BrilligOpcode bincodeDeserialize(std::vector); + }; + + struct Witness { + uint32_t value; + + friend bool operator==(const Witness&, const Witness&); + std::vector bincodeSerialize() const; + static Witness bincodeDeserialize(std::vector); + }; - friend bool operator==(const PedersenHash&, const PedersenHash&); - std::vector bincodeSerialize() const; - static PedersenHash bincodeDeserialize(std::vector); - }; + struct FunctionInput { + Circuit::Witness witness; + uint32_t num_bits; - struct FixedBaseScalarMul { - Circuit::MemoryAddress low; - Circuit::MemoryAddress high; - Circuit::HeapArray result; + friend bool operator==(const FunctionInput&, const FunctionInput&); + std::vector bincodeSerialize() const; + static FunctionInput bincodeDeserialize(std::vector); + }; - friend bool operator==(const FixedBaseScalarMul&, const FixedBaseScalarMul&); - std::vector bincodeSerialize() const; - static FixedBaseScalarMul bincodeDeserialize(std::vector); - }; + struct BlackBoxFuncCall { - struct EmbeddedCurveAdd { - Circuit::MemoryAddress input1_x; - Circuit::MemoryAddress input1_y; - Circuit::MemoryAddress input2_x; - Circuit::MemoryAddress input2_y; - Circuit::HeapArray result; + struct AND { + Circuit::FunctionInput lhs; + Circuit::FunctionInput rhs; + Circuit::Witness output; - friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); + friend bool operator==(const AND&, const AND&); std::vector bincodeSerialize() const; - static EmbeddedCurveAdd bincodeDeserialize(std::vector); + static AND bincodeDeserialize(std::vector); }; - struct BigIntAdd { - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - Circuit::MemoryAddress output; + struct XOR { + Circuit::FunctionInput lhs; + Circuit::FunctionInput rhs; + Circuit::Witness output; - friend bool operator==(const BigIntAdd&, const BigIntAdd&); + friend bool operator==(const XOR&, const XOR&); std::vector bincodeSerialize() const; - static BigIntAdd bincodeDeserialize(std::vector); + static XOR bincodeDeserialize(std::vector); }; - struct BigIntSub { - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - Circuit::MemoryAddress output; + struct RANGE { + Circuit::FunctionInput input; - friend bool operator==(const BigIntSub&, const BigIntSub&); + friend bool operator==(const RANGE&, const RANGE&); std::vector bincodeSerialize() const; - static BigIntSub bincodeDeserialize(std::vector); + static RANGE bincodeDeserialize(std::vector); }; - struct BigIntMul { - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - Circuit::MemoryAddress output; + struct SHA256 { + std::vector inputs; + std::vector outputs; - friend bool operator==(const BigIntMul&, const BigIntMul&); + friend bool operator==(const SHA256&, const SHA256&); std::vector bincodeSerialize() const; - static BigIntMul bincodeDeserialize(std::vector); + static SHA256 bincodeDeserialize(std::vector); }; - struct BigIntDiv { - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; - Circuit::MemoryAddress output; + struct Blake2s { + std::vector inputs; + std::vector outputs; - friend bool operator==(const BigIntDiv&, const BigIntDiv&); + friend bool operator==(const Blake2s&, const Blake2s&); std::vector bincodeSerialize() const; - static BigIntDiv bincodeDeserialize(std::vector); + static Blake2s bincodeDeserialize(std::vector); }; - struct BigIntFromLeBytes { - Circuit::HeapVector inputs; - Circuit::HeapVector modulus; - Circuit::MemoryAddress output; + struct Blake3 { + std::vector inputs; + std::vector outputs; - friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); + friend bool operator==(const Blake3&, const Blake3&); std::vector bincodeSerialize() const; - static BigIntFromLeBytes bincodeDeserialize(std::vector); + static Blake3 bincodeDeserialize(std::vector); }; - struct BigIntToLeBytes { - Circuit::MemoryAddress input; - Circuit::HeapVector output; + struct SchnorrVerify { + Circuit::FunctionInput public_key_x; + Circuit::FunctionInput public_key_y; + std::vector signature; + std::vector message; + Circuit::Witness output; - friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); + friend bool operator==(const SchnorrVerify&, const SchnorrVerify&); std::vector bincodeSerialize() const; - static BigIntToLeBytes bincodeDeserialize(std::vector); + static SchnorrVerify bincodeDeserialize(std::vector); }; - struct Poseidon2Permutation { - Circuit::HeapVector message; - Circuit::HeapArray output; - Circuit::MemoryAddress len; + struct PedersenCommitment { + std::vector inputs; + uint32_t domain_separator; + std::array outputs; - friend bool operator==(const Poseidon2Permutation&, const Poseidon2Permutation&); + friend bool operator==(const PedersenCommitment&, const PedersenCommitment&); std::vector bincodeSerialize() const; - static Poseidon2Permutation bincodeDeserialize(std::vector); + static PedersenCommitment bincodeDeserialize(std::vector); }; - struct Sha256Compression { - Circuit::HeapVector input; - Circuit::HeapVector hash_values; - Circuit::HeapArray output; + struct PedersenHash { + std::vector inputs; + uint32_t domain_separator; + Circuit::Witness output; - friend bool operator==(const Sha256Compression&, const Sha256Compression&); + friend bool operator==(const PedersenHash&, const PedersenHash&); std::vector bincodeSerialize() const; - static Sha256Compression bincodeDeserialize(std::vector); + static PedersenHash bincodeDeserialize(std::vector); }; - std::variant value; - - friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); - std::vector bincodeSerialize() const; - static BlackBoxOp bincodeDeserialize(std::vector); - }; - - struct Value { - std::string inner; - - friend bool operator==(const Value&, const Value&); - std::vector bincodeSerialize() const; - static Value bincodeDeserialize(std::vector); - }; - - struct ValueOrArray { - - struct MemoryAddress { - Circuit::MemoryAddress value; + struct EcdsaSecp256k1 { + std::vector public_key_x; + std::vector public_key_y; + std::vector signature; + std::vector hashed_message; + Circuit::Witness output; - friend bool operator==(const MemoryAddress&, const MemoryAddress&); + friend bool operator==(const EcdsaSecp256k1&, const EcdsaSecp256k1&); std::vector bincodeSerialize() const; - static MemoryAddress bincodeDeserialize(std::vector); + static EcdsaSecp256k1 bincodeDeserialize(std::vector); }; - struct HeapArray { - Circuit::HeapArray value; + struct EcdsaSecp256r1 { + std::vector public_key_x; + std::vector public_key_y; + std::vector signature; + std::vector hashed_message; + Circuit::Witness output; - friend bool operator==(const HeapArray&, const HeapArray&); + friend bool operator==(const EcdsaSecp256r1&, const EcdsaSecp256r1&); std::vector bincodeSerialize() const; - static HeapArray bincodeDeserialize(std::vector); + static EcdsaSecp256r1 bincodeDeserialize(std::vector); }; - struct HeapVector { - Circuit::HeapVector value; + struct FixedBaseScalarMul { + Circuit::FunctionInput low; + Circuit::FunctionInput high; + std::array outputs; - friend bool operator==(const HeapVector&, const HeapVector&); + friend bool operator==(const FixedBaseScalarMul&, const FixedBaseScalarMul&); std::vector bincodeSerialize() const; - static HeapVector bincodeDeserialize(std::vector); + static FixedBaseScalarMul bincodeDeserialize(std::vector); }; - std::variant value; - - friend bool operator==(const ValueOrArray&, const ValueOrArray&); - std::vector bincodeSerialize() const; - static ValueOrArray bincodeDeserialize(std::vector); - }; - - struct BrilligOpcode { - - struct BinaryFieldOp { - Circuit::MemoryAddress destination; - Circuit::BinaryFieldOp op; - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; + struct EmbeddedCurveAdd { + Circuit::FunctionInput input1_x; + Circuit::FunctionInput input1_y; + Circuit::FunctionInput input2_x; + Circuit::FunctionInput input2_y; + std::array outputs; - friend bool operator==(const BinaryFieldOp&, const BinaryFieldOp&); + friend bool operator==(const EmbeddedCurveAdd&, const EmbeddedCurveAdd&); std::vector bincodeSerialize() const; - static BinaryFieldOp bincodeDeserialize(std::vector); + static EmbeddedCurveAdd bincodeDeserialize(std::vector); }; - struct BinaryIntOp { - Circuit::MemoryAddress destination; - Circuit::BinaryIntOp op; - uint32_t bit_size; - Circuit::MemoryAddress lhs; - Circuit::MemoryAddress rhs; + struct Keccak256 { + std::vector inputs; + std::vector outputs; - friend bool operator==(const BinaryIntOp&, const BinaryIntOp&); + friend bool operator==(const Keccak256&, const Keccak256&); std::vector bincodeSerialize() const; - static BinaryIntOp bincodeDeserialize(std::vector); + static Keccak256 bincodeDeserialize(std::vector); }; - struct JumpIfNot { - Circuit::MemoryAddress condition; - uint64_t location; + struct Keccak256VariableLength { + std::vector inputs; + Circuit::FunctionInput var_message_size; + std::vector outputs; - friend bool operator==(const JumpIfNot&, const JumpIfNot&); + friend bool operator==(const Keccak256VariableLength&, const Keccak256VariableLength&); std::vector bincodeSerialize() const; - static JumpIfNot bincodeDeserialize(std::vector); + static Keccak256VariableLength bincodeDeserialize(std::vector); }; - struct JumpIf { - Circuit::MemoryAddress condition; - uint64_t location; + struct Keccakf1600 { + std::vector inputs; + std::vector outputs; - friend bool operator==(const JumpIf&, const JumpIf&); + friend bool operator==(const Keccakf1600&, const Keccakf1600&); std::vector bincodeSerialize() const; - static JumpIf bincodeDeserialize(std::vector); + static Keccakf1600 bincodeDeserialize(std::vector); }; - struct Jump { - uint64_t location; + struct RecursiveAggregation { + std::vector verification_key; + std::vector proof; + std::vector public_inputs; + Circuit::FunctionInput key_hash; - friend bool operator==(const Jump&, const Jump&); + friend bool operator==(const RecursiveAggregation&, const RecursiveAggregation&); std::vector bincodeSerialize() const; - static Jump bincodeDeserialize(std::vector); + static RecursiveAggregation bincodeDeserialize(std::vector); }; - struct CalldataCopy { - Circuit::MemoryAddress destination_address; - uint64_t size; - uint64_t offset; + struct BigIntAdd { + uint32_t lhs; + uint32_t rhs; + uint32_t output; - friend bool operator==(const CalldataCopy&, const CalldataCopy&); + friend bool operator==(const BigIntAdd&, const BigIntAdd&); std::vector bincodeSerialize() const; - static CalldataCopy bincodeDeserialize(std::vector); + static BigIntAdd bincodeDeserialize(std::vector); }; - struct Call { - uint64_t location; + struct BigIntSub { + uint32_t lhs; + uint32_t rhs; + uint32_t output; - friend bool operator==(const Call&, const Call&); + friend bool operator==(const BigIntSub&, const BigIntSub&); std::vector bincodeSerialize() const; - static Call bincodeDeserialize(std::vector); + static BigIntSub bincodeDeserialize(std::vector); }; - struct Const { - Circuit::MemoryAddress destination; - uint32_t bit_size; - Circuit::Value value; + struct BigIntMul { + uint32_t lhs; + uint32_t rhs; + uint32_t output; - friend bool operator==(const Const&, const Const&); + friend bool operator==(const BigIntMul&, const BigIntMul&); std::vector bincodeSerialize() const; - static Const bincodeDeserialize(std::vector); + static BigIntMul bincodeDeserialize(std::vector); }; - struct Return { - friend bool operator==(const Return&, const Return&); + struct BigIntDiv { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntDiv&, const BigIntDiv&); std::vector bincodeSerialize() const; - static Return bincodeDeserialize(std::vector); + static BigIntDiv bincodeDeserialize(std::vector); }; - struct ForeignCall { - std::string function; - std::vector destinations; - std::vector inputs; + struct BigIntFromLeBytes { + std::vector inputs; + std::vector modulus; + uint32_t output; - friend bool operator==(const ForeignCall&, const ForeignCall&); + friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); std::vector bincodeSerialize() const; - static ForeignCall bincodeDeserialize(std::vector); + static BigIntFromLeBytes bincodeDeserialize(std::vector); }; - struct Mov { - Circuit::MemoryAddress destination; - Circuit::MemoryAddress source; + struct BigIntToLeBytes { + uint32_t input; + std::vector outputs; - friend bool operator==(const Mov&, const Mov&); + friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); std::vector bincodeSerialize() const; - static Mov bincodeDeserialize(std::vector); + static BigIntToLeBytes bincodeDeserialize(std::vector); }; - struct Load { - Circuit::MemoryAddress destination; - Circuit::MemoryAddress source_pointer; + struct Poseidon2Permutation { + std::vector inputs; + std::vector outputs; + uint32_t len; - friend bool operator==(const Load&, const Load&); + friend bool operator==(const Poseidon2Permutation&, const Poseidon2Permutation&); std::vector bincodeSerialize() const; - static Load bincodeDeserialize(std::vector); + static Poseidon2Permutation bincodeDeserialize(std::vector); }; - struct Store { - Circuit::MemoryAddress destination_pointer; - Circuit::MemoryAddress source; + struct Sha256Compression { + std::vector inputs; + std::vector hash_values; + std::vector outputs; - friend bool operator==(const Store&, const Store&); + friend bool operator==(const Sha256Compression&, const Sha256Compression&); std::vector bincodeSerialize() const; - static Store bincodeDeserialize(std::vector); + static Sha256Compression bincodeDeserialize(std::vector); }; - struct BlackBox { - Circuit::BlackBoxOp value; + std::variant value; - friend bool operator==(const BlackBox&, const BlackBox&); + friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&); + std::vector bincodeSerialize() const; + static BlackBoxFuncCall bincodeDeserialize(std::vector); + }; + + struct BlockId { + uint32_t value; + + friend bool operator==(const BlockId&, const BlockId&); + std::vector bincodeSerialize() const; + static BlockId bincodeDeserialize(std::vector); + }; + + struct Expression { + std::vector> mul_terms; + std::vector> linear_combinations; + std::string q_c; + + friend bool operator==(const Expression&, const Expression&); + std::vector bincodeSerialize() const; + static Expression bincodeDeserialize(std::vector); + }; + + struct BrilligInputs { + + struct Single { + Circuit::Expression value; + + friend bool operator==(const Single&, const Single&); std::vector bincodeSerialize() const; - static BlackBox bincodeDeserialize(std::vector); + static Single bincodeDeserialize(std::vector); }; - struct Trap { - friend bool operator==(const Trap&, const Trap&); + struct Array { + std::vector value; + + friend bool operator==(const Array&, const Array&); std::vector bincodeSerialize() const; - static Trap bincodeDeserialize(std::vector); + static Array bincodeDeserialize(std::vector); }; - struct Stop { - uint64_t return_data_offset; - uint64_t return_data_size; + struct MemoryArray { + Circuit::BlockId value; - friend bool operator==(const Stop&, const Stop&); + friend bool operator==(const MemoryArray&, const MemoryArray&); std::vector bincodeSerialize() const; - static Stop bincodeDeserialize(std::vector); + static MemoryArray bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; - friend bool operator==(const BrilligOpcode&, const BrilligOpcode&); + friend bool operator==(const BrilligInputs&, const BrilligInputs&); std::vector bincodeSerialize() const; - static BrilligOpcode bincodeDeserialize(std::vector); + static BrilligInputs bincodeDeserialize(std::vector); }; struct BrilligOutputs { @@ -4561,7 +4597,9 @@ namespace Circuit { inline bool operator==(const BrilligOpcode::ForeignCall &lhs, const BrilligOpcode::ForeignCall &rhs) { if (!(lhs.function == rhs.function)) { return false; } if (!(lhs.destinations == rhs.destinations)) { return false; } + if (!(lhs.destination_value_types == rhs.destination_value_types)) { return false; } if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.input_value_types == rhs.input_value_types)) { return false; } return true; } @@ -4587,7 +4625,9 @@ template void serde::Serializable::serialize(const Circuit::BrilligOpcode::ForeignCall &obj, Serializer &serializer) { serde::Serializable::serialize(obj.function, serializer); serde::Serializable::serialize(obj.destinations, serializer); + serde::Serializable::serialize(obj.destination_value_types, serializer); serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.input_value_types, serializer); } template <> @@ -4596,7 +4636,9 @@ Circuit::BrilligOpcode::ForeignCall serde::Deserializable::deserialize(deserializer); obj.destinations = serde::Deserializable::deserialize(deserializer); + obj.destination_value_types = serde::Deserializable::deserialize(deserializer); obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.input_value_types = serde::Deserializable::deserialize(deserializer); return obj; } @@ -5404,6 +5446,162 @@ Circuit::HeapArray serde::Deserializable::deserialize(Deseri return obj; } +namespace Circuit { + + inline bool operator==(const HeapValueType &lhs, const HeapValueType &rhs) { + if (!(lhs.value == rhs.value)) { return false; } + return true; + } + + inline std::vector HeapValueType::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline HeapValueType HeapValueType::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::HeapValueType &obj, Serializer &serializer) { + serializer.increase_container_depth(); + serde::Serializable::serialize(obj.value, serializer); + serializer.decrease_container_depth(); +} + +template <> +template +Circuit::HeapValueType serde::Deserializable::deserialize(Deserializer &deserializer) { + deserializer.increase_container_depth(); + Circuit::HeapValueType obj; + obj.value = serde::Deserializable::deserialize(deserializer); + deserializer.decrease_container_depth(); + return obj; +} + +namespace Circuit { + + inline bool operator==(const HeapValueType::Simple &lhs, const HeapValueType::Simple &rhs) { + return true; + } + + inline std::vector HeapValueType::Simple::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline HeapValueType::Simple HeapValueType::Simple::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::HeapValueType::Simple &obj, Serializer &serializer) { +} + +template <> +template +Circuit::HeapValueType::Simple serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::HeapValueType::Simple obj; + return obj; +} + +namespace Circuit { + + inline bool operator==(const HeapValueType::Array &lhs, const HeapValueType::Array &rhs) { + if (!(lhs.value_types == rhs.value_types)) { return false; } + if (!(lhs.size == rhs.size)) { return false; } + return true; + } + + inline std::vector HeapValueType::Array::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline HeapValueType::Array HeapValueType::Array::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::HeapValueType::Array &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.value_types, serializer); + serde::Serializable::serialize(obj.size, serializer); +} + +template <> +template +Circuit::HeapValueType::Array serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::HeapValueType::Array obj; + obj.value_types = serde::Deserializable::deserialize(deserializer); + obj.size = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const HeapValueType::Vector &lhs, const HeapValueType::Vector &rhs) { + if (!(lhs.value_types == rhs.value_types)) { return false; } + return true; + } + + inline std::vector HeapValueType::Vector::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline HeapValueType::Vector HeapValueType::Vector::bincodeDeserialize(std::vector input) { + auto deserializer = serde::BincodeDeserializer(input); + auto value = serde::Deserializable::deserialize(deserializer); + if (deserializer.get_buffer_offset() < input.size()) { + throw serde::deserialization_error("Some input bytes were not read"); + } + return value; + } + +} // end of namespace Circuit + +template <> +template +void serde::Serializable::serialize(const Circuit::HeapValueType::Vector &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.value_types, serializer); +} + +template <> +template +Circuit::HeapValueType::Vector serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::HeapValueType::Vector obj; + obj.value_types = serde::Deserializable::deserialize(deserializer); + return obj; +} + namespace Circuit { inline bool operator==(const HeapVector &lhs, const HeapVector &rhs) { diff --git a/noir/acvm-repo/acir/src/circuit/black_box_functions.rs b/noir/acvm-repo/acir/src/circuit/black_box_functions.rs index 59a76b46a12..0a7ee244a5e 100644 --- a/noir/acvm-repo/acir/src/circuit/black_box_functions.rs +++ b/noir/acvm-repo/acir/src/circuit/black_box_functions.rs @@ -91,7 +91,7 @@ impl BlackBoxFunc { BlackBoxFunc::RecursiveAggregation => "recursive_aggregation", BlackBoxFunc::EcdsaSecp256r1 => "ecdsa_secp256r1", BlackBoxFunc::BigIntAdd => "bigint_add", - BlackBoxFunc::BigIntSub => "bigint_neg", + BlackBoxFunc::BigIntSub => "bigint_sub", BlackBoxFunc::BigIntMul => "bigint_mul", BlackBoxFunc::BigIntDiv => "bigint_div", BlackBoxFunc::BigIntFromLeBytes => "bigint_from_le_bytes", diff --git a/noir/acvm-repo/acir/src/circuit/brillig.rs b/noir/acvm-repo/acir/src/circuit/brillig.rs index 1a636fa32bc..f394a46ff82 100644 --- a/noir/acvm-repo/acir/src/circuit/brillig.rs +++ b/noir/acvm-repo/acir/src/circuit/brillig.rs @@ -1,7 +1,7 @@ +use super::opcodes::BlockId; use crate::native_types::{Expression, Witness}; use brillig::Opcode as BrilligOpcode; use serde::{Deserialize, Serialize}; -use super::opcodes::BlockId; /// Inputs for the Brillig VM. These are the initial inputs /// that the Brillig VM will use to start. @@ -9,7 +9,7 @@ use super::opcodes::BlockId; pub enum BrilligInputs { Single(Expression), Array(Vec), - MemoryArray(BlockId) + MemoryArray(BlockId), } /// Outputs for the Brillig VM. Once the VM has completed diff --git a/noir/acvm-repo/acir/src/lib.rs b/noir/acvm-repo/acir/src/lib.rs index aac01400290..c7be5026850 100644 --- a/noir/acvm-repo/acir/src/lib.rs +++ b/noir/acvm-repo/acir/src/lib.rs @@ -31,7 +31,10 @@ mod reflection { path::{Path, PathBuf}, }; - use brillig::{BinaryFieldOp, BinaryIntOp, BlackBoxOp, Opcode as BrilligOpcode, ValueOrArray}; + use brillig::{ + BinaryFieldOp, BinaryIntOp, BlackBoxOp, HeapValueType, Opcode as BrilligOpcode, + ValueOrArray, + }; use serde_reflection::{Tracer, TracerConfig}; use crate::{ @@ -69,6 +72,7 @@ mod reflection { tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); tracer.trace_simple_type::().unwrap(); + tracer.trace_simple_type::().unwrap(); let registry = tracer.registry().unwrap(); diff --git a/noir/acvm-repo/acir/tests/test_program_serialization.rs b/noir/acvm-repo/acir/tests/test_program_serialization.rs index 9387c7c4f77..6a73522c822 100644 --- a/noir/acvm-repo/acir/tests/test_program_serialization.rs +++ b/noir/acvm-repo/acir/tests/test_program_serialization.rs @@ -20,7 +20,7 @@ use acir::{ native_types::{Expression, Witness}, }; use acir_field::FieldElement; -use brillig::{HeapArray, MemoryAddress, ValueOrArray}; +use brillig::{HeapArray, HeapValueType, MemoryAddress, ValueOrArray}; #[test] fn addition_circuit() { @@ -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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 208, 49, 14, 192, 32, 8, 5, 80, 212, 30, 8, 4, 20, + 182, 94, 165, 166, 122, 255, 35, 52, 77, 28, 76, 58, 214, 191, 124, 166, 23, 242, 15, 0, 8, + 240, 77, 154, 125, 206, 198, 127, 161, 176, 209, 138, 139, 197, 88, 68, 122, 205, 157, 152, + 46, 204, 222, 76, 81, 180, 21, 35, 35, 53, 189, 179, 49, 119, 19, 171, 222, 188, 162, 147, + 112, 167, 161, 206, 99, 98, 105, 223, 95, 248, 26, 113, 90, 97, 185, 97, 217, 56, 173, 35, + 63, 243, 81, 87, 163, 125, 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 138, 91, 10, 0, 32, 16, 2, 109, 171, 175, 46, 221, + 209, 247, 229, 130, 130, 140, 200, 92, 0, 11, 157, 228, 35, 127, 212, 200, 29, 61, 116, 76, + 220, 217, 250, 171, 91, 113, 160, 66, 104, 242, 97, 0, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -102,9 +102,9 @@ fn pedersen_circuit() { let bytes = Circuit::serialize_circuit(&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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 74, 135, 9, 0, 48, 8, 75, 171, 224, 255, 15, 139, + 27, 196, 64, 200, 100, 0, 15, 133, 80, 57, 89, 219, 127, 39, 173, 126, 235, 236, 247, 151, + 48, 224, 71, 90, 33, 97, 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 210, 7, 74, 3, 1, 20, 69, 209, 177, 247, 222, 123, + 239, 189, 119, 141, 93, 99, 220, 133, 251, 95, 130, 152, 103, 78, 32, 3, 195, 33, 4, 66, + 248, 239, 254, 20, 69, 209, 84, 212, 158, 216, 206, 223, 234, 219, 204, 146, 239, 91, 170, + 111, 103, 245, 109, 101, 27, 219, 217, 193, 250, 219, 197, 110, 246, 176, 151, 125, 236, + 231, 0, 7, 57, 196, 97, 142, 112, 148, 99, 28, 231, 4, 39, 57, 197, 105, 206, 112, 150, + 115, 156, 231, 2, 23, 185, 196, 101, 174, 112, 149, 107, 92, 231, 6, 55, 185, 197, 109, + 238, 112, 151, 123, 220, 231, 1, 15, 121, 196, 99, 158, 240, 148, 103, 60, 231, 5, 47, 121, + 197, 107, 222, 240, 150, 119, 188, 231, 3, 75, 124, 228, 83, 195, 142, 121, 158, 125, 126, + 225, 43, 223, 248, 206, 15, 126, 178, 204, 47, 86, 248, 237, 119, 43, 76, 127, 105, 47, + 189, 165, 181, 116, 150, 198, 234, 125, 117, 249, 47, 233, 41, 45, 165, 163, 52, 148, 126, + 210, 78, 186, 73, 51, 233, 37, 173, 164, 147, 52, 146, 62, 210, 70, 186, 72, 19, 233, 33, + 45, 164, 131, 52, 144, 253, 23, 139, 218, 238, 217, 60, 123, 103, 235, 236, 156, 141, 179, + 239, 166, 93, 183, 237, 185, 107, 199, 125, 251, 29, 218, 237, 216, 94, 167, 118, 58, 183, + 207, 165, 93, 174, 237, 113, 107, 135, 123, 247, 47, 185, 251, 147, 59, 191, 184, 239, 155, + 187, 126, 184, 103, 217, 29, 235, 55, 171, 223, 173, 104, 184, 231, 255, 243, 7, 236, 52, + 239, 128, 225, 3, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -186,7 +186,9 @@ fn simple_brillig_foreign_call() { brillig::Opcode::ForeignCall { function: "invert".into(), destinations: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(0))], + destination_value_types: vec![HeapValueType::Simple], inputs: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(0))], + input_value_types: vec![HeapValueType::Simple], }, brillig::Opcode::Stop { return_data_offset: 0, return_data_size: 1 }, ], @@ -204,11 +206,11 @@ fn simple_brillig_foreign_call() { let bytes = Circuit::serialize_circuit(&circuit); 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 143, 65, 10, 192, 32, 12, 4, 215, 148, 150, 246, + 212, 175, 216, 31, 244, 51, 61, 244, 226, 65, 196, 247, 171, 24, 33, 136, 122, 209, 129, + 144, 176, 132, 101, 247, 4, 160, 144, 217, 196, 45, 41, 218, 203, 91, 207, 241, 168, 117, + 94, 90, 230, 37, 238, 144, 216, 27, 249, 11, 87, 156, 131, 239, 223, 248, 207, 186, 81, + 235, 150, 67, 173, 221, 189, 95, 18, 34, 97, 64, 0, 116, 135, 40, 214, 136, 1, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -272,11 +274,20 @@ fn complex_brillig_foreign_call() { ValueOrArray::HeapArray(HeapArray { pointer: 0.into(), size: 3 }), ValueOrArray::MemoryAddress(MemoryAddress::from(1)), ], + input_value_types: vec![ + HeapValueType::Array { size: 3, value_types: vec![HeapValueType::Simple] }, + HeapValueType::Simple, + ], destinations: vec![ ValueOrArray::HeapArray(HeapArray { pointer: 0.into(), size: 3 }), ValueOrArray::MemoryAddress(MemoryAddress::from(35)), ValueOrArray::MemoryAddress(MemoryAddress::from(36)), ], + destination_value_types: vec![ + HeapValueType::Array { size: 3, value_types: vec![HeapValueType::Simple] }, + HeapValueType::Simple, + HeapValueType::Simple, + ], }, brillig::Opcode::Stop { return_data_offset: 32, return_data_size: 5 }, ], @@ -294,14 +305,15 @@ 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 84, 73, 14, 131, 48, 12, 28, 147, 166, 165, 167, + 126, 161, 82, 251, 128, 180, 47, 224, 47, 85, 111, 32, 56, 242, 124, 130, 24, 68, 176, 2, + 23, 130, 4, 35, 89, 206, 50, 137, 71, 182, 147, 28, 128, 96, 128, 241, 150, 113, 44, 156, + 135, 24, 121, 5, 189, 219, 134, 143, 164, 187, 203, 237, 165, 49, 59, 129, 70, 179, 131, + 198, 177, 31, 14, 90, 239, 148, 117, 73, 154, 63, 19, 121, 63, 23, 111, 214, 219, 149, 243, + 27, 125, 206, 117, 208, 63, 85, 222, 161, 248, 32, 167, 72, 162, 245, 235, 44, 166, 94, 20, + 21, 251, 30, 196, 253, 213, 85, 83, 254, 91, 163, 168, 90, 234, 43, 24, 191, 213, 190, 172, + 156, 235, 17, 126, 59, 49, 142, 68, 120, 75, 220, 7, 166, 84, 90, 68, 72, 194, 139, 180, + 136, 25, 58, 46, 103, 45, 188, 25, 5, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -333,11 +345,10 @@ 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 145, 187, 17, 0, 32, 8, 67, 195, 111, 31, 220, 192, + 253, 167, 178, 144, 2, 239, 236, 132, 194, 52, 129, 230, 93, 8, 6, 64, 176, 101, 225, 28, + 78, 49, 43, 238, 154, 225, 254, 166, 209, 205, 165, 98, 174, 212, 177, 188, 187, 92, 255, + 173, 92, 173, 190, 93, 82, 80, 78, 123, 14, 127, 60, 97, 1, 210, 144, 46, 242, 19, 3, 0, 0, ]; assert_eq!(bytes, expected_serialization) diff --git a/noir/acvm-repo/acvm/src/pwg/brillig.rs b/noir/acvm-repo/acvm/src/pwg/brillig.rs index 69e52b6dfb4..c5a98aaf01c 100644 --- a/noir/acvm-repo/acvm/src/pwg/brillig.rs +++ b/noir/acvm-repo/acvm/src/pwg/brillig.rs @@ -3,7 +3,9 @@ use std::collections::HashMap; use acir::{ brillig::{ForeignCallParam, ForeignCallResult, Value}, circuit::{ - brillig::{Brillig, BrilligInputs, BrilligOutputs}, opcodes::BlockId, OpcodeLocation + brillig::{Brillig, BrilligInputs, BrilligOutputs}, + opcodes::BlockId, + OpcodeLocation, }, native_types::WitnessMap, FieldElement, @@ -98,11 +100,16 @@ impl<'b, B: BlackBoxFunctionSolver> BrilligSolver<'b, B> { } } } - }, + } BrilligInputs::MemoryArray(block_id) => { - let memory_block = memory.get(block_id).ok_or(OpcodeNotSolvable::MissingMemoryBlock(block_id.0))?; + let memory_block = memory + .get(block_id) + .ok_or(OpcodeNotSolvable::MissingMemoryBlock(block_id.0))?; for memory_index in 0..memory_block.block_len { - let memory_value = memory_block.block_value.get(&memory_index).expect("All memory is initialized on creation"); + let memory_value = memory_block + .block_value + .get(&memory_index) + .expect("All memory is initialized on creation"); calldata.push((*memory_value).into()); } } diff --git a/noir/acvm-repo/acvm/src/pwg/mod.rs b/noir/acvm-repo/acvm/src/pwg/mod.rs index d28f9134d98..2ee39a289e7 100644 --- a/noir/acvm-repo/acvm/src/pwg/mod.rs +++ b/noir/acvm-repo/acvm/src/pwg/mod.rs @@ -338,7 +338,13 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { // there will be a cached `BrilligSolver` to avoid recomputation. let mut solver: BrilligSolver<'_, B> = match self.brillig_solver.take() { Some(solver) => solver, - None => BrilligSolver::new(witness, &self.block_solvers, brillig, self.backend, self.instruction_pointer)?, + None => BrilligSolver::new( + witness, + &self.block_solvers, + brillig, + self.backend, + self.instruction_pointer, + )?, }; match solver.solve()? { BrilligSolverStatus::ForeignCallWait(foreign_call) => { @@ -373,7 +379,13 @@ impl<'a, B: BlackBoxFunctionSolver> ACVM<'a, B> { return StepResult::Status(self.handle_opcode_resolution(resolution)); } - let solver = BrilligSolver::new(witness, &self.block_solvers, brillig, self.backend, self.instruction_pointer); + let solver = BrilligSolver::new( + witness, + &self.block_solvers, + brillig, + self.backend, + self.instruction_pointer, + ); match solver { Ok(solver) => StepResult::IntoBrillig(solver), Err(..) => StepResult::Status(self.handle_opcode_resolution(solver.map(|_| ()))), diff --git a/noir/acvm-repo/acvm/tests/solver.rs b/noir/acvm-repo/acvm/tests/solver.rs index 9ff4a4f4897..b267c3005a8 100644 --- a/noir/acvm-repo/acvm/tests/solver.rs +++ b/noir/acvm-repo/acvm/tests/solver.rs @@ -13,6 +13,7 @@ use acir::{ use acvm::pwg::{ACVMStatus, ErrorLocation, ForeignCallWaitInfo, OpcodeResolutionError, ACVM}; use acvm_blackbox_solver::StubbedBlackBoxSolver; +use brillig_vm::brillig::HeapValueType; // Reenable these test cases once we move the brillig implementation of inversion down into the acvm stdlib. @@ -69,7 +70,9 @@ fn inversion_brillig_oracle_equivalence() { BrilligOpcode::ForeignCall { function: "invert".into(), destinations: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(1))], + destination_value_types: vec![HeapValueType::Simple], inputs: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(0))], + input_value_types: vec![HeapValueType::Simple], }, BrilligOpcode::Stop { return_data_offset: 0, return_data_size: 3 }, ], @@ -196,12 +199,16 @@ fn double_inversion_brillig_oracle() { BrilligOpcode::ForeignCall { function: "invert".into(), destinations: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(1))], + destination_value_types: vec![HeapValueType::Simple], inputs: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(0))], + input_value_types: vec![HeapValueType::Simple], }, BrilligOpcode::ForeignCall { function: "invert".into(), destinations: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(3))], + destination_value_types: vec![HeapValueType::Simple], inputs: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(2))], + input_value_types: vec![HeapValueType::Simple], }, BrilligOpcode::Stop { return_data_offset: 0, return_data_size: 5 }, ], @@ -327,12 +334,16 @@ fn oracle_dependent_execution() { BrilligOpcode::ForeignCall { function: "invert".into(), destinations: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(1))], + destination_value_types: vec![HeapValueType::Simple], inputs: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(0))], + input_value_types: vec![HeapValueType::Simple], }, BrilligOpcode::ForeignCall { function: "invert".into(), destinations: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(3))], + destination_value_types: vec![HeapValueType::Simple], inputs: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(2))], + input_value_types: vec![HeapValueType::Simple], }, BrilligOpcode::Stop { return_data_offset: 0, return_data_size: 4 }, ], @@ -453,7 +464,9 @@ fn brillig_oracle_predicate() { BrilligOpcode::ForeignCall { function: "invert".into(), destinations: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(1))], + destination_value_types: vec![HeapValueType::Simple], inputs: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(0))], + input_value_types: vec![HeapValueType::Simple], }, ], predicate: Some(Expression::default()), diff --git a/noir/acvm-repo/acvm_js/test/shared/addition.ts b/noir/acvm-repo/acvm_js/test/shared/addition.ts index ae3a2e2c35b..217902bdea6 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 208, 49, 14, 192, 32, 8, 5, 80, 212, 30, 8, 4, 20, 182, 94, 165, 166, 122, + 255, 35, 52, 77, 28, 76, 58, 214, 191, 124, 166, 23, 242, 15, 0, 8, 240, 77, 154, 125, 206, 198, 127, 161, 176, 209, + 138, 139, 197, 88, 68, 122, 205, 157, 152, 46, 204, 222, 76, 81, 180, 21, 35, 35, 53, 189, 179, 49, 119, 19, 171, 222, + 188, 162, 147, 112, 167, 161, 206, 99, 98, 105, 223, 95, 248, 26, 113, 90, 97, 185, 97, 217, 56, 173, 35, 63, 243, 81, + 87, 163, 125, 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 d30413212c5..07c343c5ba0 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,13 +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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 84, 73, 14, 131, 48, 12, 28, 147, 166, 165, 167, 126, 161, 82, 251, 128, 180, + 47, 224, 47, 85, 111, 32, 56, 242, 124, 130, 24, 68, 176, 2, 23, 130, 4, 35, 89, 206, 50, 137, 71, 182, 147, 28, 128, + 96, 128, 241, 150, 113, 44, 156, 135, 24, 121, 5, 189, 219, 134, 143, 164, 187, 203, 237, 165, 49, 59, 129, 70, 179, + 131, 198, 177, 31, 14, 90, 239, 148, 117, 73, 154, 63, 19, 121, 63, 23, 111, 214, 219, 149, 243, 27, 125, 206, 117, + 208, 63, 85, 222, 161, 248, 32, 167, 72, 162, 245, 235, 44, 166, 94, 20, 21, 251, 30, 196, 253, 213, 85, 83, 254, 91, + 163, 168, 90, 234, 43, 24, 191, 213, 190, 172, 156, 235, 17, 126, 59, 49, 142, 68, 120, 75, 220, 7, 166, 84, 90, 68, + 72, 194, 139, 180, 136, 25, 58, 46, 103, 45, 188, 25, 5, 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 2f643578518..c0859f50135 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 138, 91, 10, 0, 32, 16, 2, 109, 171, 175, 46, 221, 209, 247, 229, 130, 130, + 140, 200, 92, 0, 11, 157, 228, 35, 127, 212, 200, 29, 61, 116, 76, 220, 217, 250, 171, 91, 113, 160, 66, 104, 242, 97, + 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 817356ccfc5..cfa7c679b18 100644 --- a/noir/acvm-repo/acvm_js/test/shared/foreign_call.ts +++ b/noir/acvm-repo/acvm_js/test/shared/foreign_call.ts @@ -2,10 +2,10 @@ 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 173, 143, 65, 10, 192, 32, 12, 4, 215, 148, 150, 246, 212, 175, 216, 31, 244, 51, + 61, 244, 226, 65, 196, 247, 171, 24, 33, 136, 122, 209, 129, 144, 176, 132, 101, 247, 4, 160, 144, 217, 196, 45, 41, + 218, 203, 91, 207, 241, 168, 117, 94, 90, 230, 37, 238, 144, 216, 27, 249, 11, 87, 156, 131, 239, 223, 248, 207, 186, + 81, 235, 150, 67, 173, 221, 189, 95, 18, 34, 97, 64, 0, 116, 135, 40, 214, 136, 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 8c21e00b4a7..b5ab64b3447 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 213, 145, 187, 17, 0, 32, 8, 67, 195, 111, 31, 220, 192, 253, 167, 178, 144, 2, + 239, 236, 132, 194, 52, 129, 230, 93, 8, 6, 64, 176, 101, 225, 28, 78, 49, 43, 238, 154, 225, 254, 166, 209, 205, 165, + 98, 174, 212, 177, 188, 187, 92, 255, 173, 92, 173, 190, 93, 82, 80, 78, 123, 14, 127, 60, 97, 1, 210, 144, 46, 242, + 19, 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 2d5ce62b4c2..5150d24131c 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 74, 135, 9, 0, 48, 8, 75, 171, 224, 255, 15, 139, 27, 196, 64, 200, 100, 0, 15, + 133, 80, 57, 89, 219, 127, 39, 173, 126, 235, 236, 247, 151, 48, 224, 71, 90, 33, 97, 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 92b0f4fb0b5..2127de66f69 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, 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, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 77, 210, 7, 74, 3, 1, 20, 69, 209, 177, 247, 222, 123, 239, 189, 119, 141, 93, 99, + 220, 133, 251, 95, 130, 152, 103, 78, 32, 3, 195, 33, 4, 66, 248, 239, 254, 20, 69, 209, 84, 212, 158, 216, 206, 223, + 234, 219, 204, 146, 239, 91, 170, 111, 103, 245, 109, 101, 27, 219, 217, 193, 250, 219, 197, 110, 246, 176, 151, 125, + 236, 231, 0, 7, 57, 196, 97, 142, 112, 148, 99, 28, 231, 4, 39, 57, 197, 105, 206, 112, 150, 115, 156, 231, 2, 23, + 185, 196, 101, 174, 112, 149, 107, 92, 231, 6, 55, 185, 197, 109, 238, 112, 151, 123, 220, 231, 1, 15, 121, 196, 99, + 158, 240, 148, 103, 60, 231, 5, 47, 121, 197, 107, 222, 240, 150, 119, 188, 231, 3, 75, 124, 228, 83, 195, 142, 121, + 158, 125, 126, 225, 43, 223, 248, 206, 15, 126, 178, 204, 47, 86, 248, 237, 119, 43, 76, 127, 105, 47, 189, 165, 181, + 116, 150, 198, 234, 125, 117, 249, 47, 233, 41, 45, 165, 163, 52, 148, 126, 210, 78, 186, 73, 51, 233, 37, 173, 164, + 147, 52, 146, 62, 210, 70, 186, 72, 19, 233, 33, 45, 164, 131, 52, 144, 253, 23, 139, 218, 238, 217, 60, 123, 103, + 235, 236, 156, 141, 179, 239, 166, 93, 183, 237, 185, 107, 199, 125, 251, 29, 218, 237, 216, 94, 167, 118, 58, 183, + 207, 165, 93, 174, 237, 113, 107, 135, 123, 247, 47, 185, 251, 147, 59, 191, 184, 239, 155, 187, 126, 184, 103, 217, + 29, 235, 55, 171, 223, 173, 104, 184, 231, 255, 243, 7, 236, 52, 239, 128, 225, 3, 0, 0, ]); export const initialWitnessMap = new Map([ diff --git a/noir/acvm-repo/brillig/src/lib.rs b/noir/acvm-repo/brillig/src/lib.rs index 2e9d80e2f3b..0661e794360 100644 --- a/noir/acvm-repo/brillig/src/lib.rs +++ b/noir/acvm-repo/brillig/src/lib.rs @@ -17,7 +17,9 @@ mod value; pub use black_box::BlackBoxOp; pub use foreign_call::{ForeignCallParam, ForeignCallResult}; -pub use opcodes::{BinaryFieldOp, BinaryIntOp, HeapArray, HeapVector, MemoryAddress, ValueOrArray}; +pub use opcodes::{ + BinaryFieldOp, BinaryIntOp, HeapArray, HeapValueType, HeapVector, MemoryAddress, ValueOrArray, +}; pub use opcodes::{BrilligOpcode as Opcode, Label}; pub use value::Typ; pub use value::Value; diff --git a/noir/acvm-repo/brillig/src/opcodes.rs b/noir/acvm-repo/brillig/src/opcodes.rs index 9304b82bfa1..06c8fdc04eb 100644 --- a/noir/acvm-repo/brillig/src/opcodes.rs +++ b/noir/acvm-repo/brillig/src/opcodes.rs @@ -19,6 +19,27 @@ impl From for MemoryAddress { } } +/// Describes the memory layout for an array/vector element +#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] +pub enum HeapValueType { + // A single field element is enough to represent the value + Simple, + // The value read should be interpreted as a pointer to a heap array, which + // consists of a pointer to a slice of memory of size elements, and a + // reference count + Array { value_types: Vec, size: usize }, + // The value read should be interpreted as a pointer to a heap vector, which + // consists of a pointer to a slice of memory, a number of elements in that + // slice, and a reference count + Vector { value_types: Vec }, +} + +impl HeapValueType { + pub fn all_simple(types: &[HeapValueType]) -> bool { + types.iter().all(|typ| matches!(typ, HeapValueType::Simple)) + } +} + /// A fixed-sized array starting from a Brillig memory location. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Copy)] pub struct HeapArray { @@ -118,8 +139,13 @@ pub enum BrilligOpcode { function: String, /// Destination addresses (may be single values or memory pointers). destinations: Vec, + /// Destination value types + destination_value_types: Vec, /// Input addresses (may be single values or memory pointers). inputs: Vec, + /// Input value types (for heap allocated structures indicates how to + /// retrieve the elements) + input_value_types: Vec, }, Mov { destination: MemoryAddress, diff --git a/noir/acvm-repo/brillig_vm/src/lib.rs b/noir/acvm-repo/brillig_vm/src/lib.rs index 93093ab65f9..4292a623cdb 100644 --- a/noir/acvm-repo/brillig_vm/src/lib.rs +++ b/noir/acvm-repo/brillig_vm/src/lib.rs @@ -12,8 +12,8 @@ //! [acvm]: https://crates.io/crates/acvm use acir::brillig::{ - BinaryFieldOp, BinaryIntOp, ForeignCallParam, ForeignCallResult, HeapArray, HeapVector, - MemoryAddress, Opcode, Value, ValueOrArray, + BinaryFieldOp, BinaryIntOp, ForeignCallParam, ForeignCallResult, HeapArray, HeapValueType, + HeapVector, MemoryAddress, Opcode, Value, ValueOrArray, }; use acir::FieldElement; // Re-export `brillig`. @@ -212,7 +212,16 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.fail("return opcode hit, but callstack already empty".to_string()) } } - Opcode::ForeignCall { function, destinations, inputs } => { + Opcode::ForeignCall { + function, + destinations, + destination_value_types, + inputs, + input_value_types, + } => { + assert!(inputs.len() == input_value_types.len()); + assert!(destinations.len() == destination_value_types.len()); + if self.foreign_call_counter >= self.foreign_call_results.len() { // When this opcode is called, it is possible that the results of a foreign call are // not yet known (not enough entries in `foreign_call_results`). @@ -223,7 +232,8 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { // but has the necessary results to proceed with execution. let resolved_inputs = inputs .iter() - .map(|input| self.get_memory_values(*input)) + .zip(input_value_types) + .map(|(input, input_type)| self.get_memory_values(*input, input_type)) .collect::>(); return self.wait_for_foreign_call(function.clone(), resolved_inputs); } @@ -231,48 +241,69 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { let values = &self.foreign_call_results[self.foreign_call_counter].values; let mut invalid_foreign_call_result = false; - for (destination, output) in destinations.iter().zip(values) { - match destination { - ValueOrArray::MemoryAddress(value_index) => match output { - ForeignCallParam::Single(value) => { - self.memory.write(*value_index, *value); - } - _ => unreachable!( - "Function result size does not match brillig bytecode (expected 1 result)" - ), - }, - ValueOrArray::HeapArray(HeapArray { pointer: pointer_index, size }) => { + for ((destination, value_type), output) in + destinations.iter().zip(destination_value_types).zip(values) + { + match (destination, value_type) { + (ValueOrArray::MemoryAddress(value_index), HeapValueType::Simple) => { match output { - ForeignCallParam::Array(values) => { - if values.len() != *size { - invalid_foreign_call_result = true; - break; - } - // Convert the destination pointer to a usize - let destination = self.memory.read_ref(*pointer_index); - // Write to our destination memory - self.memory.write_slice(destination, values); - } - _ => { - unreachable!("Function result size does not match brillig bytecode size") + ForeignCallParam::Single(value) => { + self.memory.write(*value_index, *value); } + _ => unreachable!( + "Function result size does not match brillig bytecode. Expected 1 result but got {output:?}" + ), } } - ValueOrArray::HeapVector(HeapVector { pointer: pointer_index, size: size_index }) => { - match output { - ForeignCallParam::Array(values) => { - // Set our size in the size address - self.memory.write(*size_index, Value::from(values.len())); - // Convert the destination pointer to a usize - let destination = self.memory.read_ref(*pointer_index); - // Write to our destination memory - self.memory.write_slice(destination, values); + ( + ValueOrArray::HeapArray(HeapArray { pointer: pointer_index, size }), + HeapValueType::Array { value_types, size: type_size }, + ) if size == type_size => { + if HeapValueType::all_simple(value_types) { + match output { + ForeignCallParam::Array(values) => { + if values.len() != *size { + invalid_foreign_call_result = true; + break; + } + // Convert the destination pointer to a usize + let destination = self.memory.read_ref(*pointer_index); + // Write to our destination memory + self.memory.write_slice(destination, values); + } + _ => { + unreachable!("Function result size does not match brillig bytecode size") + } } - _ => { - unreachable!("Function result size does not match brillig bytecode size") + } else { + unimplemented!("deflattening heap arrays from foreign calls"); + } + } + ( + ValueOrArray::HeapVector(HeapVector {pointer: pointer_index, size: size_index }), + HeapValueType::Vector { value_types }, + ) => { + if HeapValueType::all_simple(value_types) { + match output { + ForeignCallParam::Array(values) => { + // Set our size in the size address + self.memory.write(*size_index, Value::from(values.len())); + // Convert the destination pointer to a usize + let destination = self.memory.read_ref(*pointer_index); + // Write to our destination memory + self.memory.write_slice(destination, values); + } + _ => { + unreachable!("Function result size does not match brillig bytecode size") + } } + } else { + unimplemented!("deflattening heap vectors from foreign calls"); } } + _ => { + unreachable!("Unexpected value type {value_type:?} for destination {destination:?}"); + } } } @@ -351,18 +382,82 @@ impl<'a, B: BlackBoxFunctionSolver> VM<'a, B> { self.status.clone() } - fn get_memory_values(&self, input: ValueOrArray) -> ForeignCallParam { - match input { - ValueOrArray::MemoryAddress(value_index) => self.memory.read(value_index).into(), - ValueOrArray::HeapArray(HeapArray { pointer: pointer_index, size }) => { + fn get_memory_values( + &self, + input: ValueOrArray, + value_type: &HeapValueType, + ) -> ForeignCallParam { + match (input, value_type) { + (ValueOrArray::MemoryAddress(value_index), HeapValueType::Simple) => { + self.memory.read(value_index).into() + } + ( + ValueOrArray::HeapArray(HeapArray { pointer: pointer_index, size }), + HeapValueType::Array { value_types, size: type_size }, + ) if *type_size == size => { let start = self.memory.read_ref(pointer_index); - self.memory.read_slice(start, size).to_vec().into() + self.read_slice_of_values_from_memory(start, size, value_types).into() } - ValueOrArray::HeapVector(HeapVector { pointer: pointer_index, size: size_index }) => { + ( + ValueOrArray::HeapVector(HeapVector { pointer: pointer_index, size: size_index }), + HeapValueType::Vector { value_types }, + ) => { let start = self.memory.read_ref(pointer_index); - let size = self.memory.read(size_index); - self.memory.read_slice(start, size.to_usize()).to_vec().into() + let size = self.memory.read(size_index).to_usize(); + self.read_slice_of_values_from_memory(start, size, value_types).into() } + _ => { + unreachable!("Unexpected value type {value_type:?} for input {input:?}"); + } + } + } + + /// Reads an array/vector from memory but recursively reads pointers to + /// nested arrays/vectors according to the sequence of value types. + fn read_slice_of_values_from_memory( + &self, + start: MemoryAddress, + size: usize, + value_types: &[HeapValueType], + ) -> Vec { + if HeapValueType::all_simple(value_types) { + self.memory.read_slice(start, size).to_vec() + } else { + // Check that the sequence of value types fit an integer number of + // times inside the given size. + assert!( + 0 == size % value_types.len(), + "array/vector does not contain a whole number of elements" + ); + (0..size) + .zip(value_types.iter().cycle()) + .flat_map(|(i, value_type)| { + let value_address: MemoryAddress = (start.to_usize() + i).into(); + match value_type { + HeapValueType::Simple => { + let value = self.memory.read(value_address); + vec![value] + } + HeapValueType::Array { value_types, size } => { + let array_address = self.memory.read_ref(value_address); + let array_start = self.memory.read_ref(array_address); + self.read_slice_of_values_from_memory(array_start, *size, value_types) + } + HeapValueType::Vector { value_types } => { + let vector_address = self.memory.read_ref(value_address); + let vector_start = self.memory.read_ref(vector_address); + let size_address: MemoryAddress = + (vector_address.to_usize() + 1).into(); + let vector_size = self.memory.read(size_address).to_usize(); + self.read_slice_of_values_from_memory( + vector_start, + vector_size, + value_types, + ) + } + } + }) + .collect::>() } } @@ -1021,7 +1116,9 @@ mod tests { Opcode::ForeignCall { function: "double".into(), destinations: vec![ValueOrArray::MemoryAddress(r_result)], + destination_value_types: vec![HeapValueType::Simple], inputs: vec![ValueOrArray::MemoryAddress(r_input)], + input_value_types: vec![HeapValueType::Simple], }, ]; @@ -1085,10 +1182,18 @@ mod tests { pointer: r_output, size: initial_matrix.len(), })], + destination_value_types: vec![HeapValueType::Array { + size: initial_matrix.len(), + value_types: vec![HeapValueType::Simple], + }], inputs: vec![ValueOrArray::HeapArray(HeapArray { pointer: r_input, size: initial_matrix.len(), })], + input_value_types: vec![HeapValueType::Array { + value_types: vec![HeapValueType::Simple], + size: initial_matrix.len(), + }], }, ]; @@ -1172,10 +1277,16 @@ mod tests { pointer: r_output_pointer, size: r_output_size, })], + destination_value_types: vec![HeapValueType::Vector { + value_types: vec![HeapValueType::Simple], + }], inputs: vec![ValueOrArray::HeapVector(HeapVector { pointer: r_input_pointer, size: r_input_size, })], + input_value_types: vec![HeapValueType::Vector { + value_types: vec![HeapValueType::Simple], + }], }, ]; @@ -1242,10 +1353,18 @@ mod tests { pointer: r_output, size: initial_matrix.len(), })], + destination_value_types: vec![HeapValueType::Array { + size: initial_matrix.len(), + value_types: vec![HeapValueType::Simple], + }], inputs: vec![ValueOrArray::HeapArray(HeapArray { pointer: r_input, size: initial_matrix.len(), })], + input_value_types: vec![HeapValueType::Array { + size: initial_matrix.len(), + value_types: vec![HeapValueType::Simple], + }], }, ]; @@ -1325,10 +1444,24 @@ mod tests { pointer: r_output, size: matrix_a.len(), })], + destination_value_types: vec![HeapValueType::Array { + size: matrix_a.len(), + value_types: vec![HeapValueType::Simple], + }], inputs: vec![ ValueOrArray::HeapArray(HeapArray { pointer: r_input_a, size: matrix_a.len() }), ValueOrArray::HeapArray(HeapArray { pointer: r_input_b, size: matrix_b.len() }), ], + input_value_types: vec![ + HeapValueType::Array { + size: matrix_a.len(), + value_types: vec![HeapValueType::Simple], + }, + HeapValueType::Array { + size: matrix_b.len(), + value_types: vec![HeapValueType::Simple], + }, + ], }, ]; let mut initial_memory = matrix_a.clone(); @@ -1360,4 +1493,121 @@ mod tests { // Ensure the foreign call counter has been incremented assert_eq!(vm.foreign_call_counter, 1); } + + #[test] + fn foreign_call_opcode_nested_arrays_and_slices_input() { + // [(1, <2,3>, [4]), (5, <6,7,8>, [9])] + + let v2 = vec![Value::from(2u128), Value::from(3u128)]; + let a4 = vec![Value::from(4u128)]; + let v6 = vec![Value::from(6u128), Value::from(7u128), Value::from(8u128)]; + let a9 = vec![Value::from(9u128)]; + + // construct memory by declaring all inner arrays/vectors first + let v2_ptr = 0u128; + let mut memory = v2.clone(); + let v2_start = memory.len(); + memory.extend(vec![Value::from(v2_ptr), Value::from(v2.len()), Value::from(1u128)]); + let a4_ptr = memory.len(); + memory.extend(a4.clone()); + let a4_start = memory.len(); + memory.extend(vec![Value::from(a4_ptr), Value::from(1u128)]); + let v6_ptr = memory.len(); + memory.extend(v6.clone()); + let v6_start = memory.len(); + memory.extend(vec![Value::from(v6_ptr), Value::from(v6.len()), Value::from(1u128)]); + let a9_ptr = memory.len(); + memory.extend(a9.clone()); + let a9_start = memory.len(); + memory.extend(vec![Value::from(a9_ptr), Value::from(1u128)]); + // finally we add the contents of the outer array + let outer_ptr = memory.len(); + let outer_array = vec![ + Value::from(1u128), + Value::from(v2.len()), + Value::from(v2_start), + Value::from(a4_start), + Value::from(5u128), + Value::from(v6.len()), + Value::from(v6_start), + Value::from(a9_start), + ]; + memory.extend(outer_array.clone()); + + let input_array_value_types = vec![ + HeapValueType::Simple, + HeapValueType::Simple, // size of following vector + HeapValueType::Vector { value_types: vec![HeapValueType::Simple] }, + HeapValueType::Array { value_types: vec![HeapValueType::Simple], size: 1 }, + ]; + + // memory address of the end of the above data structures + let r_ptr = memory.len(); + + let r_input = MemoryAddress::from(r_ptr); + let r_output = MemoryAddress::from(r_ptr + 1); + + let program = vec![ + Opcode::CalldataCopy { + destination_address: MemoryAddress::from(0), + size: memory.len(), + offset: 0, + }, + // input = 0 + Opcode::Const { destination: r_input, value: Value::from(outer_ptr), bit_size: 32 }, + // some_function(input) + Opcode::ForeignCall { + function: "flat_sum".into(), + destinations: vec![ValueOrArray::MemoryAddress(r_output)], + destination_value_types: vec![HeapValueType::Simple], + inputs: vec![ValueOrArray::HeapArray(HeapArray { + pointer: r_input, + size: outer_array.len(), + })], + input_value_types: vec![HeapValueType::Array { + value_types: input_array_value_types, + size: outer_array.len(), + }], + }, + ]; + + let mut vm = brillig_execute_and_get_vm(memory, &program); + + // Check that VM is waiting + assert_eq!( + vm.status, + VMStatus::ForeignCallWait { + function: "flat_sum".into(), + inputs: vec![ForeignCallParam::Array(vec![ + Value::from(1u128), + Value::from(2u128), // size of following vector + Value::from(2u128), + Value::from(3u128), + Value::from(4u128), + Value::from(5u128), + Value::from(3u128), // size of following vector + Value::from(6u128), + Value::from(7u128), + Value::from(8u128), + Value::from(9u128), + ])], + } + ); + + // Push result we're waiting for + vm.resolve_foreign_call(Value::from(45u128).into()); + + // Resume VM + brillig_execute(&mut vm); + + // Check that VM finished once resumed + assert_eq!(vm.status, VMStatus::Finished { return_data_offset: 0, return_data_size: 0 }); + + // Check result + let result_value = vm.memory.read(r_output); + assert_eq!(result_value, Value::from(45u128)); + + // Ensure the foreign call counter has been incremented + assert_eq!(vm.foreign_call_counter, 1); + } } 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 4051b8cebcd..b19ee97bc4e 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 @@ -1,4 +1,6 @@ -use crate::brillig::brillig_ir::brillig_variable::{BrilligArray, BrilligVariable, BrilligVector}; +use crate::brillig::brillig_ir::brillig_variable::{ + type_to_heap_value_type, BrilligArray, BrilligVariable, BrilligVector, +}; use crate::brillig::brillig_ir::{ BrilligBinaryOp, BrilligContext, BRILLIG_INTEGER_ARITHMETIC_BIT_SIZE, }; @@ -332,13 +334,23 @@ impl<'block> BrilligBlock<'block> { let input_registers = vecmap(arguments, |value_id| { self.convert_ssa_value(*value_id, dfg).to_register_or_memory() }); + let input_value_types = vecmap(arguments, |value_id| { + let value_type = dfg.type_of_value(*value_id); + type_to_heap_value_type(&value_type) + }); let output_registers = vecmap(result_ids, |value_id| { self.allocate_external_call_result(*value_id, dfg).to_register_or_memory() }); + let output_value_types = vecmap(result_ids, |value_id| { + let value_type = dfg.type_of_value(*value_id); + type_to_heap_value_type(&value_type) + }); self.brillig_context.foreign_call_instruction( func_name.to_owned(), &input_registers, + &input_value_types, &output_registers, + &output_value_types, ); for (i, output_register) in output_registers.iter().enumerate() { diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index 70aeff1e5d7..035b9b01500 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -23,6 +23,7 @@ use acvm::{ BinaryFieldOp, BinaryIntOp, BlackBoxOp, MemoryAddress, Opcode as BrilligOpcode, Value, ValueOrArray, }, + brillig_vm::brillig::HeapValueType, FieldElement, }; use debug_show::DebugShow; @@ -577,13 +578,19 @@ impl BrilligContext { &mut self, func_name: String, inputs: &[ValueOrArray], + input_value_types: &[HeapValueType], outputs: &[ValueOrArray], + output_value_types: &[HeapValueType], ) { + assert!(inputs.len() == input_value_types.len()); + assert!(outputs.len() == output_value_types.len()); self.debug_show.foreign_call_instruction(func_name.clone(), inputs, outputs); let opcode = BrilligOpcode::ForeignCall { function: func_name, destinations: outputs.to_vec(), + destination_value_types: output_value_types.to_vec(), inputs: inputs.to_vec(), + input_value_types: input_value_types.to_vec(), }; self.push_opcode(opcode); } @@ -948,7 +955,7 @@ impl BrilligContext { /// Issues a blackbox operation. pub(crate) fn black_box_op_instruction(&mut self, op: BlackBoxOp) { - self.debug_show.black_box_op_instruction(op); + self.debug_show.black_box_op_instruction(&op); self.push_opcode(BrilligOpcode::BlackBox(op)); } @@ -1063,6 +1070,7 @@ pub(crate) mod tests { BinaryIntOp, ForeignCallParam, ForeignCallResult, HeapVector, MemoryAddress, Value, ValueOrArray, }; + use acvm::brillig_vm::brillig::HeapValueType; use acvm::brillig_vm::{VMStatus, VM}; use acvm::{BlackBoxFunctionSolver, BlackBoxResolutionError, FieldElement}; @@ -1175,7 +1183,9 @@ pub(crate) mod tests { context.foreign_call_instruction( "make_number_sequence".into(), &[ValueOrArray::MemoryAddress(r_input_size)], + &[HeapValueType::Simple], &[ValueOrArray::HeapVector(HeapVector { pointer: r_stack, size: r_output_size })], + &[HeapValueType::Vector { value_types: vec![HeapValueType::Simple] }], ); // push stack frame by r_returned_size context.memory_op(r_stack, r_output_size, r_stack, BinaryIntOp::Add); diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs index b3fe30c40b4..856fb709fa9 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/brillig_variable.rs @@ -1,6 +1,10 @@ -use acvm::brillig_vm::brillig::{HeapArray, HeapVector, MemoryAddress, ValueOrArray}; +use acvm::brillig_vm::brillig::{ + HeapArray, HeapValueType, HeapVector, MemoryAddress, ValueOrArray, +}; use serde::{Deserialize, Serialize}; +use crate::ssa::ir::types::Type; + /// The representation of a noir array in the Brillig IR #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Copy)] pub(crate) struct BrilligArray { @@ -93,3 +97,16 @@ impl BrilligVariable { } } } + +pub(crate) fn type_to_heap_value_type(typ: &Type) -> HeapValueType { + match typ { + Type::Numeric(_) | Type::Reference(_) | Type::Function => HeapValueType::Simple, + Type::Array(elem_type, size) => HeapValueType::Array { + value_types: elem_type.as_ref().iter().map(type_to_heap_value_type).collect(), + size: typ.element_size() * size, + }, + Type::Slice(elem_type) => HeapValueType::Vector { + value_types: elem_type.as_ref().iter().map(type_to_heap_value_type).collect(), + }, + } +} diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index 45b6d3d79b2..280cd12e91d 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -342,7 +342,7 @@ impl DebugShow { } /// Debug function for black_box_op - pub(crate) fn black_box_op_instruction(&self, op: BlackBoxOp) { + pub(crate) fn black_box_op_instruction(&self, op: &BlackBoxOp) { match op { BlackBoxOp::Sha256 { message, output } => { debug_println!(self.enable_debug_trace, " SHA256 {} -> {}", message, output); diff --git a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index 5f2a531aca4..94e62e76746 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -1453,7 +1453,7 @@ impl AcirContext { } Ok(BrilligInputs::Array(var_expressions)) } - AcirValue::DynamicArray(AcirDynamicArray { block_id,.. }) => { + AcirValue::DynamicArray(AcirDynamicArray { block_id, .. }) => { Ok(BrilligInputs::MemoryArray(block_id)) } } diff --git a/noir/test_programs/execution_success/debug_logs/src/main.nr b/noir/test_programs/execution_success/debug_logs/src/main.nr index 52c910065c1..cbce6f15286 100644 --- a/noir/test_programs/execution_success/debug_logs/src/main.nr +++ b/noir/test_programs/execution_success/debug_logs/src/main.nr @@ -50,6 +50,12 @@ fn main(x: Field, y: pub Field) { regression_2906(); + let first_array = [1, 2, 3]; + let second_array = [4, 5, 6]; + let arrays_nested = [first_array, second_array]; + std::println(f"first_array: {first_array}, second_array: {second_array}"); + std::println(f"arrays_nested: {arrays_nested}"); + let free_lambda = |x| x + 1; let sentinel: u32 = 8888; std::println(f"free_lambda: {free_lambda}, sentinel: {sentinel}"); diff --git a/noir/tooling/debugger/src/context.rs b/noir/tooling/debugger/src/context.rs index 0231158ed28..9c12794d5dd 100644 --- a/noir/tooling/debugger/src/context.rs +++ b/noir/tooling/debugger/src/context.rs @@ -432,7 +432,7 @@ mod tests { }, blackbox_solver::StubbedBlackBoxSolver, brillig_vm::brillig::{ - BinaryFieldOp, MemoryAddress, Opcode as BrilligOpcode, ValueOrArray, + BinaryFieldOp, HeapValueType, MemoryAddress, Opcode as BrilligOpcode, ValueOrArray, }, }; use nargo::{artifacts::debug::DebugArtifact, ops::DefaultForeignCallExecutor}; @@ -464,7 +464,9 @@ mod tests { BrilligOpcode::ForeignCall { function: "clear_mock".into(), destinations: vec![], + destination_value_types: vec![], inputs: vec![ValueOrArray::MemoryAddress(MemoryAddress::from(0))], + input_value_types: vec![HeapValueType::Simple], }, BrilligOpcode::Stop { return_data_offset: 0, return_data_size: 0 }, ],