Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Add big int opcodes (without implementation) #4050

Merged
merged 10 commits into from
Jan 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -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<Builder>) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -41,6 +42,8 @@ struct AcirFormat {
std::vector<EcAdd> ec_add_constraints;
std::vector<EcDouble> ec_double_constraints;
std::vector<RecursionConstraint> recursion_constraints;
std::vector<BigIntFromLeBytes> bigint_from_le_bytes_constraints;
std::vector<BigIntOperation> 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
Expand Down Expand Up @@ -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;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {},
};
Expand Down Expand Up @@ -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 = {} };

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 = {},
};
Expand Down Expand Up @@ -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 = {} };

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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<T, Circuit::BlackBoxFuncCall::BigIntFromLeBytes>) {
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<T, Circuit::BlackBoxFuncCall::BigIntAdd>) {
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<T, Circuit::BlackBoxFuncCall::BigIntNeg>) {
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<T, Circuit::BlackBoxFuncCall::BigIntMul>) {
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<T, Circuit::BlackBoxFuncCall::BigIntDiv>) {
af.bigint_operations.push_back(BigIntOperation{
.lhs = arg.lhs,
.rhs = arg.rhs,
.result = arg.output,
.opcode = BigIntOperationType::Div,
});
}
},
arg.value.value);
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <typename Builder> void create_bigint_operations_constraint(Builder& builder, const BigIntOperation& input)
{
// TODO
(void)builder;
info(input);
}

template void create_bigint_operations_constraint<UltraCircuitBuilder>(UltraCircuitBuilder& builder,
const BigIntOperation& input);
template void create_bigint_operations_constraint<GoblinUltraCircuitBuilder>(GoblinUltraCircuitBuilder& builder,
const BigIntOperation& input);

template <typename Builder>
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>(UltraCircuitBuilder& builder,
const BigIntFromLeBytes& input);
template void create_bigint_from_le_bytes_constraint<GoblinUltraCircuitBuilder>(GoblinUltraCircuitBuilder& builder,
const BigIntFromLeBytes& input);

} // namespace acir_format
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once
#include "barretenberg/dsl/types.hpp"
#include "barretenberg/serialize/msgpack.hpp"
#include <cstdint>
#include <vector>

namespace acir_format {

struct BigIntFromLeBytes {
std::vector<uint32_t> inputs;
std::vector<uint32_t> 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 <typename Builder> void create_bigint_operations_constraint(Builder& builder, const BigIntOperation& input);
template <typename Builder>
void create_bigint_from_le_bytes_constraint(Builder& builder, const BigIntFromLeBytes& input);
} // namespace acir_format
Original file line number Diff line number Diff line change
@@ -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 <gtest/gtest.h>
#include <vector>

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
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {},
};
Expand Down Expand Up @@ -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 = {},
};
Expand Down Expand Up @@ -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 = {},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {},
};
Expand Down Expand Up @@ -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 = {},
};
Expand Down Expand Up @@ -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 = {},
};
Expand Down Expand Up @@ -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 = {},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {} };

Expand Down Expand Up @@ -252,6 +254,8 @@ Builder create_outer_circuit(std::vector<Builder>& inner_circuits)
.ec_add_constraints = {},
.ec_double_constraints = {},
.recursion_constraints = recursion_constraints,
.bigint_from_le_bytes_constraints = {},
.bigint_operations = {},
.constraints = {},
.block_constraints = {} };

Expand Down
Loading