Skip to content

Commit

Permalink
chore: add unit test for BB big integer opcode implementation (#4177)
Browse files Browse the repository at this point in the history
The unit test is just creating big int constraints and should be updated
when the constraints are implemented.
  • Loading branch information
guipublic authored Jan 23, 2024
1 parent d7803df commit 50939d0
Show file tree
Hide file tree
Showing 11 changed files with 237 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ void build_constraints(Builder& builder, acir_format const& constraint_system, b
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 acir_format {
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 acir_format {
fixed_base_scalar_mul_constraints,
recursion_constraints,
constraints,
block_constraints);
block_constraints,
bigint_from_le_bytes_constraints,
bigint_operations);

friend bool operator==(acir_format const& lhs, acir_format 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,
};

acir_format 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 @@ -141,6 +141,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 @@ -186,6 +188,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 @@ -229,6 +233,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 @@ -267,6 +273,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

0 comments on commit 50939d0

Please sign in to comment.