Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,33 @@ void build_constraints(Builder& builder,
gate_counter.track_diff(constraint_system.gates_per_opcode,
constraint_system.original_opcode_indices.quad_constraints.at(i));
}
// Oversize gates are a vector of mul_quad gates.
for (size_t i = 0; i < constraint_system.big_quad_constraints.size(); ++i) {
auto& big_constraint = constraint_system.big_quad_constraints.at(i);
fr next_w4_wire_value = fr(0);
// Define the 4th wire of these mul_quad gates, which is implicitly used by the previous gate.
for (size_t j = 0; j < big_constraint.size() - 1; ++j) {
if (j == 0) {
next_w4_wire_value = builder.get_variable(big_constraint[0].d);
} else {
uint32_t next_w4_wire = builder.add_variable(next_w4_wire_value);
big_constraint[j].d = next_w4_wire;
big_constraint[j].d_scaling = fr(-1);
}
builder.create_big_mul_add_gate(big_constraint[j], true);
next_w4_wire_value = builder.get_variable(big_constraint[j].a) * builder.get_variable(big_constraint[j].b) *
big_constraint[j].mul_scaling +
builder.get_variable(big_constraint[j].a) * big_constraint[j].a_scaling +
builder.get_variable(big_constraint[j].b) * big_constraint[j].b_scaling +
builder.get_variable(big_constraint[j].c) * big_constraint[j].c_scaling +
next_w4_wire_value * big_constraint[j].d_scaling + big_constraint[j].const_scaling;
next_w4_wire_value = -next_w4_wire_value;
}
uint32_t next_w4_wire = builder.add_variable(next_w4_wire_value);
big_constraint.back().d = next_w4_wire;
big_constraint.back().d_scaling = fr(-1);
builder.create_big_mul_add_gate(big_constraint.back(), false);
}

// Add logic constraint
for (size_t i = 0; i < constraint_system.logic_constraints.size(); ++i) {
Expand Down Expand Up @@ -492,12 +519,14 @@ MegaCircuitBuilder create_kernel_circuit(AcirFormat& constraint_system,
for (auto [constraint, queue_entry] :
zip_view(constraint_system.ivc_recursion_constraints, ivc.stdlib_verification_queue)) {

// Reconstruct complete proof indices from acir constraint data (in which proof is stripped of public inputs)
// Reconstruct complete proof indices from acir constraint data (in which proof is
// stripped of public inputs)
std::vector<uint32_t> complete_proof_indices =
ProofSurgeon::create_indices_for_reconstructed_proof(constraint.proof, constraint.public_inputs);
ASSERT(complete_proof_indices.size() == queue_entry.proof.size());

// Assert equality between the proof indices from the constraint data and those of the internal proof
// Assert equality between the proof indices from the constraint data and those of the
// internal proof
for (auto [proof_value, proof_idx] : zip_view(queue_entry.proof, complete_proof_indices)) {
circuit.assert_equal(proof_value.get_witness_index(), proof_idx);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ struct AcirFormat {
// This could be a large vector so use slab allocator, we don't expect the blackbox implementations to be so large.
bb::SlabVector<PolyTripleConstraint> poly_triple_constraints;
bb::SlabVector<bb::mul_quad_<bb::curve::BN254::ScalarField>> quad_constraints;
Comment thread
guipublic marked this conversation as resolved.
bb::SlabVector<std::vector<bb::mul_quad_<bb::curve::BN254::ScalarField>>> big_quad_constraints;
std::vector<BlockConstraint> block_constraints;

// Number of gates added to the circuit per original opcode.
Expand Down Expand Up @@ -153,6 +154,8 @@ struct AcirFormat {
avm_recursion_constraints,
ivc_recursion_constraints,
poly_triple_constraints,
quad_constraints,
big_quad_constraints,
block_constraints,
bigint_from_le_bytes_constraints,
bigint_to_le_bytes_constraints,
Expand Down
142 changes: 142 additions & 0 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ TEST_F(AcirFormatTests, TestASingleConstraintNoPubInputs)
.assert_equalities = {},
.poly_triple_constraints = { constraint },
.quad_constraints = {},
.big_quad_constraints = {},
.block_constraints = {},
.original_opcode_indices = create_empty_original_opcode_indices(),
};
Expand Down Expand Up @@ -191,6 +192,7 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit)
.assert_equalities = {},
.poly_triple_constraints = { expr_a, expr_b, expr_c, expr_d },
.quad_constraints = {},
.big_quad_constraints = {},
.block_constraints = {},
.original_opcode_indices = create_empty_original_opcode_indices(),
};
Expand Down Expand Up @@ -282,6 +284,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass)
.q_c = fr::neg_one(),
} },
.quad_constraints = {},
.big_quad_constraints = {},
.block_constraints = {},
.original_opcode_indices = create_empty_original_opcode_indices(),
};
Expand Down Expand Up @@ -390,6 +393,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange)
.q_c = fr::neg_one(),
} },
.quad_constraints = {},
.big_quad_constraints = {},
.block_constraints = {},
.original_opcode_indices = create_empty_original_opcode_indices(),
};
Expand Down Expand Up @@ -502,6 +506,7 @@ TEST_F(AcirFormatTests, TestVarKeccak)
.assert_equalities = {},
.poly_triple_constraints = { dummy },
.quad_constraints = {},
.big_quad_constraints = {},
.block_constraints = {},
.original_opcode_indices = create_empty_original_opcode_indices(),
};
Expand Down Expand Up @@ -583,6 +588,7 @@ TEST_F(AcirFormatTests, TestKeccakPermutation)
.assert_equalities = {},
.poly_triple_constraints = {},
.quad_constraints = {},
.big_quad_constraints = {},
.block_constraints = {},
.original_opcode_indices = create_empty_original_opcode_indices(),
};
Expand Down Expand Up @@ -659,6 +665,7 @@ TEST_F(AcirFormatTests, TestCollectsGateCounts)
.assert_equalities = {},
.poly_triple_constraints = { first_gate, second_gate },
.quad_constraints = {},
.big_quad_constraints = {},
.block_constraints = {},
.original_opcode_indices = create_empty_original_opcode_indices(),
};
Expand All @@ -669,3 +676,138 @@ TEST_F(AcirFormatTests, TestCollectsGateCounts)

