diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 02fc648a321..0fb5cebbe55 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -94,6 +94,14 @@ void build_constraints(Builder& builder, AcirFormat const& constraint_system, bo create_block_constraints(builder, constraint, has_valid_witness_assignments); } + // Add big_int constraints + for (const auto& constraint : constraint_system.bigint_operations) { + create_bigint_operations_constraint(builder, constraint); + } + for (const auto& constraint : constraint_system.bigint_from_le_bytes_constraints) { + create_bigint_from_le_bytes_constraint(builder, constraint); + } + // TODO(https://github.com/AztecProtocol/barretenberg/issues/817): disable these for UGH for now since we're not yet // dealing with proper recursion if constexpr (IsGoblinBuilder) { diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index a8768d340f4..82cf7eccad3 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -1,6 +1,7 @@ #pragma once #include "barretenberg/common/slab_allocator.hpp" #include "barretenberg/serialize/msgpack.hpp" +#include "bigint_constraint.hpp" #include "blake2s_constraint.hpp" #include "blake3_constraint.hpp" #include "block_constraint.hpp" @@ -41,6 +42,8 @@ struct AcirFormat { std::vector ec_add_constraints; std::vector ec_double_constraints; std::vector recursion_constraints; + std::vector bigint_from_le_bytes_constraints; + std::vector bigint_operations; // A standard plonk arithmetic constraint, as defined in the poly_triple struct, consists of selector values // for q_M,q_L,q_R,q_O,q_C and indices of three variables taking the role of left, right and output wire @@ -69,7 +72,9 @@ struct AcirFormat { fixed_base_scalar_mul_constraints, recursion_constraints, constraints, - block_constraints); + block_constraints, + bigint_from_le_bytes_constraints, + bigint_operations); friend bool operator==(AcirFormat const& lhs, AcirFormat const& rhs) = default; }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index 92e70b64a16..8804cd0c573 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -47,6 +47,8 @@ TEST_F(AcirFormatTests, TestASingleConstraintNoPubInputs) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = { constraint }, .block_constraints = {}, }; @@ -158,6 +160,8 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = { expr_a, expr_b, expr_c, expr_d }, .block_constraints = {} }; @@ -221,6 +225,8 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = { poly_triple{ .a = schnorr_constraint.result, .b = schnorr_constraint.result, @@ -312,6 +318,8 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = { poly_triple{ .a = schnorr_constraint.result, .b = schnorr_constraint.result, @@ -422,6 +430,8 @@ TEST_F(AcirFormatTests, TestVarKeccak) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = { dummy }, .block_constraints = {}, }; @@ -464,6 +474,8 @@ TEST_F(AcirFormatTests, TestKeccakPermutation) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = {} }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp index ee539a47ba2..5d6cf0063b8 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.hpp @@ -2,6 +2,7 @@ #include "acir_format.hpp" #include "barretenberg/common/container.hpp" #include "barretenberg/common/throw_or_abort.hpp" +#include "barretenberg/dsl/acir_format/bigint_constraint.hpp" #include "barretenberg/dsl/acir_format/blake2s_constraint.hpp" #include "barretenberg/dsl/acir_format/blake3_constraint.hpp" #include "barretenberg/dsl/acir_format/block_constraint.hpp" @@ -240,6 +241,40 @@ void handle_blackbox_func_call(Circuit::Opcode::BlackBoxFuncCall const& arg, Aci .key_hash = arg.key_hash.witness.value, }; af.recursion_constraints.push_back(c); + } else if constexpr (std::is_same_v) { + af.bigint_from_le_bytes_constraints.push_back(BigIntFromLeBytes{ + .inputs = map(arg.inputs, [](auto& e) { return e.witness.value; }), + .modulus = map(arg.modulus, [](auto& e) -> uint32_t { return e; }), + .result = arg.output, + }); + } else if constexpr (std::is_same_v) { + af.bigint_operations.push_back(BigIntOperation{ + .lhs = arg.lhs, + .rhs = arg.rhs, + .result = arg.output, + .opcode = BigIntOperationType::Add, + }); + } else if constexpr (std::is_same_v) { + af.bigint_operations.push_back(BigIntOperation{ + .lhs = arg.lhs, + .rhs = arg.rhs, + .result = arg.output, + .opcode = BigIntOperationType::Neg, + }); + } else if constexpr (std::is_same_v) { + af.bigint_operations.push_back(BigIntOperation{ + .lhs = arg.lhs, + .rhs = arg.rhs, + .result = arg.output, + .opcode = BigIntOperationType::Mul, + }); + } else if constexpr (std::is_same_v) { + af.bigint_operations.push_back(BigIntOperation{ + .lhs = arg.lhs, + .rhs = arg.rhs, + .result = arg.output, + .opcode = BigIntOperationType::Div, + }); } }, arg.value.value); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.cpp new file mode 100644 index 00000000000..4780e5ca36c --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.cpp @@ -0,0 +1,33 @@ +#include "bigint_constraint.hpp" +#include "barretenberg/dsl/types.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" +#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" + +namespace acir_format { + +template void create_bigint_operations_constraint(Builder& builder, const BigIntOperation& input) +{ + // TODO + (void)builder; + info(input); +} + +template void create_bigint_operations_constraint(UltraCircuitBuilder& builder, + const BigIntOperation& input); +template void create_bigint_operations_constraint(GoblinUltraCircuitBuilder& builder, + const BigIntOperation& input); + +template +void create_bigint_from_le_bytes_constraint(Builder& builder, const BigIntFromLeBytes& input) +{ + // TODO + (void)builder; + info(input); +} + +template void create_bigint_from_le_bytes_constraint(UltraCircuitBuilder& builder, + const BigIntFromLeBytes& input); +template void create_bigint_from_le_bytes_constraint(GoblinUltraCircuitBuilder& builder, + const BigIntFromLeBytes& input); + +} // namespace acir_format diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.hpp new file mode 100644 index 00000000000..8b21ee5e784 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.hpp @@ -0,0 +1,35 @@ +#pragma once +#include "barretenberg/dsl/types.hpp" +#include "barretenberg/serialize/msgpack.hpp" +#include +#include + +namespace acir_format { + +struct BigIntFromLeBytes { + std::vector inputs; + std::vector modulus; + uint32_t result; + + // For serialization, update with any new fields + MSGPACK_FIELDS(inputs, result); + friend bool operator==(BigIntFromLeBytes const& lhs, BigIntFromLeBytes const& rhs) = default; +}; + +enum BigIntOperationType { Add, Neg, Mul, Div }; + +struct BigIntOperation { + uint32_t lhs; + uint32_t rhs; + uint32_t result; + BigIntOperationType opcode; + + // For serialization, update with any new fields + MSGPACK_FIELDS(lhs, rhs, opcode, result); + friend bool operator==(BigIntOperation const& lhs, BigIntOperation const& rhs) = default; +}; + +template void create_bigint_operations_constraint(Builder& builder, const BigIntOperation& input); +template +void create_bigint_from_le_bytes_constraint(Builder& builder, const BigIntFromLeBytes& input); +} // namespace acir_format \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp new file mode 100644 index 00000000000..0762bfd783a --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp @@ -0,0 +1,88 @@ +#include "bigint_constraint.hpp" +#include "acir_format.hpp" +#include "barretenberg/plonk/proof_system/types/proof.hpp" +#include "barretenberg/plonk/proof_system/verification_key/verification_key.hpp" + +#include +#include + +namespace acir_format::tests { + +class BigIntTests : public ::testing::Test { + protected: + static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); } +}; + +TEST_F(BigIntTests, TestBigIntConstraintDummy) +{ + // Dummy Test: to be updated when big ints opcodes are implemented + BigIntOperation add_constraint{ + .lhs = 1, + .rhs = 2, + .result = 3, + .opcode = BigIntOperationType::Add, + }; + BigIntOperation neg_constraint{ + .lhs = 1, + .rhs = 2, + .result = 3, + .opcode = BigIntOperationType::Neg, + }; + BigIntOperation mul_constraint{ + .lhs = 1, + .rhs = 2, + .result = 3, + .opcode = BigIntOperationType::Mul, + }; + BigIntOperation div_constraint{ + .lhs = 1, + .rhs = 2, + .result = 3, + .opcode = BigIntOperationType::Div, + }; + BigIntFromLeBytes from_le_bytes_constraint{ + .inputs = { 0 }, + .modulus = { 23 }, + .result = 1, + }; + + AcirFormat constraint_system{ + .varnum = 4, + .public_inputs = {}, + .logic_constraints = {}, + .range_constraints = {}, + .sha256_constraints = {}, + .schnorr_constraints = {}, + .ecdsa_k1_constraints = {}, + .ecdsa_r1_constraints = {}, + .blake2s_constraints = {}, + .blake3_constraints = {}, + .keccak_constraints = {}, + .keccak_var_constraints = {}, + .keccak_permutations = {}, + .pedersen_constraints = {}, + .pedersen_hash_constraints = {}, + .fixed_base_scalar_mul_constraints = {}, + .ec_add_constraints = {}, + .ec_double_constraints = {}, + .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = { from_le_bytes_constraint }, + .bigint_operations = { add_constraint, neg_constraint, mul_constraint, div_constraint }, + .constraints = {}, + .block_constraints = {}, + + }; + + WitnessVector witness{ 0, 0, 1 }; + auto builder = create_circuit(constraint_system, /*size_hint*/ 0, witness); + + auto composer = Composer(); + auto prover = composer.create_ultra_with_keccak_prover(builder); + auto proof = prover.construct_proof(); + + auto verifier = composer.create_ultra_with_keccak_verifier(builder); + + EXPECT_EQ(verifier.verify_proof(proof), true); +} + +} // namespace acir_format::tests \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index d90a2a7879b..7c0444f6191 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -128,6 +128,8 @@ TEST_F(UltraPlonkRAM, TestBlockConstraint) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = { block }, }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp index 5554fdd8d6d..2e17b97008d 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp @@ -107,6 +107,8 @@ TEST_F(ECDSASecp256k1, TestECDSAConstraintSucceed) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = {}, }; @@ -151,6 +153,8 @@ TEST_F(ECDSASecp256k1, TestECDSACompilesForVerifier) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = {}, }; @@ -190,6 +194,8 @@ TEST_F(ECDSASecp256k1, TestECDSAConstraintFail) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = {}, }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp index ebd78e1b672..c3487e35da0 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp @@ -142,6 +142,8 @@ TEST(ECDSASecp256r1, test_hardcoded) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = {}, }; @@ -187,6 +189,8 @@ TEST(ECDSASecp256r1, TestECDSAConstraintSucceed) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = {}, }; @@ -230,6 +234,8 @@ TEST(ECDSASecp256r1, TestECDSACompilesForVerifier) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = {}, }; @@ -268,6 +274,8 @@ TEST(ECDSASecp256r1, TestECDSAConstraintFail) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = {}, }; diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp index cbbdd2a22b9..20650bf589b 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp @@ -100,6 +100,8 @@ Builder create_inner_circuit() .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = {}, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = { expr_a, expr_b, expr_c, expr_d }, .block_constraints = {} }; @@ -252,6 +254,8 @@ Builder create_outer_circuit(std::vector& inner_circuits) .ec_add_constraints = {}, .ec_double_constraints = {}, .recursion_constraints = recursion_constraints, + .bigint_from_le_bytes_constraints = {}, + .bigint_operations = {}, .constraints = {}, .block_constraints = {} }; 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 c85f609bbd1..8e18e5bc043 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -206,6 +206,65 @@ struct BlackBoxFuncCall { static RecursiveAggregation bincodeDeserialize(std::vector); }; + struct BigIntAdd { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntAdd&, const BigIntAdd&); + std::vector bincodeSerialize() const; + static BigIntAdd bincodeDeserialize(std::vector); + }; + + struct BigIntNeg { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntNeg&, const BigIntNeg&); + std::vector bincodeSerialize() const; + static BigIntNeg bincodeDeserialize(std::vector); + }; + + struct BigIntMul { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntMul&, const BigIntMul&); + std::vector bincodeSerialize() const; + static BigIntMul bincodeDeserialize(std::vector); + }; + + struct BigIntDiv { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntDiv&, const BigIntDiv&); + std::vector bincodeSerialize() const; + static BigIntDiv bincodeDeserialize(std::vector); + }; + + struct BigIntFromLeBytes { + std::vector inputs; + std::vector modulus; + uint32_t output; + + friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); + std::vector bincodeSerialize() const; + static BigIntFromLeBytes bincodeDeserialize(std::vector); + }; + + struct BigIntToLeBytes { + uint32_t input; + std::vector outputs; + + friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); + std::vector bincodeSerialize() const; + static BigIntToLeBytes bincodeDeserialize(std::vector); + }; + std::variant + RecursiveAggregation, + BigIntAdd, + BigIntNeg, + BigIntMul, + BigIntDiv, + BigIntFromLeBytes, + BigIntToLeBytes> value; friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&); @@ -239,8 +304,6 @@ struct BlockId { static BlockId bincodeDeserialize(std::vector); }; -// TODO(https://github.com/AztecProtocol/barretenberg/issues/825): This struct is more general than it needs / should be -// allowed to be. We can only accommodate 1 quadratic term and 3 linear terms. struct Expression { std::vector> mul_terms; std::vector> linear_combinations; @@ -563,6 +626,65 @@ struct BlackBoxOp { static EmbeddedCurveDouble bincodeDeserialize(std::vector); }; + struct BigIntAdd { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntAdd&, const BigIntAdd&); + std::vector bincodeSerialize() const; + static BigIntAdd bincodeDeserialize(std::vector); + }; + + struct BigIntNeg { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntNeg&, const BigIntNeg&); + std::vector bincodeSerialize() const; + static BigIntNeg bincodeDeserialize(std::vector); + }; + + struct BigIntMul { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntMul&, const BigIntMul&); + std::vector bincodeSerialize() const; + static BigIntMul bincodeDeserialize(std::vector); + }; + + struct BigIntDiv { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntDiv&, const BigIntDiv&); + std::vector bincodeSerialize() const; + static BigIntDiv bincodeDeserialize(std::vector); + }; + + struct BigIntFromLeBytes { + Circuit::HeapVector inputs; + Circuit::HeapVector modulus; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); + std::vector bincodeSerialize() const; + static BigIntFromLeBytes bincodeDeserialize(std::vector); + }; + + struct BigIntToLeBytes { + Circuit::RegisterIndex input; + Circuit::HeapVector output; + + friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); + std::vector bincodeSerialize() const; + static BigIntToLeBytes bincodeDeserialize(std::vector); + }; + std::variant + EmbeddedCurveDouble, + BigIntAdd, + BigIntNeg, + BigIntMul, + BigIntDiv, + BigIntFromLeBytes, + BigIntToLeBytes> value; friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); @@ -2883,25 +3011,31 @@ Circuit::BlackBoxFuncCall::RecursiveAggregation serde::Deserializable< namespace Circuit { -inline bool operator==(const BlackBoxOp& lhs, const BlackBoxOp& rhs) +inline bool operator==(const BlackBoxFuncCall::BigIntAdd& lhs, const BlackBoxFuncCall::BigIntAdd& rhs) { - if (!(lhs.value == rhs.value)) { + if (!(lhs.lhs == rhs.lhs)) { + return false; + } + if (!(lhs.rhs == rhs.rhs)) { + return false; + } + if (!(lhs.output == rhs.output)) { return false; } return true; } -inline std::vector BlackBoxOp::bincodeSerialize() const +inline std::vector BlackBoxFuncCall::BigIntAdd::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp BlackBoxOp::bincodeDeserialize(std::vector input) +inline BlackBoxFuncCall::BigIntAdd BlackBoxFuncCall::BigIntAdd::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -2912,29 +3046,34 @@ inline BlackBoxOp BlackBoxOp::bincodeDeserialize(std::vector input) template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp& obj, Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxFuncCall::BigIntAdd& obj, Serializer& serializer) { - serializer.increase_container_depth(); - serde::Serializable::serialize(obj.value, serializer); - serializer.decrease_container_depth(); + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp serde::Deserializable::deserialize(Deserializer& deserializer) +Circuit::BlackBoxFuncCall::BigIntAdd serde::Deserializable::deserialize( + Deserializer& deserializer) { - deserializer.increase_container_depth(); - Circuit::BlackBoxOp obj; - obj.value = serde::Deserializable::deserialize(deserializer); - deserializer.decrease_container_depth(); + Circuit::BlackBoxFuncCall::BigIntAdd obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::Sha256& lhs, const BlackBoxOp::Sha256& rhs) +inline bool operator==(const BlackBoxFuncCall::BigIntNeg& lhs, const BlackBoxFuncCall::BigIntNeg& rhs) { - if (!(lhs.message == rhs.message)) { + if (!(lhs.lhs == rhs.lhs)) { + return false; + } + if (!(lhs.rhs == rhs.rhs)) { return false; } if (!(lhs.output == rhs.output)) { @@ -2943,17 +3082,17 @@ inline bool operator==(const BlackBoxOp::Sha256& lhs, const BlackBoxOp::Sha256& return true; } -inline std::vector BlackBoxOp::Sha256::bincodeSerialize() const +inline std::vector BlackBoxFuncCall::BigIntNeg::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::Sha256 BlackBoxOp::Sha256::bincodeDeserialize(std::vector input) +inline BlackBoxFuncCall::BigIntNeg BlackBoxFuncCall::BigIntNeg::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -2964,28 +3103,34 @@ inline BlackBoxOp::Sha256 BlackBoxOp::Sha256::bincodeDeserialize(std::vector template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Sha256& obj, - Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxFuncCall::BigIntNeg& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::Sha256 serde::Deserializable::deserialize(Deserializer& deserializer) +Circuit::BlackBoxFuncCall::BigIntNeg serde::Deserializable::deserialize( + Deserializer& deserializer) { - Circuit::BlackBoxOp::Sha256 obj; - obj.message = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxFuncCall::BigIntNeg obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::Blake2s& lhs, const BlackBoxOp::Blake2s& rhs) +inline bool operator==(const BlackBoxFuncCall::BigIntMul& lhs, const BlackBoxFuncCall::BigIntMul& rhs) { - if (!(lhs.message == rhs.message)) { + if (!(lhs.lhs == rhs.lhs)) { + return false; + } + if (!(lhs.rhs == rhs.rhs)) { return false; } if (!(lhs.output == rhs.output)) { @@ -2994,17 +3139,17 @@ inline bool operator==(const BlackBoxOp::Blake2s& lhs, const BlackBoxOp::Blake2s return true; } -inline std::vector BlackBoxOp::Blake2s::bincodeSerialize() const +inline std::vector BlackBoxFuncCall::BigIntMul::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::Blake2s BlackBoxOp::Blake2s::bincodeDeserialize(std::vector input) +inline BlackBoxFuncCall::BigIntMul BlackBoxFuncCall::BigIntMul::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3015,29 +3160,34 @@ inline BlackBoxOp::Blake2s BlackBoxOp::Blake2s::bincodeDeserialize(std::vector template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Blake2s& obj, - Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxFuncCall::BigIntMul& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::Blake2s serde::Deserializable::deserialize( +Circuit::BlackBoxFuncCall::BigIntMul serde::Deserializable::deserialize( Deserializer& deserializer) { - Circuit::BlackBoxOp::Blake2s obj; - obj.message = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxFuncCall::BigIntMul obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::Blake3& lhs, const BlackBoxOp::Blake3& rhs) +inline bool operator==(const BlackBoxFuncCall::BigIntDiv& lhs, const BlackBoxFuncCall::BigIntDiv& rhs) { - if (!(lhs.message == rhs.message)) { + if (!(lhs.lhs == rhs.lhs)) { + return false; + } + if (!(lhs.rhs == rhs.rhs)) { return false; } if (!(lhs.output == rhs.output)) { @@ -3046,17 +3196,17 @@ inline bool operator==(const BlackBoxOp::Blake3& lhs, const BlackBoxOp::Blake3& return true; } -inline std::vector BlackBoxOp::Blake3::bincodeSerialize() const +inline std::vector BlackBoxFuncCall::BigIntDiv::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::Blake3 BlackBoxOp::Blake3::bincodeDeserialize(std::vector input) +inline BlackBoxFuncCall::BigIntDiv BlackBoxFuncCall::BigIntDiv::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3067,28 +3217,34 @@ inline BlackBoxOp::Blake3 BlackBoxOp::Blake3::bincodeDeserialize(std::vector template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Blake3& obj, - Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxFuncCall::BigIntDiv& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::Blake3 serde::Deserializable::deserialize(Deserializer& deserializer) +Circuit::BlackBoxFuncCall::BigIntDiv serde::Deserializable::deserialize( + Deserializer& deserializer) { - Circuit::BlackBoxOp::Blake3 obj; - obj.message = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxFuncCall::BigIntDiv obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::Keccak256& lhs, const BlackBoxOp::Keccak256& rhs) +inline bool operator==(const BlackBoxFuncCall::BigIntFromLeBytes& lhs, const BlackBoxFuncCall::BigIntFromLeBytes& rhs) { - if (!(lhs.message == rhs.message)) { + if (!(lhs.inputs == rhs.inputs)) { + return false; + } + if (!(lhs.modulus == rhs.modulus)) { return false; } if (!(lhs.output == rhs.output)) { @@ -3097,17 +3253,18 @@ inline bool operator==(const BlackBoxOp::Keccak256& lhs, const BlackBoxOp::Kecca return true; } -inline std::vector BlackBoxOp::Keccak256::bincodeSerialize() const +inline std::vector BlackBoxFuncCall::BigIntFromLeBytes::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::Keccak256 BlackBoxOp::Keccak256::bincodeDeserialize(std::vector input) +inline BlackBoxFuncCall::BigIntFromLeBytes BlackBoxFuncCall::BigIntFromLeBytes::bincodeDeserialize( + std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3118,48 +3275,51 @@ inline BlackBoxOp::Keccak256 BlackBoxOp::Keccak256::bincodeDeserialize(std::vect template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Keccak256& obj, - Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxFuncCall::BigIntFromLeBytes& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.modulus, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::Keccak256 serde::Deserializable::deserialize( - Deserializer& deserializer) +Circuit::BlackBoxFuncCall::BigIntFromLeBytes serde::Deserializable< + Circuit::BlackBoxFuncCall::BigIntFromLeBytes>::deserialize(Deserializer& deserializer) { - Circuit::BlackBoxOp::Keccak256 obj; - obj.message = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxFuncCall::BigIntFromLeBytes obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.modulus = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::Keccakf1600& lhs, const BlackBoxOp::Keccakf1600& rhs) +inline bool operator==(const BlackBoxFuncCall::BigIntToLeBytes& lhs, const BlackBoxFuncCall::BigIntToLeBytes& rhs) { - if (!(lhs.message == rhs.message)) { + if (!(lhs.input == rhs.input)) { return false; } - if (!(lhs.output == rhs.output)) { + if (!(lhs.outputs == rhs.outputs)) { return false; } return true; } -inline std::vector BlackBoxOp::Keccakf1600::bincodeSerialize() const +inline std::vector BlackBoxFuncCall::BigIntToLeBytes::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::Keccakf1600 BlackBoxOp::Keccakf1600::bincodeDeserialize(std::vector input) +inline BlackBoxFuncCall::BigIntToLeBytes BlackBoxFuncCall::BigIntToLeBytes::bincodeDeserialize( + std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3170,57 +3330,45 @@ inline BlackBoxOp::Keccakf1600 BlackBoxOp::Keccakf1600::bincodeDeserialize(std:: template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::Keccakf1600& obj, - Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxFuncCall::BigIntToLeBytes& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.message, serializer); - serde::Serializable::serialize(obj.output, serializer); + serde::Serializable::serialize(obj.input, serializer); + serde::Serializable::serialize(obj.outputs, serializer); } template <> template -Circuit::BlackBoxOp::Keccakf1600 serde::Deserializable::deserialize( - Deserializer& deserializer) +Circuit::BlackBoxFuncCall::BigIntToLeBytes serde::Deserializable< + Circuit::BlackBoxFuncCall::BigIntToLeBytes>::deserialize(Deserializer& deserializer) { - Circuit::BlackBoxOp::Keccakf1600 obj; - obj.message = serde::Deserializable::deserialize(deserializer); - obj.output = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxFuncCall::BigIntToLeBytes obj; + obj.input = serde::Deserializable::deserialize(deserializer); + obj.outputs = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::EcdsaSecp256k1& lhs, const BlackBoxOp::EcdsaSecp256k1& rhs) +inline bool operator==(const BlackBoxOp& lhs, const BlackBoxOp& rhs) { - if (!(lhs.hashed_msg == rhs.hashed_msg)) { - return false; - } - if (!(lhs.public_key_x == rhs.public_key_x)) { - return false; - } - if (!(lhs.public_key_y == rhs.public_key_y)) { - return false; - } - if (!(lhs.signature == rhs.signature)) { - return false; - } - if (!(lhs.result == rhs.result)) { + if (!(lhs.value == rhs.value)) { return false; } return true; } -inline std::vector BlackBoxOp::EcdsaSecp256k1::bincodeSerialize() const +inline std::vector BlackBoxOp::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::EcdsaSecp256k1 BlackBoxOp::EcdsaSecp256k1::bincodeDeserialize(std::vector input) +inline BlackBoxOp BlackBoxOp::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3231,44 +3379,668 @@ inline BlackBoxOp::EcdsaSecp256k1 BlackBoxOp::EcdsaSecp256k1::bincodeDeserialize template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::EcdsaSecp256k1& obj, - Serializer& serializer) +void serde::Serializable::serialize(const Circuit::BlackBoxOp& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.hashed_msg, serializer); - serde::Serializable::serialize(obj.public_key_x, serializer); - serde::Serializable::serialize(obj.public_key_y, serializer); - serde::Serializable::serialize(obj.signature, serializer); - serde::Serializable::serialize(obj.result, serializer); + serializer.increase_container_depth(); + serde::Serializable::serialize(obj.value, serializer); + serializer.decrease_container_depth(); } template <> template -Circuit::BlackBoxOp::EcdsaSecp256k1 serde::Deserializable::deserialize( - Deserializer& deserializer) +Circuit::BlackBoxOp serde::Deserializable::deserialize(Deserializer& deserializer) { - Circuit::BlackBoxOp::EcdsaSecp256k1 obj; - obj.hashed_msg = serde::Deserializable::deserialize(deserializer); - obj.public_key_x = serde::Deserializable::deserialize(deserializer); - obj.public_key_y = serde::Deserializable::deserialize(deserializer); - obj.signature = serde::Deserializable::deserialize(deserializer); - obj.result = serde::Deserializable::deserialize(deserializer); + deserializer.increase_container_depth(); + Circuit::BlackBoxOp obj; + obj.value = serde::Deserializable::deserialize(deserializer); + deserializer.decrease_container_depth(); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::EcdsaSecp256r1& lhs, const BlackBoxOp::EcdsaSecp256r1& rhs) +inline bool operator==(const BlackBoxOp::Sha256& lhs, const BlackBoxOp::Sha256& rhs) { - if (!(lhs.hashed_msg == rhs.hashed_msg)) { - return false; - } - if (!(lhs.public_key_x == rhs.public_key_x)) { + if (!(lhs.message == rhs.message)) { return false; } - if (!(lhs.public_key_y == rhs.public_key_y)) { + if (!(lhs.output == rhs.output)) { return false; } - if (!(lhs.signature == rhs.signature)) { + return true; +} + +inline std::vector BlackBoxOp::Sha256::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::Sha256 BlackBoxOp::Sha256::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::BlackBoxOp::Sha256& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Sha256 serde::Deserializable::deserialize(Deserializer& deserializer) +{ + Circuit::BlackBoxOp::Sha256 obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::Blake2s& lhs, const BlackBoxOp::Blake2s& rhs) +{ + if (!(lhs.message == rhs.message)) { + return false; + } + if (!(lhs.output == rhs.output)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::Blake2s::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::Blake2s BlackBoxOp::Blake2s::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::BlackBoxOp::Blake2s& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Blake2s serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::Blake2s obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::Blake3& lhs, const BlackBoxOp::Blake3& rhs) +{ + if (!(lhs.message == rhs.message)) { + return false; + } + if (!(lhs.output == rhs.output)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::Blake3::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::Blake3 BlackBoxOp::Blake3::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::BlackBoxOp::Blake3& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Blake3 serde::Deserializable::deserialize(Deserializer& deserializer) +{ + Circuit::BlackBoxOp::Blake3 obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::Keccak256& lhs, const BlackBoxOp::Keccak256& rhs) +{ + if (!(lhs.message == rhs.message)) { + return false; + } + if (!(lhs.output == rhs.output)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::Keccak256::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::Keccak256 BlackBoxOp::Keccak256::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::BlackBoxOp::Keccak256& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Keccak256 serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::Keccak256 obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::Keccakf1600& lhs, const BlackBoxOp::Keccakf1600& rhs) +{ + if (!(lhs.message == rhs.message)) { + return false; + } + if (!(lhs.output == rhs.output)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::Keccakf1600::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::Keccakf1600 BlackBoxOp::Keccakf1600::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::BlackBoxOp::Keccakf1600& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::Keccakf1600 serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::Keccakf1600 obj; + obj.message = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::EcdsaSecp256k1& lhs, const BlackBoxOp::EcdsaSecp256k1& rhs) +{ + if (!(lhs.hashed_msg == rhs.hashed_msg)) { + return false; + } + if (!(lhs.public_key_x == rhs.public_key_x)) { + return false; + } + if (!(lhs.public_key_y == rhs.public_key_y)) { + return false; + } + if (!(lhs.signature == rhs.signature)) { + return false; + } + if (!(lhs.result == rhs.result)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::EcdsaSecp256k1::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::EcdsaSecp256k1 BlackBoxOp::EcdsaSecp256k1::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::BlackBoxOp::EcdsaSecp256k1& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.hashed_msg, serializer); + serde::Serializable::serialize(obj.public_key_x, serializer); + serde::Serializable::serialize(obj.public_key_y, serializer); + serde::Serializable::serialize(obj.signature, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Circuit::BlackBoxOp::EcdsaSecp256k1 serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::EcdsaSecp256k1 obj; + obj.hashed_msg = serde::Deserializable::deserialize(deserializer); + obj.public_key_x = serde::Deserializable::deserialize(deserializer); + obj.public_key_y = serde::Deserializable::deserialize(deserializer); + obj.signature = serde::Deserializable::deserialize(deserializer); + obj.result = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::EcdsaSecp256r1& lhs, const BlackBoxOp::EcdsaSecp256r1& rhs) +{ + if (!(lhs.hashed_msg == rhs.hashed_msg)) { + return false; + } + if (!(lhs.public_key_x == rhs.public_key_x)) { + return false; + } + if (!(lhs.public_key_y == rhs.public_key_y)) { + return false; + } + if (!(lhs.signature == rhs.signature)) { + return false; + } + if (!(lhs.result == rhs.result)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::EcdsaSecp256r1::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::EcdsaSecp256r1 BlackBoxOp::EcdsaSecp256r1::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::BlackBoxOp::EcdsaSecp256r1& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.hashed_msg, serializer); + serde::Serializable::serialize(obj.public_key_x, serializer); + serde::Serializable::serialize(obj.public_key_y, serializer); + serde::Serializable::serialize(obj.signature, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Circuit::BlackBoxOp::EcdsaSecp256r1 serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::EcdsaSecp256r1 obj; + obj.hashed_msg = serde::Deserializable::deserialize(deserializer); + obj.public_key_x = serde::Deserializable::deserialize(deserializer); + obj.public_key_y = serde::Deserializable::deserialize(deserializer); + obj.signature = serde::Deserializable::deserialize(deserializer); + obj.result = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::SchnorrVerify& lhs, const BlackBoxOp::SchnorrVerify& rhs) +{ + if (!(lhs.public_key_x == rhs.public_key_x)) { + return false; + } + if (!(lhs.public_key_y == rhs.public_key_y)) { + return false; + } + if (!(lhs.message == rhs.message)) { + return false; + } + if (!(lhs.signature == rhs.signature)) { + return false; + } + if (!(lhs.result == rhs.result)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::SchnorrVerify::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::SchnorrVerify BlackBoxOp::SchnorrVerify::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::BlackBoxOp::SchnorrVerify& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.public_key_x, serializer); + serde::Serializable::serialize(obj.public_key_y, serializer); + serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.signature, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Circuit::BlackBoxOp::SchnorrVerify serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::SchnorrVerify obj; + obj.public_key_x = serde::Deserializable::deserialize(deserializer); + obj.public_key_y = serde::Deserializable::deserialize(deserializer); + obj.message = serde::Deserializable::deserialize(deserializer); + obj.signature = serde::Deserializable::deserialize(deserializer); + obj.result = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::PedersenCommitment& lhs, const BlackBoxOp::PedersenCommitment& rhs) +{ + if (!(lhs.inputs == rhs.inputs)) { + return false; + } + if (!(lhs.domain_separator == rhs.domain_separator)) { + return false; + } + if (!(lhs.output == rhs.output)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::PedersenCommitment::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::PedersenCommitment BlackBoxOp::PedersenCommitment::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::BlackBoxOp::PedersenCommitment& obj, Serializer& serializer) +{ + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.domain_separator, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::PedersenCommitment serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::PedersenCommitment obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.domain_separator = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::PedersenHash& lhs, const BlackBoxOp::PedersenHash& rhs) +{ + if (!(lhs.inputs == rhs.inputs)) { + return false; + } + if (!(lhs.domain_separator == rhs.domain_separator)) { + return false; + } + if (!(lhs.output == rhs.output)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::PedersenHash::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::PedersenHash BlackBoxOp::PedersenHash::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::BlackBoxOp::PedersenHash& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.domain_separator, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::PedersenHash serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::PedersenHash obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.domain_separator = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::FixedBaseScalarMul& lhs, const BlackBoxOp::FixedBaseScalarMul& rhs) +{ + if (!(lhs.low == rhs.low)) { + return false; + } + if (!(lhs.high == rhs.high)) { + return false; + } + if (!(lhs.result == rhs.result)) { + return false; + } + return true; +} + +inline std::vector BlackBoxOp::FixedBaseScalarMul::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::FixedBaseScalarMul BlackBoxOp::FixedBaseScalarMul::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::BlackBoxOp::FixedBaseScalarMul& obj, Serializer& serializer) +{ + serde::Serializable::serialize(obj.low, serializer); + serde::Serializable::serialize(obj.high, serializer); + serde::Serializable::serialize(obj.result, serializer); +} + +template <> +template +Circuit::BlackBoxOp::FixedBaseScalarMul serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::FixedBaseScalarMul obj; + obj.low = serde::Deserializable::deserialize(deserializer); + obj.high = serde::Deserializable::deserialize(deserializer); + obj.result = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::EmbeddedCurveAdd& lhs, const BlackBoxOp::EmbeddedCurveAdd& rhs) +{ + if (!(lhs.input1_x == rhs.input1_x)) { + return false; + } + if (!(lhs.input1_y == rhs.input1_y)) { + return false; + } + if (!(lhs.input2_x == rhs.input2_x)) { + return false; + } + if (!(lhs.input2_y == rhs.input2_y)) { return false; } if (!(lhs.result == rhs.result)) { @@ -3277,17 +4049,17 @@ inline bool operator==(const BlackBoxOp::EcdsaSecp256r1& lhs, const BlackBoxOp:: return true; } -inline std::vector BlackBoxOp::EcdsaSecp256r1::bincodeSerialize() const +inline std::vector BlackBoxOp::EmbeddedCurveAdd::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::EcdsaSecp256r1 BlackBoxOp::EcdsaSecp256r1::bincodeDeserialize(std::vector input) +inline BlackBoxOp::EmbeddedCurveAdd BlackBoxOp::EmbeddedCurveAdd::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3298,44 +4070,38 @@ inline BlackBoxOp::EcdsaSecp256r1 BlackBoxOp::EcdsaSecp256r1::bincodeDeserialize template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::EcdsaSecp256r1& obj, - Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxOp::EmbeddedCurveAdd& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.hashed_msg, serializer); - serde::Serializable::serialize(obj.public_key_x, serializer); - serde::Serializable::serialize(obj.public_key_y, serializer); - serde::Serializable::serialize(obj.signature, serializer); + serde::Serializable::serialize(obj.input1_x, serializer); + serde::Serializable::serialize(obj.input1_y, serializer); + serde::Serializable::serialize(obj.input2_x, serializer); + serde::Serializable::serialize(obj.input2_y, serializer); serde::Serializable::serialize(obj.result, serializer); } template <> template -Circuit::BlackBoxOp::EcdsaSecp256r1 serde::Deserializable::deserialize( +Circuit::BlackBoxOp::EmbeddedCurveAdd serde::Deserializable::deserialize( Deserializer& deserializer) { - Circuit::BlackBoxOp::EcdsaSecp256r1 obj; - obj.hashed_msg = serde::Deserializable::deserialize(deserializer); - obj.public_key_x = serde::Deserializable::deserialize(deserializer); - obj.public_key_y = serde::Deserializable::deserialize(deserializer); - obj.signature = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxOp::EmbeddedCurveAdd obj; + obj.input1_x = serde::Deserializable::deserialize(deserializer); + obj.input1_y = serde::Deserializable::deserialize(deserializer); + obj.input2_x = serde::Deserializable::deserialize(deserializer); + obj.input2_y = serde::Deserializable::deserialize(deserializer); obj.result = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::SchnorrVerify& lhs, const BlackBoxOp::SchnorrVerify& rhs) +inline bool operator==(const BlackBoxOp::EmbeddedCurveDouble& lhs, const BlackBoxOp::EmbeddedCurveDouble& rhs) { - if (!(lhs.public_key_x == rhs.public_key_x)) { - return false; - } - if (!(lhs.public_key_y == rhs.public_key_y)) { - return false; - } - if (!(lhs.message == rhs.message)) { + if (!(lhs.input1_x == rhs.input1_x)) { return false; } - if (!(lhs.signature == rhs.signature)) { + if (!(lhs.input1_y == rhs.input1_y)) { return false; } if (!(lhs.result == rhs.result)) { @@ -3344,17 +4110,17 @@ inline bool operator==(const BlackBoxOp::SchnorrVerify& lhs, const BlackBoxOp::S return true; } -inline std::vector BlackBoxOp::SchnorrVerify::bincodeSerialize() const +inline std::vector BlackBoxOp::EmbeddedCurveDouble::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::SchnorrVerify BlackBoxOp::SchnorrVerify::bincodeDeserialize(std::vector input) +inline BlackBoxOp::EmbeddedCurveDouble BlackBoxOp::EmbeddedCurveDouble::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3365,38 +4131,34 @@ inline BlackBoxOp::SchnorrVerify BlackBoxOp::SchnorrVerify::bincodeDeserialize(s template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::SchnorrVerify& obj, - Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxOp::EmbeddedCurveDouble& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.public_key_x, serializer); - serde::Serializable::serialize(obj.public_key_y, serializer); - serde::Serializable::serialize(obj.message, serializer); - serde::Serializable::serialize(obj.signature, serializer); + serde::Serializable::serialize(obj.input1_x, serializer); + serde::Serializable::serialize(obj.input1_y, serializer); serde::Serializable::serialize(obj.result, serializer); } template <> template -Circuit::BlackBoxOp::SchnorrVerify serde::Deserializable::deserialize( +Circuit::BlackBoxOp::EmbeddedCurveDouble serde::Deserializable::deserialize( Deserializer& deserializer) { - Circuit::BlackBoxOp::SchnorrVerify obj; - obj.public_key_x = serde::Deserializable::deserialize(deserializer); - obj.public_key_y = serde::Deserializable::deserialize(deserializer); - obj.message = serde::Deserializable::deserialize(deserializer); - obj.signature = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxOp::EmbeddedCurveDouble obj; + obj.input1_x = serde::Deserializable::deserialize(deserializer); + obj.input1_y = serde::Deserializable::deserialize(deserializer); obj.result = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::PedersenCommitment& lhs, const BlackBoxOp::PedersenCommitment& rhs) +inline bool operator==(const BlackBoxOp::BigIntAdd& lhs, const BlackBoxOp::BigIntAdd& rhs) { - if (!(lhs.inputs == rhs.inputs)) { + if (!(lhs.lhs == rhs.lhs)) { return false; } - if (!(lhs.domain_separator == rhs.domain_separator)) { + if (!(lhs.rhs == rhs.rhs)) { return false; } if (!(lhs.output == rhs.output)) { @@ -3405,17 +4167,17 @@ inline bool operator==(const BlackBoxOp::PedersenCommitment& lhs, const BlackBox return true; } -inline std::vector BlackBoxOp::PedersenCommitment::bincodeSerialize() const +inline std::vector BlackBoxOp::BigIntAdd::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::PedersenCommitment BlackBoxOp::PedersenCommitment::bincodeDeserialize(std::vector input) +inline BlackBoxOp::BigIntAdd BlackBoxOp::BigIntAdd::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3426,34 +4188,34 @@ inline BlackBoxOp::PedersenCommitment BlackBoxOp::PedersenCommitment::bincodeDes template <> template -void serde::Serializable::serialize( - const Circuit::BlackBoxOp::PedersenCommitment& obj, Serializer& serializer) +void serde::Serializable::serialize(const Circuit::BlackBoxOp::BigIntAdd& obj, + Serializer& serializer) { - serde::Serializable::serialize(obj.inputs, serializer); - serde::Serializable::serialize(obj.domain_separator, serializer); + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::PedersenCommitment serde::Deserializable::deserialize( +Circuit::BlackBoxOp::BigIntAdd serde::Deserializable::deserialize( Deserializer& deserializer) { - Circuit::BlackBoxOp::PedersenCommitment obj; - obj.inputs = serde::Deserializable::deserialize(deserializer); - obj.domain_separator = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxOp::BigIntAdd obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::PedersenHash& lhs, const BlackBoxOp::PedersenHash& rhs) +inline bool operator==(const BlackBoxOp::BigIntNeg& lhs, const BlackBoxOp::BigIntNeg& rhs) { - if (!(lhs.inputs == rhs.inputs)) { + if (!(lhs.lhs == rhs.lhs)) { return false; } - if (!(lhs.domain_separator == rhs.domain_separator)) { + if (!(lhs.rhs == rhs.rhs)) { return false; } if (!(lhs.output == rhs.output)) { @@ -3462,17 +4224,17 @@ inline bool operator==(const BlackBoxOp::PedersenHash& lhs, const BlackBoxOp::Pe return true; } -inline std::vector BlackBoxOp::PedersenHash::bincodeSerialize() const +inline std::vector BlackBoxOp::BigIntNeg::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::PedersenHash BlackBoxOp::PedersenHash::bincodeDeserialize(std::vector input) +inline BlackBoxOp::BigIntNeg BlackBoxOp::BigIntNeg::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3483,53 +4245,53 @@ inline BlackBoxOp::PedersenHash BlackBoxOp::PedersenHash::bincodeDeserialize(std template <> template -void serde::Serializable::serialize(const Circuit::BlackBoxOp::PedersenHash& obj, - Serializer& serializer) +void serde::Serializable::serialize(const Circuit::BlackBoxOp::BigIntNeg& obj, + Serializer& serializer) { - serde::Serializable::serialize(obj.inputs, serializer); - serde::Serializable::serialize(obj.domain_separator, serializer); + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::PedersenHash serde::Deserializable::deserialize( +Circuit::BlackBoxOp::BigIntNeg serde::Deserializable::deserialize( Deserializer& deserializer) { - Circuit::BlackBoxOp::PedersenHash obj; - obj.inputs = serde::Deserializable::deserialize(deserializer); - obj.domain_separator = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxOp::BigIntNeg obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::FixedBaseScalarMul& lhs, const BlackBoxOp::FixedBaseScalarMul& rhs) +inline bool operator==(const BlackBoxOp::BigIntMul& lhs, const BlackBoxOp::BigIntMul& rhs) { - if (!(lhs.low == rhs.low)) { + if (!(lhs.lhs == rhs.lhs)) { return false; } - if (!(lhs.high == rhs.high)) { + if (!(lhs.rhs == rhs.rhs)) { return false; } - if (!(lhs.result == rhs.result)) { + if (!(lhs.output == rhs.output)) { return false; } return true; } -inline std::vector BlackBoxOp::FixedBaseScalarMul::bincodeSerialize() const +inline std::vector BlackBoxOp::BigIntMul::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::FixedBaseScalarMul BlackBoxOp::FixedBaseScalarMul::bincodeDeserialize(std::vector input) +inline BlackBoxOp::BigIntMul BlackBoxOp::BigIntMul::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3540,59 +4302,110 @@ inline BlackBoxOp::FixedBaseScalarMul BlackBoxOp::FixedBaseScalarMul::bincodeDes template <> template -void serde::Serializable::serialize( - const Circuit::BlackBoxOp::FixedBaseScalarMul& obj, Serializer& serializer) +void serde::Serializable::serialize(const Circuit::BlackBoxOp::BigIntMul& obj, + Serializer& serializer) { - serde::Serializable::serialize(obj.low, serializer); - serde::Serializable::serialize(obj.high, serializer); - serde::Serializable::serialize(obj.result, serializer); + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::FixedBaseScalarMul serde::Deserializable::deserialize( +Circuit::BlackBoxOp::BigIntMul serde::Deserializable::deserialize( Deserializer& deserializer) { - Circuit::BlackBoxOp::FixedBaseScalarMul obj; - obj.low = serde::Deserializable::deserialize(deserializer); - obj.high = serde::Deserializable::deserialize(deserializer); - obj.result = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxOp::BigIntMul obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::EmbeddedCurveAdd& lhs, const BlackBoxOp::EmbeddedCurveAdd& rhs) +inline bool operator==(const BlackBoxOp::BigIntDiv& lhs, const BlackBoxOp::BigIntDiv& rhs) { - if (!(lhs.input1_x == rhs.input1_x)) { + if (!(lhs.lhs == rhs.lhs)) { return false; } - if (!(lhs.input1_y == rhs.input1_y)) { + if (!(lhs.rhs == rhs.rhs)) { return false; } - if (!(lhs.input2_x == rhs.input2_x)) { + if (!(lhs.output == rhs.output)) { return false; } - if (!(lhs.input2_y == rhs.input2_y)) { + return true; +} + +inline std::vector BlackBoxOp::BigIntDiv::bincodeSerialize() const +{ + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); +} + +inline BlackBoxOp::BigIntDiv BlackBoxOp::BigIntDiv::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::BlackBoxOp::BigIntDiv& obj, + Serializer& serializer) +{ + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::BigIntDiv serde::Deserializable::deserialize( + Deserializer& deserializer) +{ + Circuit::BlackBoxOp::BigIntDiv obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + +inline bool operator==(const BlackBoxOp::BigIntFromLeBytes& lhs, const BlackBoxOp::BigIntFromLeBytes& rhs) +{ + if (!(lhs.inputs == rhs.inputs)) { return false; } - if (!(lhs.result == rhs.result)) { + if (!(lhs.modulus == rhs.modulus)) { + return false; + } + if (!(lhs.output == rhs.output)) { return false; } return true; } -inline std::vector BlackBoxOp::EmbeddedCurveAdd::bincodeSerialize() const +inline std::vector BlackBoxOp::BigIntFromLeBytes::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::EmbeddedCurveAdd BlackBoxOp::EmbeddedCurveAdd::bincodeDeserialize(std::vector input) +inline BlackBoxOp::BigIntFromLeBytes BlackBoxOp::BigIntFromLeBytes::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3603,57 +4416,50 @@ inline BlackBoxOp::EmbeddedCurveAdd BlackBoxOp::EmbeddedCurveAdd::bincodeDeseria template <> template -void serde::Serializable::serialize( - const Circuit::BlackBoxOp::EmbeddedCurveAdd& obj, Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxOp::BigIntFromLeBytes& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.input1_x, serializer); - serde::Serializable::serialize(obj.input1_y, serializer); - serde::Serializable::serialize(obj.input2_x, serializer); - serde::Serializable::serialize(obj.input2_y, serializer); - serde::Serializable::serialize(obj.result, serializer); + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.modulus, serializer); + serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::EmbeddedCurveAdd serde::Deserializable::deserialize( +Circuit::BlackBoxOp::BigIntFromLeBytes serde::Deserializable::deserialize( Deserializer& deserializer) { - Circuit::BlackBoxOp::EmbeddedCurveAdd obj; - obj.input1_x = serde::Deserializable::deserialize(deserializer); - obj.input1_y = serde::Deserializable::deserialize(deserializer); - obj.input2_x = serde::Deserializable::deserialize(deserializer); - obj.input2_y = serde::Deserializable::deserialize(deserializer); - obj.result = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxOp::BigIntFromLeBytes obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.modulus = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); return obj; } namespace Circuit { -inline bool operator==(const BlackBoxOp::EmbeddedCurveDouble& lhs, const BlackBoxOp::EmbeddedCurveDouble& rhs) +inline bool operator==(const BlackBoxOp::BigIntToLeBytes& lhs, const BlackBoxOp::BigIntToLeBytes& rhs) { - if (!(lhs.input1_x == rhs.input1_x)) { - return false; - } - if (!(lhs.input1_y == rhs.input1_y)) { + if (!(lhs.input == rhs.input)) { return false; } - if (!(lhs.result == rhs.result)) { + if (!(lhs.output == rhs.output)) { return false; } return true; } -inline std::vector BlackBoxOp::EmbeddedCurveDouble::bincodeSerialize() const +inline std::vector BlackBoxOp::BigIntToLeBytes::bincodeSerialize() const { auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); + serde::Serializable::serialize(*this, serializer); return std::move(serializer).bytes(); } -inline BlackBoxOp::EmbeddedCurveDouble BlackBoxOp::EmbeddedCurveDouble::bincodeDeserialize(std::vector input) +inline BlackBoxOp::BigIntToLeBytes BlackBoxOp::BigIntToLeBytes::bincodeDeserialize(std::vector input) { auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); + auto value = serde::Deserializable::deserialize(deserializer); if (deserializer.get_buffer_offset() < input.size()) { throw_or_abort("Some input bytes were not read"); } @@ -3664,23 +4470,21 @@ inline BlackBoxOp::EmbeddedCurveDouble BlackBoxOp::EmbeddedCurveDouble::bincodeD template <> template -void serde::Serializable::serialize( - const Circuit::BlackBoxOp::EmbeddedCurveDouble& obj, Serializer& serializer) +void serde::Serializable::serialize( + const Circuit::BlackBoxOp::BigIntToLeBytes& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.input1_x, serializer); - serde::Serializable::serialize(obj.input1_y, serializer); - serde::Serializable::serialize(obj.result, serializer); + serde::Serializable::serialize(obj.input, serializer); + serde::Serializable::serialize(obj.output, serializer); } template <> template -Circuit::BlackBoxOp::EmbeddedCurveDouble serde::Deserializable::deserialize( +Circuit::BlackBoxOp::BigIntToLeBytes serde::Deserializable::deserialize( Deserializer& deserializer) { - Circuit::BlackBoxOp::EmbeddedCurveDouble obj; - obj.input1_x = serde::Deserializable::deserialize(deserializer); - obj.input1_y = serde::Deserializable::deserialize(deserializer); - obj.result = serde::Deserializable::deserialize(deserializer); + Circuit::BlackBoxOp::BigIntToLeBytes obj; + obj.input = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/noir/acvm-repo/acir/codegen/acir.cpp b/noir/acvm-repo/acir/codegen/acir.cpp index 9b74a8ea631..07bcd5f9f97 100644 --- a/noir/acvm-repo/acir/codegen/acir.cpp +++ b/noir/acvm-repo/acir/codegen/acir.cpp @@ -206,7 +206,66 @@ namespace Circuit { static RecursiveAggregation bincodeDeserialize(std::vector); }; - std::variant value; + struct BigIntAdd { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntAdd&, const BigIntAdd&); + std::vector bincodeSerialize() const; + static BigIntAdd bincodeDeserialize(std::vector); + }; + + struct BigIntNeg { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntNeg&, const BigIntNeg&); + std::vector bincodeSerialize() const; + static BigIntNeg bincodeDeserialize(std::vector); + }; + + struct BigIntMul { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntMul&, const BigIntMul&); + std::vector bincodeSerialize() const; + static BigIntMul bincodeDeserialize(std::vector); + }; + + struct BigIntDiv { + uint32_t lhs; + uint32_t rhs; + uint32_t output; + + friend bool operator==(const BigIntDiv&, const BigIntDiv&); + std::vector bincodeSerialize() const; + static BigIntDiv bincodeDeserialize(std::vector); + }; + + struct BigIntFromLeBytes { + std::vector inputs; + std::vector modulus; + uint32_t output; + + friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); + std::vector bincodeSerialize() const; + static BigIntFromLeBytes bincodeDeserialize(std::vector); + }; + + struct BigIntToLeBytes { + uint32_t input; + std::vector outputs; + + friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); + std::vector bincodeSerialize() const; + static BigIntToLeBytes bincodeDeserialize(std::vector); + }; + + std::variant value; friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&); std::vector bincodeSerialize() const; @@ -543,7 +602,66 @@ namespace Circuit { static EmbeddedCurveDouble bincodeDeserialize(std::vector); }; - std::variant value; + struct BigIntAdd { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntAdd&, const BigIntAdd&); + std::vector bincodeSerialize() const; + static BigIntAdd bincodeDeserialize(std::vector); + }; + + struct BigIntNeg { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntNeg&, const BigIntNeg&); + std::vector bincodeSerialize() const; + static BigIntNeg bincodeDeserialize(std::vector); + }; + + struct BigIntMul { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntMul&, const BigIntMul&); + std::vector bincodeSerialize() const; + static BigIntMul bincodeDeserialize(std::vector); + }; + + struct BigIntDiv { + Circuit::RegisterIndex lhs; + Circuit::RegisterIndex rhs; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntDiv&, const BigIntDiv&); + std::vector bincodeSerialize() const; + static BigIntDiv bincodeDeserialize(std::vector); + }; + + struct BigIntFromLeBytes { + Circuit::HeapVector inputs; + Circuit::HeapVector modulus; + Circuit::RegisterIndex output; + + friend bool operator==(const BigIntFromLeBytes&, const BigIntFromLeBytes&); + std::vector bincodeSerialize() const; + static BigIntFromLeBytes bincodeDeserialize(std::vector); + }; + + struct BigIntToLeBytes { + Circuit::RegisterIndex input; + Circuit::HeapVector output; + + friend bool operator==(const BigIntToLeBytes&, const BigIntToLeBytes&); + std::vector bincodeSerialize() const; + static BigIntToLeBytes bincodeDeserialize(std::vector); + }; + + std::variant value; friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); std::vector bincodeSerialize() const; @@ -2469,6 +2587,267 @@ Circuit::BlackBoxFuncCall::RecursiveAggregation serde::Deserializable BlackBoxFuncCall::BigIntAdd::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxFuncCall::BigIntAdd BlackBoxFuncCall::BigIntAdd::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::BlackBoxFuncCall::BigIntAdd &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxFuncCall::BigIntAdd serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntAdd obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxFuncCall::BigIntNeg &lhs, const BlackBoxFuncCall::BigIntNeg &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxFuncCall::BigIntNeg::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxFuncCall::BigIntNeg BlackBoxFuncCall::BigIntNeg::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::BlackBoxFuncCall::BigIntNeg &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxFuncCall::BigIntNeg serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntNeg obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxFuncCall::BigIntMul &lhs, const BlackBoxFuncCall::BigIntMul &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxFuncCall::BigIntMul::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxFuncCall::BigIntMul BlackBoxFuncCall::BigIntMul::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::BlackBoxFuncCall::BigIntMul &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxFuncCall::BigIntMul serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntMul obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxFuncCall::BigIntDiv &lhs, const BlackBoxFuncCall::BigIntDiv &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxFuncCall::BigIntDiv::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxFuncCall::BigIntDiv BlackBoxFuncCall::BigIntDiv::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::BlackBoxFuncCall::BigIntDiv &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxFuncCall::BigIntDiv serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntDiv obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxFuncCall::BigIntFromLeBytes &lhs, const BlackBoxFuncCall::BigIntFromLeBytes &rhs) { + if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.modulus == rhs.modulus)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxFuncCall::BigIntFromLeBytes::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxFuncCall::BigIntFromLeBytes BlackBoxFuncCall::BigIntFromLeBytes::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::BlackBoxFuncCall::BigIntFromLeBytes &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.modulus, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxFuncCall::BigIntFromLeBytes serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntFromLeBytes obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.modulus = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxFuncCall::BigIntToLeBytes &lhs, const BlackBoxFuncCall::BigIntToLeBytes &rhs) { + if (!(lhs.input == rhs.input)) { return false; } + if (!(lhs.outputs == rhs.outputs)) { return false; } + return true; + } + + inline std::vector BlackBoxFuncCall::BigIntToLeBytes::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxFuncCall::BigIntToLeBytes BlackBoxFuncCall::BigIntToLeBytes::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::BlackBoxFuncCall::BigIntToLeBytes &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.input, serializer); + serde::Serializable::serialize(obj.outputs, serializer); +} + +template <> +template +Circuit::BlackBoxFuncCall::BigIntToLeBytes serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxFuncCall::BigIntToLeBytes obj; + obj.input = serde::Deserializable::deserialize(deserializer); + obj.outputs = serde::Deserializable::deserialize(deserializer); + return obj; +} + namespace Circuit { inline bool operator==(const BlackBoxOp &lhs, const BlackBoxOp &rhs) { @@ -3092,6 +3471,267 @@ Circuit::BlackBoxOp::EmbeddedCurveDouble serde::Deserializable BlackBoxOp::BigIntAdd::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::BigIntAdd BlackBoxOp::BigIntAdd::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::BlackBoxOp::BigIntAdd &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::BigIntAdd serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntAdd obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::BigIntNeg &lhs, const BlackBoxOp::BigIntNeg &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::BigIntNeg::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::BigIntNeg BlackBoxOp::BigIntNeg::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::BlackBoxOp::BigIntNeg &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::BigIntNeg serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntNeg obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::BigIntMul &lhs, const BlackBoxOp::BigIntMul &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::BigIntMul::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::BigIntMul BlackBoxOp::BigIntMul::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::BlackBoxOp::BigIntMul &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::BigIntMul serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntMul obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::BigIntDiv &lhs, const BlackBoxOp::BigIntDiv &rhs) { + if (!(lhs.lhs == rhs.lhs)) { return false; } + if (!(lhs.rhs == rhs.rhs)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::BigIntDiv::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::BigIntDiv BlackBoxOp::BigIntDiv::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::BlackBoxOp::BigIntDiv &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.lhs, serializer); + serde::Serializable::serialize(obj.rhs, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::BigIntDiv serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntDiv obj; + obj.lhs = serde::Deserializable::deserialize(deserializer); + obj.rhs = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::BigIntFromLeBytes &lhs, const BlackBoxOp::BigIntFromLeBytes &rhs) { + if (!(lhs.inputs == rhs.inputs)) { return false; } + if (!(lhs.modulus == rhs.modulus)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::BigIntFromLeBytes::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::BigIntFromLeBytes BlackBoxOp::BigIntFromLeBytes::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::BlackBoxOp::BigIntFromLeBytes &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.inputs, serializer); + serde::Serializable::serialize(obj.modulus, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::BigIntFromLeBytes serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntFromLeBytes obj; + obj.inputs = serde::Deserializable::deserialize(deserializer); + obj.modulus = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + +namespace Circuit { + + inline bool operator==(const BlackBoxOp::BigIntToLeBytes &lhs, const BlackBoxOp::BigIntToLeBytes &rhs) { + if (!(lhs.input == rhs.input)) { return false; } + if (!(lhs.output == rhs.output)) { return false; } + return true; + } + + inline std::vector BlackBoxOp::BigIntToLeBytes::bincodeSerialize() const { + auto serializer = serde::BincodeSerializer(); + serde::Serializable::serialize(*this, serializer); + return std::move(serializer).bytes(); + } + + inline BlackBoxOp::BigIntToLeBytes BlackBoxOp::BigIntToLeBytes::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::BlackBoxOp::BigIntToLeBytes &obj, Serializer &serializer) { + serde::Serializable::serialize(obj.input, serializer); + serde::Serializable::serialize(obj.output, serializer); +} + +template <> +template +Circuit::BlackBoxOp::BigIntToLeBytes serde::Deserializable::deserialize(Deserializer &deserializer) { + Circuit::BlackBoxOp::BigIntToLeBytes obj; + obj.input = serde::Deserializable::deserialize(deserializer); + obj.output = serde::Deserializable::deserialize(deserializer); + return obj; +} + namespace Circuit { inline bool operator==(const BlockId &lhs, const BlockId &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 d1f5560313b..41b8923a8c9 100644 --- a/noir/acvm-repo/acir/src/circuit/black_box_functions.rs +++ b/noir/acvm-repo/acir/src/circuit/black_box_functions.rs @@ -49,6 +49,18 @@ pub enum BlackBoxFunc { EmbeddedCurveAdd, /// Point doubling over the embedded curve on which [`FieldElement`][acir_field::FieldElement] is defined. EmbeddedCurveDouble, + /// BigInt addition + BigIntAdd, + /// BigInt subtraction + BigIntNeg, + /// BigInt multiplication + BigIntMul, + /// BigInt division + BigIntDiv, + /// BigInt from le bytes + BigIntFromLeBytes, + /// BigInt to le bytes + BigIntToLeBytes, } impl std::fmt::Display for BlackBoxFunc { @@ -77,8 +89,15 @@ impl BlackBoxFunc { BlackBoxFunc::Keccakf1600 => "keccakf1600", BlackBoxFunc::RecursiveAggregation => "recursive_aggregation", BlackBoxFunc::EcdsaSecp256r1 => "ecdsa_secp256r1", + BlackBoxFunc::BigIntAdd => "bigint_add", + BlackBoxFunc::BigIntNeg => "bigint_neg", + BlackBoxFunc::BigIntMul => "bigint_mul", + BlackBoxFunc::BigIntDiv => "bigint_div", + BlackBoxFunc::BigIntFromLeBytes => "bigint_from_le_bytes", + BlackBoxFunc::BigIntToLeBytes => "bigint_to_le_bytes", } } + pub fn lookup(op_name: &str) -> Option { match op_name { "sha256" => Some(BlackBoxFunc::SHA256), @@ -98,6 +117,12 @@ impl BlackBoxFunc { "keccak256" => Some(BlackBoxFunc::Keccak256), "keccakf1600" => Some(BlackBoxFunc::Keccakf1600), "recursive_aggregation" => Some(BlackBoxFunc::RecursiveAggregation), + "bigint_add" => Some(BlackBoxFunc::BigIntAdd), + "bigint_neg" => Some(BlackBoxFunc::BigIntNeg), + "bigint_mul" => Some(BlackBoxFunc::BigIntMul), + "bigint_div" => Some(BlackBoxFunc::BigIntDiv), + "bigint_from_le_bytes" => Some(BlackBoxFunc::BigIntFromLeBytes), + "bigint_to_le_bytes" => Some(BlackBoxFunc::BigIntToLeBytes), _ => None, } } diff --git a/noir/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/noir/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 7ee4e2498a5..1fdc0265377 100644 --- a/noir/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/noir/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -120,6 +120,35 @@ pub enum BlackBoxFuncCall { /// key provided to the circuit matches the key produced by the circuit creator key_hash: FunctionInput, }, + BigIntAdd { + lhs: u32, + rhs: u32, + output: u32, + }, + BigIntNeg { + lhs: u32, + rhs: u32, + output: u32, + }, + BigIntMul { + lhs: u32, + rhs: u32, + output: u32, + }, + BigIntDiv { + lhs: u32, + rhs: u32, + output: u32, + }, + BigIntFromLeBytes { + inputs: Vec, + modulus: Vec, + output: u32, + }, + BigIntToLeBytes { + input: u32, + outputs: Vec, + }, } impl BlackBoxFuncCall { @@ -143,6 +172,12 @@ impl BlackBoxFuncCall { BlackBoxFuncCall::Keccak256VariableLength { .. } => BlackBoxFunc::Keccak256, BlackBoxFuncCall::Keccakf1600 { .. } => BlackBoxFunc::Keccakf1600, BlackBoxFuncCall::RecursiveAggregation { .. } => BlackBoxFunc::RecursiveAggregation, + BlackBoxFuncCall::BigIntAdd { .. } => BlackBoxFunc::BigIntAdd, + BlackBoxFuncCall::BigIntNeg { .. } => BlackBoxFunc::BigIntNeg, + BlackBoxFuncCall::BigIntMul { .. } => BlackBoxFunc::BigIntMul, + BlackBoxFuncCall::BigIntDiv { .. } => BlackBoxFunc::BigIntDiv, + BlackBoxFuncCall::BigIntFromLeBytes { .. } => BlackBoxFunc::BigIntFromLeBytes, + &BlackBoxFuncCall::BigIntToLeBytes { .. } => BlackBoxFunc::BigIntToLeBytes, } } @@ -158,10 +193,16 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::Keccak256 { inputs, .. } | BlackBoxFuncCall::Keccakf1600 { inputs, .. } | BlackBoxFuncCall::PedersenCommitment { inputs, .. } - | BlackBoxFuncCall::PedersenHash { inputs, .. } => inputs.to_vec(), + | BlackBoxFuncCall::PedersenHash { inputs, .. } + | BlackBoxFuncCall::BigIntFromLeBytes { inputs, .. } => inputs.to_vec(), BlackBoxFuncCall::AND { lhs, rhs, .. } | BlackBoxFuncCall::XOR { lhs, rhs, .. } => { vec![*lhs, *rhs] } + BlackBoxFuncCall::BigIntAdd { .. } + | BlackBoxFuncCall::BigIntNeg { .. } + | BlackBoxFuncCall::BigIntMul { .. } + | BlackBoxFuncCall::BigIntDiv { .. } + | BlackBoxFuncCall::BigIntToLeBytes { .. } => Vec::new(), BlackBoxFuncCall::FixedBaseScalarMul { low, high, .. } => vec![*low, *high], BlackBoxFuncCall::EmbeddedCurveAdd { input1_x, input1_y, input2_x, input2_y, .. @@ -249,7 +290,8 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::Blake2s { outputs, .. } | BlackBoxFuncCall::Blake3 { outputs, .. } | BlackBoxFuncCall::Keccak256 { outputs, .. } - | BlackBoxFuncCall::Keccakf1600 { outputs, .. } => outputs.to_vec(), + | BlackBoxFuncCall::Keccakf1600 { outputs, .. } + | BlackBoxFuncCall::Keccak256VariableLength { outputs, .. } => outputs.to_vec(), BlackBoxFuncCall::AND { output, .. } | BlackBoxFuncCall::XOR { output, .. } | BlackBoxFuncCall::SchnorrVerify { output, .. } @@ -260,10 +302,16 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::PedersenCommitment { outputs, .. } | BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } | BlackBoxFuncCall::EmbeddedCurveDouble { outputs, .. } => vec![outputs.0, outputs.1], - BlackBoxFuncCall::RANGE { .. } | BlackBoxFuncCall::RecursiveAggregation { .. } => { + BlackBoxFuncCall::RANGE { .. } + | BlackBoxFuncCall::RecursiveAggregation { .. } + | BlackBoxFuncCall::BigIntFromLeBytes { .. } + | BlackBoxFuncCall::BigIntAdd { .. } + | BlackBoxFuncCall::BigIntNeg { .. } + | BlackBoxFuncCall::BigIntMul { .. } + | BlackBoxFuncCall::BigIntDiv { .. } => { vec![] } - BlackBoxFuncCall::Keccak256VariableLength { outputs, .. } => outputs.to_vec(), + BlackBoxFuncCall::BigIntToLeBytes { outputs, .. } => outputs.to_vec(), } } } diff --git a/noir/acvm-repo/acvm/src/compiler/transformers/mod.rs b/noir/acvm-repo/acvm/src/compiler/transformers/mod.rs index 306ea1b7c12..effe1128d36 100644 --- a/noir/acvm-repo/acvm/src/compiler/transformers/mod.rs +++ b/noir/acvm-repo/acvm/src/compiler/transformers/mod.rs @@ -105,7 +105,12 @@ pub(super) fn transform_internal( transformer.mark_solvable(*output); } acir::circuit::opcodes::BlackBoxFuncCall::RANGE { .. } - | acir::circuit::opcodes::BlackBoxFuncCall::RecursiveAggregation { .. } => (), + | acir::circuit::opcodes::BlackBoxFuncCall::RecursiveAggregation { .. } + | acir::circuit::opcodes::BlackBoxFuncCall::BigIntFromLeBytes { .. } + | acir::circuit::opcodes::BlackBoxFuncCall::BigIntAdd { .. } + | acir::circuit::opcodes::BlackBoxFuncCall::BigIntNeg { .. } + | acir::circuit::opcodes::BlackBoxFuncCall::BigIntMul { .. } + | acir::circuit::opcodes::BlackBoxFuncCall::BigIntDiv { .. } => (), acir::circuit::opcodes::BlackBoxFuncCall::SHA256 { outputs, .. } | acir::circuit::opcodes::BlackBoxFuncCall::Keccak256 { outputs, .. } | acir::circuit::opcodes::BlackBoxFuncCall::Keccak256VariableLength { @@ -114,7 +119,10 @@ pub(super) fn transform_internal( } | acir::circuit::opcodes::BlackBoxFuncCall::Keccakf1600 { outputs, .. } | acir::circuit::opcodes::BlackBoxFuncCall::Blake2s { outputs, .. } - | acir::circuit::opcodes::BlackBoxFuncCall::Blake3 { outputs, .. } => { + | acir::circuit::opcodes::BlackBoxFuncCall::Blake3 { outputs, .. } + | acir::circuit::opcodes::BlackBoxFuncCall::BigIntToLeBytes { + outputs, .. + } => { for witness in outputs { transformer.mark_solvable(*witness); } diff --git a/noir/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/noir/acvm-repo/acvm/src/pwg/blackbox/mod.rs index 5eea234885c..a56b24b86f3 100644 --- a/noir/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/noir/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -185,5 +185,11 @@ pub(crate) fn solve( } // Recursive aggregation will be entirely handled by the backend and is not solved by the ACVM BlackBoxFuncCall::RecursiveAggregation { .. } => Ok(()), + BlackBoxFuncCall::BigIntAdd { .. } => todo!(), + BlackBoxFuncCall::BigIntNeg { .. } => todo!(), + BlackBoxFuncCall::BigIntMul { .. } => todo!(), + BlackBoxFuncCall::BigIntDiv { .. } => todo!(), + BlackBoxFuncCall::BigIntFromLeBytes { .. } => todo!(), + BlackBoxFuncCall::BigIntToLeBytes { .. } => todo!(), } } diff --git a/noir/acvm-repo/brillig/src/black_box.rs b/noir/acvm-repo/brillig/src/black_box.rs index c007e78b785..5893758ce9e 100644 --- a/noir/acvm-repo/brillig/src/black_box.rs +++ b/noir/acvm-repo/brillig/src/black_box.rs @@ -6,15 +6,30 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum BlackBoxOp { /// Calculates the SHA256 hash of the inputs. - Sha256 { message: HeapVector, output: HeapArray }, + Sha256 { + message: HeapVector, + output: HeapArray, + }, /// Calculates the Blake2s hash of the inputs. - Blake2s { message: HeapVector, output: HeapArray }, + Blake2s { + message: HeapVector, + output: HeapArray, + }, /// Calculates the Blake3 hash of the inputs. - Blake3 { message: HeapVector, output: HeapArray }, + Blake3 { + message: HeapVector, + output: HeapArray, + }, /// Calculates the Keccak256 hash of the inputs. - Keccak256 { message: HeapVector, output: HeapArray }, + Keccak256 { + message: HeapVector, + output: HeapArray, + }, /// Keccak Permutation function of 1600 width - Keccakf1600 { message: HeapVector, output: HeapArray }, + Keccakf1600 { + message: HeapVector, + output: HeapArray, + }, /// Verifies a ECDSA signature over the secp256k1 curve. EcdsaSecp256k1 { hashed_msg: HeapVector, @@ -40,11 +55,23 @@ pub enum BlackBoxOp { result: RegisterIndex, }, /// Calculates a Pedersen commitment to the inputs. - PedersenCommitment { inputs: HeapVector, domain_separator: RegisterIndex, output: HeapArray }, + PedersenCommitment { + inputs: HeapVector, + domain_separator: RegisterIndex, + output: HeapArray, + }, /// Calculates a Pedersen hash to the inputs. - PedersenHash { inputs: HeapVector, domain_separator: RegisterIndex, output: RegisterIndex }, + PedersenHash { + inputs: HeapVector, + domain_separator: RegisterIndex, + output: RegisterIndex, + }, /// Performs scalar multiplication over the embedded curve. - FixedBaseScalarMul { low: RegisterIndex, high: RegisterIndex, result: HeapArray }, + FixedBaseScalarMul { + low: RegisterIndex, + high: RegisterIndex, + result: HeapArray, + }, /// Performs addition over the embedded curve. EmbeddedCurveAdd { input1_x: RegisterIndex, @@ -54,5 +81,39 @@ pub enum BlackBoxOp { result: HeapArray, }, /// Performs point doubling over the embedded curve. - EmbeddedCurveDouble { input1_x: RegisterIndex, input1_y: RegisterIndex, result: HeapArray }, + EmbeddedCurveDouble { + input1_x: RegisterIndex, + input1_y: RegisterIndex, + result: HeapArray, + }, + + BigIntAdd { + lhs: RegisterIndex, + rhs: RegisterIndex, + output: RegisterIndex, + }, + BigIntNeg { + lhs: RegisterIndex, + rhs: RegisterIndex, + output: RegisterIndex, + }, + BigIntMul { + lhs: RegisterIndex, + rhs: RegisterIndex, + output: RegisterIndex, + }, + BigIntDiv { + lhs: RegisterIndex, + rhs: RegisterIndex, + output: RegisterIndex, + }, + BigIntFromLeBytes { + inputs: HeapVector, + modulus: HeapVector, + output: RegisterIndex, + }, + BigIntToLeBytes { + input: RegisterIndex, + output: HeapVector, + }, } diff --git a/noir/acvm-repo/brillig_vm/src/black_box.rs b/noir/acvm-repo/brillig_vm/src/black_box.rs index 463038509e1..edbebb61ece 100644 --- a/noir/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/acvm-repo/brillig_vm/src/black_box.rs @@ -200,6 +200,12 @@ pub(crate) fn evaluate_black_box( registers.set(*output, hash.into()); Ok(()) } + BlackBoxOp::BigIntAdd { .. } => todo!(), + BlackBoxOp::BigIntNeg { .. } => todo!(), + BlackBoxOp::BigIntMul { .. } => todo!(), + BlackBoxOp::BigIntDiv { .. } => todo!(), + BlackBoxOp::BigIntFromLeBytes { .. } => todo!(), + BlackBoxOp::BigIntToLeBytes { .. } => todo!(), } } @@ -218,6 +224,12 @@ fn black_box_function_from_op(op: &BlackBoxOp) -> BlackBoxFunc { BlackBoxOp::FixedBaseScalarMul { .. } => BlackBoxFunc::FixedBaseScalarMul, BlackBoxOp::EmbeddedCurveAdd { .. } => BlackBoxFunc::EmbeddedCurveAdd, BlackBoxOp::EmbeddedCurveDouble { .. } => BlackBoxFunc::EmbeddedCurveDouble, + BlackBoxOp::BigIntAdd { .. } => BlackBoxFunc::BigIntAdd, + BlackBoxOp::BigIntNeg { .. } => BlackBoxFunc::BigIntNeg, + BlackBoxOp::BigIntMul { .. } => BlackBoxFunc::BigIntMul, + BlackBoxOp::BigIntDiv { .. } => BlackBoxFunc::BigIntDiv, + BlackBoxOp::BigIntFromLeBytes { .. } => BlackBoxFunc::BigIntFromLeBytes, + BlackBoxOp::BigIntToLeBytes { .. } => BlackBoxFunc::BigIntToLeBytes, } } diff --git a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index c081806f4a7..c7b6f39279b 100644 --- a/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/noir/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -244,6 +244,107 @@ pub(crate) fn convert_black_box_call( BlackBoxFunc::RecursiveAggregation => unimplemented!( "ICE: `BlackBoxFunc::RecursiveAggregation` is not implemented by the Brillig VM" ), + BlackBoxFunc::BigIntAdd => { + if let ( + [BrilligVariable::Simple(lhs), BrilligVariable::Simple(rhs)], + [BrilligVariable::Simple(output)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntAdd { + lhs: *lhs, + rhs: *rhs, + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntNeg => { + if let ( + [BrilligVariable::Simple(lhs), BrilligVariable::Simple(rhs)], + [BrilligVariable::Simple(output)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntNeg { + lhs: *lhs, + rhs: *rhs, + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntMul => { + if let ( + [BrilligVariable::Simple(lhs), BrilligVariable::Simple(rhs)], + [BrilligVariable::Simple(output)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntMul { + lhs: *lhs, + rhs: *rhs, + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntDiv => { + if let ( + [BrilligVariable::Simple(lhs), BrilligVariable::Simple(rhs)], + [BrilligVariable::Simple(output)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntDiv { + lhs: *lhs, + rhs: *rhs, + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntFromLeBytes => { + if let ([inputs, modulus], [BrilligVariable::Simple(output)]) = + (function_arguments, function_results) + { + let inputs_vector = convert_array_or_vector(brillig_context, inputs, bb_func); + let modulus_vector = convert_array_or_vector(brillig_context, modulus, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntFromLeBytes { + inputs: inputs_vector.to_heap_vector(), + modulus: modulus_vector.to_heap_vector(), + output: *output, + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } + BlackBoxFunc::BigIntToLeBytes => { + if let ( + [BrilligVariable::Simple(input)], + [BrilligVariable::BrilligVector(result_vector)], + ) = (function_arguments, function_results) + { + brillig_context.black_box_op_instruction(BlackBoxOp::BigIntToLeBytes { + input: *input, + output: result_vector.to_heap_vector(), + }); + } else { + unreachable!( + "ICE: EmbeddedCurveAdd expects two register arguments and one array result" + ) + } + } } } 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 dc8c6b6694c..5709b0a1aa2 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 @@ -457,6 +457,59 @@ impl DebugShow { result ); } + BlackBoxOp::BigIntAdd { lhs, rhs, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_ADD {} {} -> {}", + lhs, + rhs, + output + ); + } + BlackBoxOp::BigIntNeg { lhs, rhs, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_NEG {} {} -> {}", + lhs, + rhs, + output + ); + } + BlackBoxOp::BigIntMul { lhs, rhs, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_MUL {} {} -> {}", + lhs, + rhs, + output + ); + } + BlackBoxOp::BigIntDiv { lhs, rhs, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_DIV {} {} -> {}", + lhs, + rhs, + output + ); + } + BlackBoxOp::BigIntFromLeBytes { inputs, modulus, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_FROM_LE_BYTES {} {} -> {}", + inputs, + modulus, + output + ); + } + BlackBoxOp::BigIntToLeBytes { input, output } => { + debug_println!( + self.enable_debug_trace, + " BIGINT_TO_LE_BYTES {} -> {}", + input, + output + ); + } } } diff --git a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index efc64c5286e..4572cf1dd08 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -251,6 +251,34 @@ impl GeneratedAcir { public_inputs: inputs[2].clone(), key_hash: inputs[3][0], }, + BlackBoxFunc::BigIntAdd => BlackBoxFuncCall::BigIntAdd { + lhs: constants[0].to_u128() as u32, + rhs: constants[1].to_u128() as u32, + output: constants[2].to_u128() as u32, + }, + BlackBoxFunc::BigIntNeg => BlackBoxFuncCall::BigIntNeg { + lhs: constants[0].to_u128() as u32, + rhs: constants[1].to_u128() as u32, + output: constants[2].to_u128() as u32, + }, + BlackBoxFunc::BigIntMul => BlackBoxFuncCall::BigIntMul { + lhs: constants[0].to_u128() as u32, + rhs: constants[1].to_u128() as u32, + output: constants[2].to_u128() as u32, + }, + BlackBoxFunc::BigIntDiv => BlackBoxFuncCall::BigIntDiv { + lhs: constants[0].to_u128() as u32, + rhs: constants[1].to_u128() as u32, + output: constants[2].to_u128() as u32, + }, + BlackBoxFunc::BigIntFromLeBytes => BlackBoxFuncCall::BigIntFromLeBytes { + inputs: inputs[0].clone(), + modulus: vecmap(constants, |c| c.to_u128() as u8), + output: todo!(), + }, + BlackBoxFunc::BigIntToLeBytes => { + BlackBoxFuncCall::BigIntToLeBytes { input: constants[0].to_u128() as u32, outputs } + } }; self.push_opcode(AcirOpcode::BlackBoxFuncCall(black_box_func_call)); @@ -573,6 +601,7 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { match name { // Bitwise opcodes will take in 2 parameters BlackBoxFunc::AND | BlackBoxFunc::XOR => Some(2), + // All of the hash/cipher methods will take in a // variable number of inputs. BlackBoxFunc::Keccak256 @@ -593,15 +622,30 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { BlackBoxFunc::SchnorrVerify | BlackBoxFunc::EcdsaSecp256k1 | BlackBoxFunc::EcdsaSecp256r1 => None, + // Inputs for fixed based scalar multiplication // is the low and high limbs of the scalar BlackBoxFunc::FixedBaseScalarMul => Some(2), + // Recursive aggregation has a variable number of inputs BlackBoxFunc::RecursiveAggregation => None, + // Addition over the embedded curve: input are coordinates (x1,y1) and (x2,y2) of the Grumpkin points BlackBoxFunc::EmbeddedCurveAdd => Some(4), + // Doubling over the embedded curve: input is (x,y) coordinate of the point. BlackBoxFunc::EmbeddedCurveDouble => Some(2), + + // Big integer operations take in 2 inputs + BlackBoxFunc::BigIntAdd + | BlackBoxFunc::BigIntNeg + | BlackBoxFunc::BigIntMul + | BlackBoxFunc::BigIntDiv => Some(2), + + // FromLeBytes takes a variable array of bytes as input + BlackBoxFunc::BigIntFromLeBytes => None, + // ToLeBytes takes a single big integer as input + BlackBoxFunc::BigIntToLeBytes => Some(1), } } @@ -612,28 +656,46 @@ fn black_box_expected_output_size(name: BlackBoxFunc) -> Option { // Bitwise opcodes will return 1 parameter which is the output // or the operation. BlackBoxFunc::AND | BlackBoxFunc::XOR => Some(1), + // 32 byte hash algorithms BlackBoxFunc::Keccak256 | BlackBoxFunc::SHA256 | BlackBoxFunc::Blake2s | BlackBoxFunc::Blake3 => Some(32), + BlackBoxFunc::Keccakf1600 => Some(25), + // Pedersen commitment returns a point BlackBoxFunc::PedersenCommitment => Some(2), + // Pedersen hash returns a field BlackBoxFunc::PedersenHash => Some(1), + // Can only apply a range constraint to one // witness at a time. BlackBoxFunc::RANGE => Some(0), + // Signature verification algorithms will return a boolean BlackBoxFunc::SchnorrVerify | BlackBoxFunc::EcdsaSecp256k1 | BlackBoxFunc::EcdsaSecp256r1 => Some(1), + // Output of operations over the embedded curve // will be 2 field elements representing the point. BlackBoxFunc::FixedBaseScalarMul | BlackBoxFunc::EmbeddedCurveAdd | BlackBoxFunc::EmbeddedCurveDouble => Some(2), + + // Big integer operations return a big integer + BlackBoxFunc::BigIntAdd + | BlackBoxFunc::BigIntNeg + | BlackBoxFunc::BigIntMul + | BlackBoxFunc::BigIntDiv + | BlackBoxFunc::BigIntFromLeBytes => Some(1), + + // ToLeBytes returns a variable array of bytes + BlackBoxFunc::BigIntToLeBytes => None, + // Recursive aggregation has a variable number of outputs BlackBoxFunc::RecursiveAggregation => None, } diff --git a/noir/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/noir/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index d1991abab37..ff9dc4f345e 100644 --- a/noir/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/noir/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -434,8 +434,13 @@ fn simplify_black_box_func( // Currently unsolvable here as we rely on an implementation in the backend. SimplifyResult::None } - - BlackBoxFunc::RecursiveAggregation => SimplifyResult::None, + BlackBoxFunc::BigIntAdd + | BlackBoxFunc::BigIntNeg + | BlackBoxFunc::BigIntMul + | BlackBoxFunc::BigIntDiv + | BlackBoxFunc::RecursiveAggregation + | BlackBoxFunc::BigIntFromLeBytes + | BlackBoxFunc::BigIntToLeBytes => SimplifyResult::None, BlackBoxFunc::AND => { unreachable!("ICE: `BlackBoxFunc::AND` calls should be transformed into a `BinaryOp`")