12#include <gtest/gtest.h>
17template <
typename Builder_,
18 typename AcirConstraint_,
19 size_t num_multiplication_terms,
20 size_t num_linear_terms,
21 bool overlap_mul_and_linear,
33template <
typename Builder_,
34 typename AcirConstraint_,
35 size_t num_multiplication_terms,
36 size_t num_linear_terms,
37 bool overlap_mul_and_linear,
53 if constexpr (overlap_mul_and_linear) {
57 if constexpr (overlap_mul_and_linear && num_multiplication_terms > 1) {
61 if constexpr (overlap_mul_and_linear && num_multiplication_terms > 2) {
76 size_t num_multiplication_gates = num_multiplication_terms;
77 num_gates += num_multiplication_gates;
80 size_t num_witnesses_into_wires = num_linear_terms;
87 size_t num_witnesses_first_wire = num_multiplication_gates != 0 ? 2U : 4U;
88 if (num_witnesses_into_wires <= num_witnesses_first_wire) {
89 return num_multiplication_gates != 0 ? num_multiplication_gates : 1U;
91 num_witnesses_into_wires -= num_witnesses_first_wire;
92 num_gates += num_multiplication_gates != 0 ? 0U : 1U;
95 if (num_witnesses_into_wires + 1 <= num_gates) {
98 num_witnesses_into_wires -= (num_multiplication_gates - 1);
101 size_t num_additional_gates = num_witnesses_into_wires / (Builder::NUM_WIRES - 1);
102 size_t diff = num_witnesses_into_wires - num_additional_gates * (Builder::NUM_WIRES - 1);
103 num_additional_gates += diff == 0 ? 0U : 1U;
105 return num_gates + num_additional_gates;
115 static std::vector<std::string>
get_labels() {
return {
"None",
"InvalidateConstant",
"InvalidateWitness" }; }
121 const std::vector<bb::fr>& witness_values)
125 for (
const auto& mul_term : mul_terms) {
129 result += scalar * lhs_value * rhs_value;
132 for (
const auto& linear_term : linear_terms) {
133 bb::fr scalar = linear_term.first;
134 bb::fr value = witness_values[linear_term.second.first];
150 mul_terms.reserve(num_multiplication_terms);
151 for (
size_t idx = 0; idx < num_multiplication_terms; ++idx) {
162 linear_terms.reserve(num_linear_terms);
163 for (
size_t idx = 0; idx < num_linear_terms; ++idx) {
175 if constexpr (overlap_mul_and_linear) {
176 BB_ASSERT_GTE(num_linear_terms, 1U,
"We need at least 1 linear terms when overlapping is turned on.");
178 num_multiplication_terms, 1U,
"We need at least 1 multiplication terms when overlapping is turned on.");
181 std::get<1>(mul_terms[0]).first = linear_terms[0].second.first;
183 if constexpr (num_multiplication_terms > 1 && num_linear_terms > 1) {
185 std::get<2>(mul_terms[1]).first = linear_terms[1].second.first;
188 if constexpr (num_multiplication_terms > 2 && num_linear_terms > 2) {
190 std::get<1>(mul_terms[2]).first = linear_terms[2].second.first;
191 std::get<2>(mul_terms[2]).first = linear_terms[2].second.first;
197 if constexpr (overlap_linear) {
201 <<
" linear term when overlapping is turned on.");
211 for (
const auto& mul_term : mul_terms) {
216 for (
const auto& linear_term : linear_terms) {
218 std::make_tuple(linear_term.first.to_buffer(),
Acir::Witness(linear_term.second.first)));
230 if (EXPECTED_NUM_GATES > 1) {
251 switch (invalid_witness_target) {
274 return { constraint, witness_values };
278template <
typename ArithmeticConstra
intParams_>
280 :
public ::testing::Test,
281 public TestClass<ArithmeticConstraintsTestingFunctions<typename ArithmeticConstraintParams_::Builder,
282 typename ArithmeticConstraintParams_::AcirConstraint,
283 ArithmeticConstraintParams_::NUM_MULTIPLICATION_TERMS,
284 ArithmeticConstraintParams_::NUM_LINEAR_TERMS,
285 ArithmeticConstraintParams_::OVERLAP_MUL_AND_LINEAR,
286 ArithmeticConstraintParams_::OVERLAP_LINEAR>> {
319 TestFixture::template test_vk_independence<Flavor>();
324 TestFixture::test_tampering();
327template <
typename ArithmeticConstra
intParams_>
329 :
public ::testing::Test,
330 public TestClass<ArithmeticConstraintsTestingFunctions<typename ArithmeticConstraintParams_::Builder,
331 typename ArithmeticConstraintParams_::AcirConstraint,
332 ArithmeticConstraintParams_::NUM_MULTIPLICATION_TERMS,
333 ArithmeticConstraintParams_::NUM_LINEAR_TERMS,
334 ArithmeticConstraintParams_::OVERLAP_MUL_AND_LINEAR,
335 ArithmeticConstraintParams_::OVERLAP_LINEAR>> {
362 TestFixture::template test_vk_independence<Flavor>();
367 TestFixture::test_tampering();
372using BuilderTypes = testing::Types<UltraCircuitBuilder, MegaCircuitBuilder>;
382 BigQuadConstraintTest::generate_constraints(big_quad_constraint, witness_values);
385 AcirProgram program{ constraint_system, witness_values };
387 auto builder = create_circuit<TypeParam>(program, metadata);
389 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ BIG_QUAD<TypeParam> }));
392TEST(AssertZeroConstraintTest, UnsatisfiableCircuitWithNonZeroConstantOnly)
402 "circuit is unsatisfiable. An AssertZero opcode contains no variables but has a non-zero constant");
405TEST(AssertZeroConstraintTest, SatisfiableCircuitWithZeroConstantOnly)
415 "split_into_mul_quad_gates: resulted in zero gates");
430 static std::vector<std::string>
get_labels() {
return {
"None",
"InvalidateConstant",
"InvalidateWitness" }; }
437 std::vector<Acir::Opcode> opcodes;
443 for (
size_t i = 0; i < num_bilinear; ++i) {
444 const size_t num_linear = std::min(i,
size_t{ 4 });
456 bb::fr c = -(q_m *
a *
b + q_l *
a + q_r *
b + q_4 * d + q_c) * (q_5 *
a + q_o).
invert();
463 if (num_linear > 0) {
466 if (num_linear > 1) {
469 if (num_linear > 2) {
472 if (num_linear > 3) {
506 return { constraint, witness_values };
510template <
typename Params>
512 public TestClass<BilinearConstraintTestingFunctions<Params::value>> {
526 TestFixture::template test_vk_independence<MegaFlavor>();
531 TestFixture::test_tampering();
550 if constexpr (num_batched_eq == 1) {
562 if constexpr (num_batched_eq == 1) {
563 return {
"None",
"InvalidateConstantFirstHalf",
"InvalidateWitnessFirstHalf" };
566 "InvalidateConstantFirstHalf",
567 "InvalidateWitnessFirstHalf",
568 "InvalidateConstantSecondHalf",
569 "InvalidateWitnessSecondHalf" };
578 std::vector<Acir::Opcode> opcodes;
582 for (
size_t i = 0; i < num_batched_eq; ++i) {
583 const size_t num_witnesses =
std::max(
size_t{ 1 }, std::min(i,
size_t{ 2 }));
587 if (num_witnesses == 1) {
590 expr.
q_c = (-(c1 * w1)).to_buffer();
610 (num_batched_eq + 1) / 2,
611 "generate_constraints: expected ceil(N/2) batched-eq rows.");
639 return { constraint, witness_values };
643template <
typename Params>
645 public TestClass<BatchedEqCheckConstraintTestingFunctions<Params::value>> {
661 TestFixture::template test_vk_independence<MegaFlavor>();
666 TestFixture::test_tampering();
testing::Types< std::integral_constant< size_t, 1 >, std::integral_constant< size_t, 2 >, std::integral_constant< size_t, 3 >, std::integral_constant< size_t, 4 >, std::integral_constant< size_t, 5 >, std::integral_constant< size_t, 7 > > BatchedEqConfigs
testing::Types< ArithmeticConstraintParams< UltraCircuitBuilder, BigQuadConstraint, 1, 3, false, false >, ArithmeticConstraintParams< UltraCircuitBuilder, BigQuadConstraint, 0, 5, false, false >, ArithmeticConstraintParams< UltraCircuitBuilder, BigQuadConstraint, 2, 0, false, false >, ArithmeticConstraintParams< UltraCircuitBuilder, BigQuadConstraint, 3, 3, true, false >, ArithmeticConstraintParams< UltraCircuitBuilder, BigQuadConstraint, 1, 4, false, true >, ArithmeticConstraintParams< UltraCircuitBuilder, BigQuadConstraint, 5, 5, true, true >, ArithmeticConstraintParams< UltraCircuitBuilder, BigQuadConstraint, 0, 6, false, true >, ArithmeticConstraintParams< MegaCircuitBuilder, BigQuadConstraint, 1, 3, false, false >, ArithmeticConstraintParams< MegaCircuitBuilder, BigQuadConstraint, 0, 5, false, false >, ArithmeticConstraintParams< MegaCircuitBuilder, BigQuadConstraint, 2, 0, false, false >, ArithmeticConstraintParams< MegaCircuitBuilder, BigQuadConstraint, 3, 3, true, false >, ArithmeticConstraintParams< MegaCircuitBuilder, BigQuadConstraint, 1, 4, false, true >, ArithmeticConstraintParams< MegaCircuitBuilder, BigQuadConstraint, 5, 5, true, true >, ArithmeticConstraintParams< MegaCircuitBuilder, BigQuadConstraint, 0, 6, false, true > > BigQuadConstraintConfigs
testing::Types< ArithmeticConstraintParams< UltraCircuitBuilder, QuadConstraint, 1, 0, false, false >, ArithmeticConstraintParams< UltraCircuitBuilder, QuadConstraint, 1, 1, false, false >, ArithmeticConstraintParams< UltraCircuitBuilder, QuadConstraint, 1, 2, false, false >, ArithmeticConstraintParams< UltraCircuitBuilder, QuadConstraint, 1, 3, false, true >, ArithmeticConstraintParams< UltraCircuitBuilder, QuadConstraint, 1, 4, true, true >, ArithmeticConstraintParams< UltraCircuitBuilder, QuadConstraint, 0, 4, false, false >, ArithmeticConstraintParams< UltraCircuitBuilder, QuadConstraint, 0, 5, false, true >, ArithmeticConstraintParams< MegaCircuitBuilder, QuadConstraint, 1, 0, false, false >, ArithmeticConstraintParams< MegaCircuitBuilder, QuadConstraint, 1, 1, false, false >, ArithmeticConstraintParams< MegaCircuitBuilder, QuadConstraint, 1, 2, false, false >, ArithmeticConstraintParams< MegaCircuitBuilder, QuadConstraint, 1, 3, false, true >, ArithmeticConstraintParams< MegaCircuitBuilder, QuadConstraint, 1, 4, true, true >, ArithmeticConstraintParams< MegaCircuitBuilder, QuadConstraint, 0, 4, false, false >, ArithmeticConstraintParams< MegaCircuitBuilder, QuadConstraint, 0, 5, false, true > > QuadConstraintConfigs
testing::Types< std::integral_constant< size_t, 1 >, std::integral_constant< size_t, 2 >, std::integral_constant< size_t, 3 >, std::integral_constant< size_t, 5 > > BilinearConfigs
#define BB_ASSERT(expression,...)
#define BB_ASSERT_GTE(left, right,...)
#define BB_ASSERT_GT(left, right,...)
#define BB_ASSERT_EQ(actual, expected,...)
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
static constexpr size_t NUM_LINEAR_TERMS
static constexpr size_t NUM_MULTIPLICATION_TERMS
AcirConstraint_ AcirConstraint
static constexpr bool OVERLAP_MUL_AND_LINEAR
static constexpr bool OVERLAP_LINEAR
static std::vector< std::string > get_labels()
static std::vector< Target > get_all()
static void generate_constraints(AcirConstraint &arithmetic_constraint, WitnessVector &witness_values)
AcirConstraint_ AcirConstraint
static constexpr size_t NUM_OVERLAP_MUL_AND_LINEAR
static constexpr size_t LINEAR_OFFSET
static std::pair< AcirConstraint, WitnessVector > invalidate_witness(AcirConstraint constraint, WitnessVector witness_values, const typename InvalidWitness::Target &invalid_witness_target)
static bb::fr evaluate_expression_result(const std::vector< std::tuple< bb::fr, std::pair< uint32_t, bb::fr >, std::pair< uint32_t, bb::fr > > > &mul_terms, const std::vector< std::pair< bb::fr, std::pair< uint32_t, bb::fr > > > &linear_terms, const std::vector< bb::fr > &witness_values)
static constexpr size_t num_overlap_mul_and_linear()
Compute the number of elements to overlap between multiplication and linear terms.
static constexpr size_t NUM_OVERLAP_LINEAR
static ProgramMetadata generate_metadata()
static size_t expected_num_gates()
static constexpr bool IS_BIG_QUAD
static void SetUpTestSuite()
static std::vector< std::string > get_labels()
@ InvalidateConstantFirstHalf
@ InvalidateWitnessFirstHalf
@ InvalidateConstantSecondHalf
@ InvalidateWitnessSecondHalf
static std::vector< Target > get_all()
static ProgramMetadata generate_metadata()
std::vector< BatchedEqCheckConstraint > AcirConstraint
static void generate_constraints(AcirConstraint &constraint, WitnessVector &witness_values)
static std::pair< AcirConstraint, WitnessVector > invalidate_witness(AcirConstraint constraint, WitnessVector witness_values, const typename InvalidWitness::Target &target)
static void SetUpTestSuite()
static void SetUpTestSuite()
static std::vector< Target > get_all()
static std::vector< std::string > get_labels()
std::vector< BilinearConstraint > AcirConstraint
static ProgramMetadata generate_metadata()
static void generate_constraints(AcirConstraint &constraint, WitnessVector &witness_values)
static std::pair< AcirConstraint, WitnessVector > invalidate_witness(AcirConstraint constraint, WitnessVector witness_values, const typename InvalidWitness::Target &target)
static void SetUpTestSuite()
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
MegaCircuitBuilder_< field< Bn254FrParams > > MegaCircuitBuilder
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::vector< Instruction > target
::testing::Types< UltraCircuitBuilder, MegaCircuitBuilder > BuilderTypes
std::vector< uint8_t > to_buffer(T const &value)
std::vector< std::tuple< std::vector< uint8_t >, Acir::Witness > > linear_combinations
std::vector< uint8_t > q_c
std::vector< std::tuple< std::vector< uint8_t >, Acir::Witness, Acir::Witness > > mul_terms
std::variant< AssertZero, BlackBoxFuncCall, MemoryOp, MemoryInit, BrilligCall, Call > value
static constexpr field one()
constexpr field invert() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
BB_INLINE std::vector< uint8_t > to_buffer() const
static constexpr field zero()