EXPECT_EQ(constraint_system.gates_per_opcode, std::vector<size_t>({ 2, 1 }));
}

TEST_F(AcirFormatTests, TestBigAdd)
{

WitnessVector witness_values;
witness_values.emplace_back(fr(0));

witness_values = {
fr(0), fr(1), fr(2), fr(3), fr(4), fr(5), fr(6), fr(7), fr(8), fr(9), fr(10), fr(11), fr(12), fr(13), fr(-91),
};

bb::mul_quad_<fr> quad1 = {
.a = 0,
.b = 1,
.c = 2,
.d = 3,
.mul_scaling = 0,
.a_scaling = fr::one(),
.b_scaling = fr::one(),
.c_scaling = fr::one(),
.d_scaling = fr::one(),
.const_scaling = fr(0),
};

bb::mul_quad_<fr> quad2 = {
.a = 4,
.b = 5,
.c = 6,
.d = 0,
.mul_scaling = 0,
.a_scaling = fr::one(),
.b_scaling = fr::one(),
.c_scaling = fr::one(),
.d_scaling = fr(0),
.const_scaling = fr(0),
};

bb::mul_quad_<fr> quad3 = {
.a = 7,
.b = 8,
.c = 9,
.d = 0,
.mul_scaling = 0,
.a_scaling = fr::one(),
.b_scaling = fr::one(),
.c_scaling = fr::one(),
.d_scaling = fr(0),
.const_scaling = fr(0),
};
bb::mul_quad_<fr> quad4 = {
.a = 10,
.b = 11,
.c = 12,
.d = 0,
.mul_scaling = 0,
.a_scaling = fr::one(),
.b_scaling = fr::one(),
.c_scaling = fr::one(),
.d_scaling = fr(0),
.const_scaling = fr(0),
};
bb::mul_quad_<fr> quad5 = {
.a = 13,
.b = 14,
.c = 0,
.d = 18,
.mul_scaling = 0,
.a_scaling = fr::one(),
.b_scaling = fr::one(),
.c_scaling = fr(0),
.d_scaling = fr(-1),
.const_scaling = fr(0),
};

auto res_x = fr(91);
auto assert_equal = poly_triple{
.a = 14,
.b = 0,
.c = 0,
.q_m = 0,
.q_l = fr::one(),
.q_r = 0,
.q_o = 0,
.q_c = res_x,
};
auto quad_constraint = { quad1, quad2, quad3, quad4, quad5 };
size_t num_variables = witness_values.size();
AcirFormat constraint_system{
.varnum = static_cast<uint32_t>(num_variables + 1),
.recursive = false,
.num_acir_opcodes = 1,
.public_inputs = {},
.logic_constraints = {},
.range_constraints = {},
.aes128_constraints = {},
.sha256_compression = {},
.schnorr_constraints = {},
.ecdsa_k1_constraints = {},
.ecdsa_r1_constraints = {},
.blake2s_constraints = {},
.blake3_constraints = {},
.keccak_constraints = {},
.keccak_permutations = {},
.pedersen_constraints = {},
.pedersen_hash_constraints = {},
.poseidon2_constraints = {},
.multi_scalar_mul_constraints = {},
.ec_add_constraints = {},
.recursion_constraints = {},
.honk_recursion_constraints = {},
.avm_recursion_constraints = {},
.ivc_recursion_constraints = {},
.bigint_from_le_bytes_constraints = {},
.bigint_to_le_bytes_constraints = {},
.bigint_operations = {},
.assert_equalities = {},
.poly_triple_constraints = { assert_equal },
.quad_constraints = {},
.big_quad_constraints = { quad_constraint },
.block_constraints = {},
.original_opcode_indices = create_empty_original_opcode_indices(),
};
mock_opcode_indices(constraint_system);

auto builder = create_circuit(constraint_system, /*size_hint*/ 0, witness_values);

auto composer = Composer();
auto prover = composer.create_prover(builder);

auto proof = prover.construct_proof();

EXPECT_TRUE(CircuitChecker::check(builder));
auto verifier = composer.create_verifier(builder);
EXPECT_EQ(verifier.verify_proof(proof), true);
}
Loading