Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
arithmetic_constraints.test.cpp
Go to the documentation of this file.
2#include "acir_format.hpp"
3
9
10#include <algorithm>
11#include <cstdint>
12#include <gtest/gtest.h>
13#include <vector>
14
15using namespace acir_format;
16
17template <typename Builder_,
18 typename AcirConstraint_,
19 size_t num_multiplication_terms,
20 size_t num_linear_terms,
21 bool overlap_mul_and_linear,
22 bool overlap_linear>
24 public:
25 using Builder = Builder_;
26 using AcirConstraint = AcirConstraint_;
27 static constexpr size_t NUM_MULTIPLICATION_TERMS = num_multiplication_terms;
28 static constexpr size_t NUM_LINEAR_TERMS = num_linear_terms;
29 static constexpr bool OVERLAP_MUL_AND_LINEAR = overlap_mul_and_linear;
30 static constexpr bool OVERLAP_LINEAR = overlap_linear;
31};
32
33template <typename Builder_,
34 typename AcirConstraint_,
35 size_t num_multiplication_terms,
36 size_t num_linear_terms,
37 bool overlap_mul_and_linear,
38 bool overlap_linear>
40 public:
41 using Builder = Builder_;
42 using AcirConstraint = AcirConstraint_;
43
45
49 static constexpr size_t num_overlap_mul_and_linear()
50 {
51 size_t result = 0;
52
53 if constexpr (overlap_mul_and_linear) {
54 result++;
55 }
56
57 if constexpr (overlap_mul_and_linear && num_multiplication_terms > 1) {
58 result++;
59 }
60
61 if constexpr (overlap_mul_and_linear && num_multiplication_terms > 2) {
62 result++;
63 }
64
65 return result;
66 }
67
69 static constexpr size_t NUM_OVERLAP_LINEAR = 1;
70 static constexpr size_t LINEAR_OFFSET = overlap_mul_and_linear ? NUM_OVERLAP_MUL_AND_LINEAR : 0U;
71
72 static size_t expected_num_gates()
73 {
74 size_t num_gates = 0;
75
76 size_t num_multiplication_gates = num_multiplication_terms;
77 num_gates += num_multiplication_gates;
78
79 // Compute the number of witnesses that have to be put into wires on top of the multiplication terms
80 size_t num_witnesses_into_wires = num_linear_terms;
81 num_witnesses_into_wires -= overlap_mul_and_linear ? NUM_OVERLAP_MUL_AND_LINEAR : 0U;
82 num_witnesses_into_wires -= overlap_linear ? NUM_OVERLAP_LINEAR : 0U;
83
84 // Update the number of required gates
85
86 // The first gate uses all wires, so we fit two new witnesses when there are multiplication terms, 4 otherwise
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;
90 }
91 num_witnesses_into_wires -= num_witnesses_first_wire;
92 num_gates += num_multiplication_gates != 0 ? 0U : 1U;
93
94 // All other gates don't use the last wire, so we fit one new witness per gate
95 if (num_witnesses_into_wires + 1 <= num_gates) {
96 return num_gates;
97 }
98 num_witnesses_into_wires -= (num_multiplication_gates - 1);
99
100 // Now we add the remaining witnesses
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;
104
105 return num_gates + num_additional_gates;
106 }
107
109 public:
115 static std::vector<std::string> get_labels() { return { "None", "InvalidateConstant", "InvalidateWitness" }; }
116 };
117
119 const std::vector<std::tuple<bb::fr, std::pair<uint32_t, bb::fr>, std::pair<uint32_t, bb::fr>>>& mul_terms,
120 const std::vector<std::pair<bb::fr, std::pair<uint32_t, bb::fr>>>& linear_terms,
121 const std::vector<bb::fr>& witness_values)
122 {
123 bb::fr result = 0;
124
125 for (const auto& mul_term : mul_terms) {
126 bb::fr scalar = std::get<0>(mul_term);
127 bb::fr lhs_value = witness_values[std::get<1>(mul_term).first];
128 bb::fr rhs_value = witness_values[std::get<2>(mul_term).first];
129 result += scalar * lhs_value * rhs_value;
130 }
131
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];
135 result += scalar * value;
136 }
137
138 return result;
139 }
140
142
143 static void generate_constraints(AcirConstraint& arithmetic_constraint, WitnessVector& witness_values)
144 {
145 // (scalar, (lhs_index, lhs_value), (rhs_index, rhs_value))
147 // (scalar, (index, value)
149
150 mul_terms.reserve(num_multiplication_terms);
151 for (size_t idx = 0; idx < num_multiplication_terms; ++idx) {
152 bb::fr lhs_value = bb::fr::random_element();
153 bb::fr rhs_value = bb::fr::random_element();
155
156 uint32_t lhs_index = add_to_witness_and_track_indices(witness_values, lhs_value);
157 uint32_t rhs_index = add_to_witness_and_track_indices(witness_values, rhs_value);
158 mul_terms.push_back(
159 std::make_tuple(scalar, std::make_pair(lhs_index, lhs_value), std::make_pair(rhs_index, rhs_value)));
160 }
161
162 linear_terms.reserve(num_linear_terms);
163 for (size_t idx = 0; idx < num_linear_terms; ++idx) {
166
167 uint32_t index = add_to_witness_and_track_indices(witness_values, value);
168 linear_terms.push_back(std::make_pair(scalar, std::make_pair(index, value)));
169 }
170
171 // Expressions that would lead to these cases are:
172 // 1. w1 * w2 + w1
173 // 2. w1 * w2 + w3 * w4 + w1 + w4
174 // 3. w1 * w1 + w3 * w4 + w5 * w5 + w1 + w4 + w5
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.");
179
180 // Overlap lhs of multiplication term with linear term
181 std::get<1>(mul_terms[0]).first = linear_terms[0].second.first;
182
183 if constexpr (num_multiplication_terms > 1 && num_linear_terms > 1) {
184 // Overlap rhs of multiplication term with linear term
185 std::get<2>(mul_terms[1]).first = linear_terms[1].second.first;
186 }
187
188 if constexpr (num_multiplication_terms > 2 && num_linear_terms > 2) {
189 // Overlap both terms in the multiplication term with linear term
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;
192 }
193 }
194
195 // Expression that would lead to this case is:
196 // w1 + w1
197 if constexpr (overlap_linear) {
198 BB_ASSERT_GT(num_linear_terms,
200 "We need at least " << NUM_OVERLAP_LINEAR + LINEAR_OFFSET + 1
201 << " linear term when overlapping is turned on.");
202
203 // Overlap two linear terms
204 linear_terms[LINEAR_OFFSET].second.first = linear_terms[LINEAR_OFFSET + 1].second.first;
205 }
206
207 bb::fr result = -evaluate_expression_result(mul_terms, linear_terms, witness_values);
208
209 // Build the Acir::Expression
210 Acir::Expression expression;
211 for (const auto& mul_term : mul_terms) {
212 expression.mul_terms.push_back(std::make_tuple(std::get<0>(mul_term).to_buffer(),
213 Acir::Witness(std::get<1>(mul_term).first),
214 Acir::Witness(std::get<2>(mul_term).first)));
215 }
216 for (const auto& linear_term : linear_terms) {
217 expression.linear_combinations.push_back(
218 std::make_tuple(linear_term.first.to_buffer(), Acir::Witness(linear_term.second.first)));
219 }
220 expression.q_c = result.to_buffer();
221
222 // Construct the big quad constraint via the standard arithmetic path (is_mega = false).
223 Acir::Opcode::AssertZero acir_assert_zero{ .value = expression };
224 AcirFormat dummy_acir_format;
225 std::vector<BatchedEqEntry> batched_eq_assert_zeros;
226 assert_zero_to_constraints(acir_assert_zero, dummy_acir_format, 0, batched_eq_assert_zeros, /*is_mega=*/false);
227
228 // Check that the construction worked as expected
229 size_t EXPECTED_NUM_GATES = expected_num_gates();
230 if (EXPECTED_NUM_GATES > 1) {
231 BB_ASSERT(dummy_acir_format.quad_constraints.empty());
232 BB_ASSERT_EQ(dummy_acir_format.big_quad_constraints.size(), 1U);
233 BB_ASSERT_EQ(dummy_acir_format.big_quad_constraints[0].size(), EXPECTED_NUM_GATES);
234 } else {
235 BB_ASSERT(dummy_acir_format.big_quad_constraints.empty());
236 BB_ASSERT_EQ(dummy_acir_format.quad_constraints.size(), 1U);
237 }
238
239 if constexpr (IS_BIG_QUAD) {
240 arithmetic_constraint = dummy_acir_format.big_quad_constraints[0];
241 } else {
242 arithmetic_constraint = dummy_acir_format.quad_constraints[0];
243 }
244 }
245
247 AcirConstraint constraint,
248 WitnessVector witness_values,
249 const typename InvalidWitness::Target& invalid_witness_target)
250 {
251 switch (invalid_witness_target) {
253 break;
255 // Invalidate the equation by changing the constant term
256 if constexpr (IS_BIG_QUAD) {
257 constraint[0].const_scaling += bb::fr::one();
258 } else {
259 constraint.const_scaling += bb::fr::one();
260 }
261 break;
262 }
264 // Invalidate the equation by changing one of the witness values
265 if constexpr (IS_BIG_QUAD) {
266 witness_values[constraint[0].a] += bb::fr::one();
267 } else {
268 witness_values[constraint.a] += bb::fr::one();
269 }
270 break;
271 }
272 };
273
274 return { constraint, witness_values };
275 };
276};
277
278template <typename ArithmeticConstraintParams_>
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>> {
287 protected:
289};
290
291using BigQuadConstraintConfigs = testing::Types<
293 // requiring 2 gates
298 // requiring 2 gates
301 // requiring 2 gates
303 // requiring 2 gates
308 // requiring 2 gates
311 // requiring 2 gates
312
314
315TYPED_TEST(BigQuadConstraintTest, GenerateVKFromConstraints)
316{
317 using Flavor =
319 TestFixture::template test_vk_independence<Flavor>();
320}
321
323{
324 TestFixture::test_tampering();
325}
326
327template <typename ArithmeticConstraintParams_>
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>> {
336 protected:
338};
339
340using QuadConstraintConfigs = testing::Types<
355
357
358TYPED_TEST(QuadConstraintTest, GenerateVKFromConstraints)
359{
360 using Flavor =
362 TestFixture::template test_vk_independence<Flavor>();
363}
364
366{
367 TestFixture::test_tampering();
368}
369
370template <typename Builder> class BigQuadOpcodeGateCountTest : public ::testing::Test {};
371
372using BuilderTypes = testing::Types<UltraCircuitBuilder, MegaCircuitBuilder>;
374
376{
379
380 BigQuadConstraint big_quad_constraint;
381 WitnessVector witness_values;
382 BigQuadConstraintTest::generate_constraints(big_quad_constraint, witness_values);
383
384 AcirFormat constraint_system = constraint_to_acir_format(big_quad_constraint);
385 AcirProgram program{ constraint_system, witness_values };
386 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
387 auto builder = create_circuit<TypeParam>(program, metadata);
388
389 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ BIG_QUAD<TypeParam> }));
390}
391
392TEST(AssertZeroConstraintTest, UnsatisfiableCircuitWithNonZeroConstantOnly)
393{
394 // An AssertZero opcode with no variables and a non-zero constant is fundamentally unsatisfiable:
395 // it asserts `nonzero_constant == 0` which can never hold.
397 Acir::Opcode::AssertZero assert_zero{ .value = expr };
398 AcirFormat af;
399 std::vector<BatchedEqEntry> batched_eq_assert_zeros;
401 assert_zero_to_constraints(assert_zero, af, 0, batched_eq_assert_zeros, /*is_mega=*/false),
402 "circuit is unsatisfiable. An AssertZero opcode contains no variables but has a non-zero constant");
403}
404
405TEST(AssertZeroConstraintTest, SatisfiableCircuitWithZeroConstantOnly)
406{
407 // An AssertZero opcode with no variables and a zero constant is trivially satisfiable (0 == 0),
408 // but should still be rejected since it produces a zero gate.
410 Acir::Opcode::AssertZero assert_zero{ .value = expr };
411 AcirFormat af;
412 std::vector<BatchedEqEntry> batched_eq_assert_zeros;
414 assert_zero_to_constraints(assert_zero, af, 0, batched_eq_assert_zeros, /*is_mega=*/false),
415 "split_into_mul_quad_gates: resulted in zero gates");
416}
417
418template <size_t num_bilinear> class BilinearConstraintTestingFunctions {
419 public:
422
424 public:
430 static std::vector<std::string> get_labels() { return { "None", "InvalidateConstant", "InvalidateWitness" }; }
431 };
432
434
435 static void generate_constraints(AcirConstraint& constraint, WitnessVector& witness_values)
436 {
437 std::vector<Acir::Opcode> opcodes;
438
439 // M bilinear gates whose two products share wire a:
440 // q_m·a·b + q_5·a·c + q_l·a + q_r·b + q_o·c + q_4·e + q_c = 0
441 // Wires a, b, c carry the products; d is the linear-only fourth wire. The i-th gate carries min(i, 4) linear
442 // terms (placed on a, b, c, d in turn) and we solve for c so the identity holds.
443 for (size_t i = 0; i < num_bilinear; ++i) {
444 const size_t num_linear = std::min(i, size_t{ 4 });
447 bb::fr q_l = num_linear > 0 ? bb::fr::random_element() : bb::fr::zero();
448 bb::fr q_r = num_linear > 1 ? bb::fr::random_element() : bb::fr::zero();
449 bb::fr q_o = num_linear > 2 ? bb::fr::random_element() : bb::fr::zero();
450 bb::fr q_4 = num_linear > 3 ? bb::fr::random_element() : bb::fr::zero();
454 bb::fr d = bb::fr::random_element(); // linear-only fourth wire (used only when num_linear > 3)
455 // c·(q_5·a + q_o) = −(q_m·a·b + q_l·a + q_r·b + q_4·e + q_c)
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();
457 uint32_t ai = add_to_witness_and_track_indices(witness_values, a);
458 uint32_t bi = add_to_witness_and_track_indices(witness_values, b);
459 uint32_t ci = add_to_witness_and_track_indices(witness_values, c);
460 Acir::Expression expr;
461 expr.mul_terms.push_back(std::make_tuple(q_m.to_buffer(), Acir::Witness(ai), Acir::Witness(bi)));
462 expr.mul_terms.push_back(std::make_tuple(q_5.to_buffer(), Acir::Witness(ai), Acir::Witness(ci)));
463 if (num_linear > 0) {
464 expr.linear_combinations.push_back(std::make_tuple(q_l.to_buffer(), Acir::Witness(ai)));
465 }
466 if (num_linear > 1) {
467 expr.linear_combinations.push_back(std::make_tuple(q_r.to_buffer(), Acir::Witness(bi)));
468 }
469 if (num_linear > 2) {
470 expr.linear_combinations.push_back(std::make_tuple(q_o.to_buffer(), Acir::Witness(ci)));
471 }
472 if (num_linear > 3) {
473 uint32_t di = add_to_witness_and_track_indices(witness_values, d);
474 expr.linear_combinations.push_back(std::make_tuple(q_4.to_buffer(), Acir::Witness(di)));
475 }
476 expr.q_c = q_c.to_buffer();
477 opcodes.push_back(Acir::Opcode{ .value = Acir::Opcode::AssertZero{ .value = expr } });
478 }
479
480 Acir::Circuit circuit = build_acir_circuit(opcodes);
481 AcirFormat af = circuit_serde_to_acir_format(circuit, /*is_mega=*/true);
482
483 // M shared-wire two-product AssertZeros classify to M BILINEAR rows; nothing else is produced.
484 BB_ASSERT_EQ(af.bilinear_constraints.size(), num_bilinear, "generate_constraints: expected M bilinear rows.");
486 BB_ASSERT(af.quad_constraints.empty());
488
489 constraint = af.bilinear_constraints;
490 }
491
493 WitnessVector witness_values,
494 const typename InvalidWitness::Target& target)
495 {
496 switch (target) {
498 break;
500 constraint[0].q_c += bb::fr::one();
501 break;
503 witness_values[constraint[0].a] += bb::fr::one();
504 break;
505 }
506 return { constraint, witness_values };
507 }
508};
509
510template <typename Params>
511class BilinearConstraintTest : public ::testing::Test,
512 public TestClass<BilinearConstraintTestingFunctions<Params::value>> {
513 protected:
515};
516
517using BilinearConfigs = testing::Types<std::integral_constant<size_t, 1>,
521
523
524TYPED_TEST(BilinearConstraintTest, GenerateVKFromConstraints)
525{
526 TestFixture::template test_vk_independence<MegaFlavor>();
527}
528
530{
531 TestFixture::test_tampering();
532}
533
534template <size_t num_batched_eq> class BatchedEqCheckConstraintTestingFunctions {
535 public:
538
540 public:
560 static std::vector<std::string> get_labels()
561 {
562 if constexpr (num_batched_eq == 1) {
563 return { "None", "InvalidateConstantFirstHalf", "InvalidateWitnessFirstHalf" };
564 } else {
565 return { "None",
566 "InvalidateConstantFirstHalf",
567 "InvalidateWitnessFirstHalf",
568 "InvalidateConstantSecondHalf",
569 "InvalidateWitnessSecondHalf" };
570 }
571 }
572 };
573
575
576 static void generate_constraints(AcirConstraint& constraint, WitnessVector& witness_values)
577 {
578 std::vector<Acir::Opcode> opcodes;
579
580 // N linear "equality" AssertZeros. The i-th equality uses min(i, 2) witnesses, floored at 1 (a
581 // batched-eq needs at least one witness)
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 }));
586 Acir::Expression expr;
587 if (num_witnesses == 1) {
588 uint32_t w1i = add_to_witness_and_track_indices(witness_values, w1);
589 expr.linear_combinations.push_back(std::make_tuple(c1.to_buffer(), Acir::Witness(w1i)));
590 expr.q_c = (-(c1 * w1)).to_buffer();
591 } else {
594 // c2·w2 = −(c1·w1 + q_c)
595 bb::fr w2 = -(c1 * w1 + q_c) * c2.invert();
596 uint32_t w1i = add_to_witness_and_track_indices(witness_values, w1);
597 uint32_t w2i = add_to_witness_and_track_indices(witness_values, w2);
598 expr.linear_combinations.push_back(std::make_tuple(c1.to_buffer(), Acir::Witness(w1i)));
599 expr.linear_combinations.push_back(std::make_tuple(c2.to_buffer(), Acir::Witness(w2i)));
600 expr.q_c = q_c.to_buffer();
601 }
602 opcodes.push_back(Acir::Opcode{ .value = Acir::Opcode::AssertZero{ .value = expr } });
603 }
604
605 Acir::Circuit circuit = build_acir_circuit(opcodes);
606 AcirFormat af = circuit_serde_to_acir_format(circuit, /*is_mega=*/true);
607
608 // N linear AssertZeros pair greedily into ceil(N/2) BATCHED_EQ rows; nothing else is produced.
610 (num_batched_eq + 1) / 2,
611 "generate_constraints: expected ceil(N/2) batched-eq rows.");
613 BB_ASSERT(af.quad_constraints.empty());
615
616 constraint = af.batched_eq_check_constraints;
617 }
618
620 WitnessVector witness_values,
621 const typename InvalidWitness::Target& target)
622 {
623 switch (target) {
625 break;
627 constraint[0].q_c += bb::fr::one();
628 break;
630 witness_values[constraint[0].a] += bb::fr::one();
631 break;
633 constraint[0].q_m += bb::fr::one();
634 break;
636 witness_values[constraint[0].c] += bb::fr::one();
637 break;
638 }
639 return { constraint, witness_values };
640 }
641};
642
643template <typename Params>
644class BatchedEqCheckConstraintTest : public ::testing::Test,
645 public TestClass<BatchedEqCheckConstraintTestingFunctions<Params::value>> {
646 protected:
648};
649
650using BatchedEqConfigs = testing::Types<std::integral_constant<size_t, 1>,
656
658
659TYPED_TEST(BatchedEqCheckConstraintTest, GenerateVKFromConstraints)
660{
661 TestFixture::template test_vk_independence<MegaFlavor>();
662}
663
665{
666 TestFixture::test_tampering();
667}
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,...)
Definition assert.hpp:70
#define BB_ASSERT_GTE(left, right,...)
Definition assert.hpp:128
#define BB_ASSERT_GT(left, right,...)
Definition assert.hpp:113
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
Definition assert.hpp:224
static constexpr size_t NUM_MULTIPLICATION_TERMS
static void generate_constraints(AcirConstraint &arithmetic_constraint, WitnessVector &witness_values)
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.
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)
std::vector< BilinearConstraint > 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)
Constraint representing a polynomial of degree 1 or 2 that does not fit into a standard UltraHonk ari...
AluTraceBuilder builder
Definition alu.test.cpp:124
FF a
FF b
AcirFormat circuit_serde_to_acir_format(Acir::Circuit const &circuit, bool is_mega)
Convert an Acir::Circuit into an AcirFormat by processing all the opcodes.
AcirFormat constraint_to_acir_format(const ConstraintType &constraint)
Convert an AcirConstraint (single or vector) to AcirFormat by going through the full ACIR serde flow.
std::vector< bb::fr > WitnessVector
void assert_zero_to_constraints(Acir::Opcode::AssertZero const &arg, AcirFormat &af, size_t opcode_index, std::vector< BatchedEqEntry > &batched_eq_assert_zeros, bool is_mega)
Single entrypoint for processing arithmetic (AssertZero) opcodes.
std::vector< uint32_t > add_to_witness_and_track_indices(std::vector< bb::fr > &witness, const T &input)
Append values to a witness vector and track their indices.
Definition utils.hpp:90
Acir::Circuit build_acir_circuit(const std::vector< Acir::Opcode > &opcodes)
Build an Acir::Circuit from opcodes and witness count.
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
Definition tuple.hpp:13
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
Definition acir.hpp:5856
std::vector< uint8_t > q_c
Definition acir.hpp:5857
std::vector< std::tuple< std::vector< uint8_t >, Acir::Witness, Acir::Witness > > mul_terms
Definition acir.hpp:5855
Acir::Expression value
Definition acir.hpp:6330
std::variant< AssertZero, BlackBoxFuncCall, MemoryOp, MemoryInit, BrilligCall, Call > value
Definition acir.hpp:6592
Barretenberg's representation of ACIR constraints.
std::vector< QuadConstraint > quad_constraints
std::vector< BatchedEqCheckConstraint > batched_eq_check_constraints
std::vector< BilinearConstraint > bilinear_constraints
std::vector< BigQuadConstraint > big_quad_constraints
Struct containing both the constraints to be added to the circuit and the witness vector.
Metadata required to create a circuit.
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()
VectorField result