Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
opcode_gate_count.test.cpp
Go to the documentation of this file.
1#include <gtest/gtest.h>
2#include <memory>
3#include <vector>
4
5#include "acir_format.hpp"
11#include "test_class.hpp"
12
14
15using namespace bb;
16using namespace bb::crypto;
17using namespace acir_format;
18
19// Gate count pinning test suite
20template <typename Builder> class OpcodeGateCountTests : public ::testing::Test {
21 protected:
23
24 // NOTE: Gate count constants are defined in gate_count_constants.hpp
25 // All constants below reference the shared definitions from that file
26
27 // NOTE: Recursion constraint gate counts are NOT included in this suite because they:
28 // 1. Require proof generation which is expensive and slow
29 // 2. Have different gate counts depending on the recursive flavor (Ultra vs UltraRollup vs ZK, etc.)
30 //
31 // Recursion constraint gate count tests are located in their respective test files:
32 // - Honk recursion: honk_recursion_constraint.test.cpp::GateCountSingleHonkRecursion
33 //
34 // - Chonk recursion: chonk_recursion_constraints.test.cpp::GateCountChonkRecursion
35 //
36 // - Hypernova recursion: hypernova_recursion_constraint.test.cpp
37 //
38 // - AVM recursion: Not tested (AVM is not compiled in standard bb builds)
39};
40
41using BuilderTypes = testing::Types<UltraCircuitBuilder, MegaCircuitBuilder>;
43
45{
46 static constexpr size_t EXPECTED_RESULT = IsMegaBuilder<TypeParam> ? ZERO_GATE + MEGA_OFFSET<TypeParam> : ZERO_GATE;
47
48 TypeParam builder;
49 EXPECT_EQ(builder.num_gates(), EXPECTED_RESULT);
50}
51
53{
55 .a = 0,
56 .b = 1,
57 .c = 2,
58 .d = 3,
59 .mul_scaling = fr::one(),
60 .a_scaling = 0,
61 .b_scaling = 0,
62 .c_scaling = 0,
63 .d_scaling = fr::neg_one(),
64 .const_scaling = 0,
65 };
66
67 WitnessVector witness(4, 0);
68
69 // Test that gate counting works for multiple constraints
70 std::vector<bb::mul_quad_<fr>> constraints = { quad, quad };
71 AcirFormat constraint_system = constraint_to_acir_format(constraints);
72
73 AcirProgram program{ constraint_system, witness };
74 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
75 auto builder = create_circuit<TypeParam>(program, metadata);
76
77 // The first gate count incorporates the zero gate and mega offset adjustments, while the second doesn't
78 EXPECT_EQ(program.constraints.gates_per_opcode,
79 std::vector<size_t>({ QUAD<TypeParam>, QUAD<TypeParam> - ZERO_GATE - MEGA_OFFSET<TypeParam> }));
80}
81
83{
84 LogicConstraint logic_constraint{
87 .result = 2,
88 .num_bits = 32,
89 .is_xor_gate = true,
90 };
91
92 WitnessVector witness{ 5, 10, 15 };
93
94 AcirFormat constraint_system = constraint_to_acir_format(logic_constraint);
95
96 AcirProgram program{ constraint_system, witness };
97 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
98 auto builder = create_circuit<TypeParam>(program, metadata);
99
100 // As of now, this is the only test we have for the XOR opcode, so we test that it works
101 EXPECT_TRUE(CircuitChecker::check(builder));
102 EXPECT_FALSE(builder.failed());
103
104 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ LOGIC_XOR_32<TypeParam> }));
105}
106
108{
109 LogicConstraint logic_constraint{
112 .result = 2,
113 .num_bits = 32,
114 .is_xor_gate = false,
115 };
116
117 WitnessVector witness{ 5, 10, 0 };
118
119 AcirFormat constraint_system = constraint_to_acir_format(logic_constraint);
120
121 AcirProgram program{ constraint_system, witness };
122 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
123 auto builder = create_circuit<TypeParam>(program, metadata);
124
125 // As of now, this is the only test we have for the AND opcode, so we test that it works
126 EXPECT_TRUE(CircuitChecker::check(builder));
127 EXPECT_FALSE(builder.failed());
128
129 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ LOGIC_AND_32<TypeParam> }));
130}
131
133{
134 RangeConstraint range_constraint{
135 .witness = 0,
136 .num_bits = 32,
137 };
138
139 WitnessVector witness{ 100 };
140
141 AcirFormat constraint_system = constraint_to_acir_format(range_constraint);
142
143 AcirProgram program{ constraint_system, witness };
144 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
145 auto builder = create_circuit<TypeParam>(program, metadata);
146
147 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ RANGE_32<TypeParam> }));
148}
149
151{
152 Keccakf1600 keccak_permutation;
153
154 for (size_t idx = 0; idx < 25; idx++) {
155 keccak_permutation.state[idx] = WitnessOrConstant<bb::fr>::from_index(static_cast<uint32_t>(idx));
156 keccak_permutation.result[idx] = static_cast<uint32_t>(idx) + 25;
157 }
158
159 // As of now, this is the only test for the Keccak permutation opcode, so we test that it works as expected
160 std::array<uint64_t, 25> native_state = { 0 };
161 std::array<uint64_t, 25> expected_state = native_state;
162 ethash_keccakf1600(expected_state.data());
163
164 WitnessVector witness(25, 0);
165 for (const auto& state : expected_state) {
166 witness.emplace_back(state);
167 }
168
169 AcirFormat constraint_system = constraint_to_acir_format(keccak_permutation);
170
171 AcirProgram program{ constraint_system, witness };
172 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
173 auto builder = create_circuit<TypeParam>(program, metadata);
174
175 EXPECT_TRUE(CircuitChecker::check(builder));
176 EXPECT_FALSE(builder.failed());
177
178 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ KECCAK_PERMUTATION<TypeParam> }));
179}
180
182{
183 Poseidon2Constraint poseidon2_constraint;
184
185 for (size_t idx = 0; idx < 4; idx++) {
186 poseidon2_constraint.state.emplace_back(WitnessOrConstant<bb::fr>::from_index(static_cast<uint32_t>(idx)));
187 poseidon2_constraint.result.emplace_back(static_cast<uint32_t>(idx) + 4);
188 }
189
190 WitnessVector witness(8, 0);
191
192 AcirFormat constraint_system = constraint_to_acir_format(poseidon2_constraint);
193
194 AcirProgram program{ constraint_system, witness };
195 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
196 auto builder = create_circuit<TypeParam>(program, metadata);
197
198 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ POSEIDON2_PERMUTATION<TypeParam> }));
199}
200
202{
203 Sha256Compression sha256_compression;
204
205 for (size_t i = 0; i < 16; ++i) {
206 sha256_compression.inputs[i] = WitnessOrConstant<bb::fr>::from_index(static_cast<uint32_t>(i));
207 }
208 for (size_t i = 0; i < 8; ++i) {
209 sha256_compression.hash_values[i] = WitnessOrConstant<bb::fr>::from_index(static_cast<uint32_t>(i));
210 }
211 for (size_t i = 0; i < 8; ++i) {
212 sha256_compression.result[i] = static_cast<uint32_t>(i) + 24;
213 }
214
215 WitnessVector witness(32, 0);
216
217 AcirFormat constraint_system = constraint_to_acir_format(sha256_compression);
218
219 AcirProgram program{ constraint_system, witness };
220 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
221 auto builder = create_circuit<TypeParam>(program, metadata);
222
223 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ SHA256_COMPRESSION<TypeParam> }));
224}
225
227{
228 AES128Constraint aes128_constraint;
229
230 // Create a minimal AES128 constraint with 16 bytes of input
231 for (size_t i = 0; i < 16; ++i) {
232 aes128_constraint.inputs.push_back(WitnessOrConstant<bb::fr>::from_index(static_cast<uint32_t>(i)));
233 }
234
235 for (size_t i = 0; i < 16; ++i) {
236 aes128_constraint.iv[i] = WitnessOrConstant<bb::fr>::from_index(static_cast<uint32_t>(i + 16));
237 }
238
239 for (size_t i = 0; i < 16; ++i) {
240 aes128_constraint.key[i] = WitnessOrConstant<bb::fr>::from_index(static_cast<uint32_t>(i + 32));
241 }
242
243 for (size_t i = 0; i < 16; ++i) {
244 aes128_constraint.outputs.push_back(static_cast<uint32_t>(i + 48));
245 }
246
247 WitnessVector witness(64, fr(0));
248
249 AcirFormat constraint_system = constraint_to_acir_format(aes128_constraint);
250
251 AcirProgram program{ constraint_system, witness };
252 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
253 auto builder = create_circuit<TypeParam>(program, metadata);
254
255 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ AES128_ENCRYPTION<TypeParam> }));
256}
257
259{
260 EcdsaConstraint ecdsa_constraint{ .type = bb::CurveType::SECP256K1 };
261 for (size_t i = 0; i < 32; ++i) {
262 ecdsa_constraint.hashed_message[i] = static_cast<uint32_t>(i);
263 }
264
265 for (size_t i = 0; i < 64; ++i) {
266 ecdsa_constraint.signature[i] = static_cast<uint32_t>(i + 32);
267 }
268
269 for (size_t i = 0; i < 32; ++i) {
270 ecdsa_constraint.pub_x_indices[i] = static_cast<uint32_t>(i + 96);
271 }
272
273 for (size_t i = 0; i < 32; ++i) {
274 ecdsa_constraint.pub_y_indices[i] = static_cast<uint32_t>(i + 128);
275 }
276
277 ecdsa_constraint.predicate = WitnessOrConstant<bb::fr>::from_index(static_cast<uint32_t>(160));
278 ecdsa_constraint.result = static_cast<uint32_t>(161);
279
280 WitnessVector witness(162, fr(0));
281 // Override public key values to avoid failures
282 auto point = bb::curve::SECP256K1::AffineElement::one();
283 auto x_buffer = point.x.to_buffer();
284 auto y_buffer = point.y.to_buffer();
285 for (size_t idx = 0; idx < 32; idx++) {
286 witness[idx + 96] = x_buffer[idx];
287 witness[idx + 128] = y_buffer[idx];
288 }
289
290 AcirFormat constraint_system = constraint_to_acir_format(ecdsa_constraint);
291
292 AcirProgram program{ constraint_system, witness };
293 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
294 auto builder = create_circuit<TypeParam>(program, metadata);
295
296 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ ECDSA_SECP256K1<TypeParam> }));
297}
298
300{
301 EcdsaConstraint ecdsa_constraint{ .type = bb::CurveType::SECP256R1 };
302 for (size_t i = 0; i < 32; ++i) {
303 ecdsa_constraint.hashed_message[i] = static_cast<uint32_t>(i);
304 }
305
306 for (size_t i = 0; i < 64; ++i) {
307 ecdsa_constraint.signature[i] = static_cast<uint32_t>(i + 32);
308 }
309
310 for (size_t i = 0; i < 32; ++i) {
311 ecdsa_constraint.pub_x_indices[i] = static_cast<uint32_t>(i + 96);
312 }
313
314 for (size_t i = 0; i < 32; ++i) {
315 ecdsa_constraint.pub_y_indices[i] = static_cast<uint32_t>(i + 128);
316 }
317
318 ecdsa_constraint.predicate = WitnessOrConstant<bb::fr>::from_index(static_cast<uint32_t>(160));
319 ecdsa_constraint.result = static_cast<uint32_t>(161);
320
321 WitnessVector witness(162, fr(0));
322 // Override public key values to avoid failures
323 auto point = bb::curve::SECP256K1::AffineElement::one();
324 auto x_buffer = point.x.to_buffer();
325 auto y_buffer = point.y.to_buffer();
326 for (size_t idx = 0; idx < 32; idx++) {
327 witness[idx + 96] = x_buffer[idx];
328 witness[idx + 128] = y_buffer[idx];
329 }
330
331 AcirFormat constraint_system = constraint_to_acir_format(ecdsa_constraint);
332
333 AcirProgram program{ constraint_system, witness };
334 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
335 auto builder = create_circuit<TypeParam>(program, metadata);
336
337 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ ECDSA_SECP256R1<TypeParam> }));
338}
339
341{
342 Blake2sConstraint blake2s_constraint;
343
344 blake2s_constraint.inputs.push_back(WitnessOrConstant<bb::fr>::from_index(0));
345
346 for (size_t i = 0; i < 32; ++i) {
347 blake2s_constraint.result[i] = static_cast<uint32_t>(i + 1);
348 }
349
350 WitnessVector witness(33, fr(0));
351
352 AcirFormat constraint_system = constraint_to_acir_format(blake2s_constraint);
353
354 AcirProgram program{ constraint_system, witness };
355 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
356 auto builder = create_circuit<TypeParam>(program, metadata);
357
358 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ BLAKE2S<TypeParam> }));
359}
360
362{
363 Blake3Constraint blake3_constraint;
364
365 blake3_constraint.inputs.push_back(WitnessOrConstant<bb::fr>::from_index(0));
366
367 for (size_t i = 0; i < 32; ++i) {
368 blake3_constraint.result[i] = static_cast<uint32_t>(i + 1);
369 }
370
371 WitnessVector witness(33, fr(0));
372
373 AcirFormat constraint_system = constraint_to_acir_format(blake3_constraint);
374
375 AcirProgram program{ constraint_system, witness };
376 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
377 auto builder = create_circuit<TypeParam>(program, metadata);
378
379 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ BLAKE3<TypeParam> }));
380}
381
383{
384 using GrumpkinPoint = bb::grumpkin::g1::affine_element;
385
386 // Use a valid Grumpkin point (the generator)
387 auto point = GrumpkinPoint::one();
388
389 MultiScalarMul msm_constraint;
390
391 // Create a minimal MSM with one point and one scalar
392 msm_constraint.points.push_back(WitnessOrConstant<bb::fr>::from_index(0)); // x
393 msm_constraint.points.push_back(WitnessOrConstant<bb::fr>::from_index(1)); // y
394 msm_constraint.points.push_back(WitnessOrConstant<bb::fr>::from_index(2)); // is_infinite
395
396 msm_constraint.scalars.push_back(WitnessOrConstant<bb::fr>::from_index(3)); // scalar_lo
397 msm_constraint.scalars.push_back(WitnessOrConstant<bb::fr>::from_index(4)); // scalar_hi
398
400
401 msm_constraint.out_point_x = 6;
402 msm_constraint.out_point_y = 7;
403 msm_constraint.out_point_is_infinite = 8;
404
405 WitnessVector witness(9, fr(0));
406 // Set valid point coordinates
407 witness[0] = point.x;
408 witness[1] = point.y;
409 witness[2] = fr(0);
410 witness[6] = point.x;
411 witness[7] = point.y;
412 witness[8] = fr(0);
413
414 AcirFormat constraint_system = constraint_to_acir_format(msm_constraint);
415
416 AcirProgram program{ constraint_system, witness };
417 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
418 auto builder = create_circuit<TypeParam>(program, metadata);
419
420 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ MULTI_SCALAR_MUL<TypeParam> }));
421}
422
424{
425 using GrumpkinPoint = bb::grumpkin::g1::affine_element;
426
427 // Use valid Grumpkin points (the generator)
428 auto point1 = GrumpkinPoint::one();
429 auto point2 = GrumpkinPoint::one();
430
431 EcAdd ec_add_constraint{
434 .input1_infinite = WitnessOrConstant<bb::fr>::from_index(2),
437 .input2_infinite = WitnessOrConstant<bb::fr>::from_index(5),
439 .result_x = 7,
440 .result_y = 8,
441 .result_infinite = 9,
442 };
443
444 WitnessVector witness(10, fr(0));
445 // Set valid point1 coordinates
446 witness[0] = point1.x;
447 witness[1] = point1.y;
448 witness[2] = fr(0);
449 // Set valid point2 coordinates
450 witness[3] = point2.x;
451 witness[4] = point2.y;
452 witness[5] = fr(0);
453 // Set valid result coordinates
454 witness[7] = point1.x;
455 witness[8] = point1.y;
456 witness[9] = fr(0);
457
458 AcirFormat constraint_system = constraint_to_acir_format(ec_add_constraint);
459
460 AcirProgram program{ constraint_system, witness };
461 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
462 auto builder = create_circuit<TypeParam>(program, metadata);
463
464 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ EC_ADD<TypeParam> }));
465}
466
468{
469 WitnessVector witness{ 10, 20, 0, 10 };
470
471 // Create a simple ROM block with 2 elements and 1 read
472 std::vector<uint32_t> init;
473 init.push_back(0); // 10
474 init.push_back(1); // 20
475
477 trace.push_back(MemOp{
478 .access_type = AccessType::Read,
481 });
482
483 BlockConstraint block_constraint{
484 .init = init,
485 .trace = trace,
486 .type = BlockType::ROM,
487 .calldata_id = CallDataType::None,
488 };
489
490 AcirFormat constraint_system = constraint_to_acir_format(block_constraint);
491 // The block constraint creates 2 opcodes (MemoryInit + MemoryOp), but MemoryInit doesn't add gates, so we
492 // adjust num_acir_opcodes to track only the MemoryOp gates
493 constraint_system.num_acir_opcodes = 1;
495
496 AcirProgram program{ constraint_system, witness };
497 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
498 auto builder = create_circuit<TypeParam>(program, metadata);
499
500 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ BLOCK_ROM_READ<TypeParam> }));
501}
502
504{
505 WitnessVector witness{ 10, 20, 0, 10 };
506
507 // Create a simple RAM block with 2 elements and 1 read
508 std::vector<uint32_t> init;
509 init.push_back(0); // 10
510 init.push_back(1); // 20
511
513 trace.push_back(MemOp{
514 .access_type = AccessType::Read,
517 });
518
519 BlockConstraint block_constraint{
520 .init = init,
521 .trace = trace,
522 .type = BlockType::RAM,
523 .calldata_id = CallDataType::None,
524 };
525
526 AcirFormat constraint_system = constraint_to_acir_format(block_constraint);
527 // The block constraint creates 2 opcodes (MemoryInit + MemoryOp), but MemoryInit doesn't add gates, so we
528 // adjust num_acir_opcodes to track only the MemoryOp gates
529 constraint_system.num_acir_opcodes = 1;
531
532 AcirProgram program{ constraint_system, witness };
533 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
534 auto builder = create_circuit<TypeParam>(program, metadata);
535
536 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ BLOCK_RAM_READ<TypeParam> }));
537}
538
540{
541 WitnessVector witness{ 10, 20, 0, 10 };
542
543 // Create a simple RAM block with 2 elements and 1 read
544 std::vector<uint32_t> init;
545 init.push_back(0); // 10
546 init.push_back(1); // 20
547
549 trace.push_back(MemOp{
550 .access_type = AccessType::Write,
553 });
554
555 BlockConstraint block_constraint{
556 .init = init,
557 .trace = trace,
558 .type = BlockType::RAM,
559 .calldata_id = CallDataType::None,
560 };
561
562 AcirFormat constraint_system = constraint_to_acir_format(block_constraint);
563 // The block constraint creates 2 opcodes (MemoryInit + MemoryOp), but MemoryInit doesn't add gates, so we
564 // adjust num_acir_opcodes to track only the MemoryOp gates
565 constraint_system.num_acir_opcodes = 1;
567
568 AcirProgram program{ constraint_system, witness };
569 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
570 auto builder = create_circuit<TypeParam>(program, metadata);
571
572 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ BLOCK_RAM_WRITE<TypeParam> }));
573}
574
576{
577 if constexpr (!IsMegaBuilder<TypeParam>) {
578 GTEST_SKIP() << "CallData only supported on MegaCircuitBuilder";
579 }
580
581 WitnessVector witness{ 10, 20, 0, 10 };
582
583 // Create a simple CallData block with 2 elements and 1 read
584 std::vector<uint32_t> init;
585 init.push_back(0); // 10
586 init.push_back(1); // 20
587
589 trace.push_back(MemOp{
590 .access_type = AccessType::Read,
593 });
594
595 // Primary calldata
596 {
597 BlockConstraint block_constraint{
598 .init = init,
599 .trace = trace,
600 .type = BlockType::CallData,
601 .calldata_id = CallDataType::Primary,
602 };
603
604 AcirFormat constraint_system = constraint_to_acir_format(block_constraint);
605 // The block constraint creates 2 opcodes (MemoryInit + MemoryOp), but MemoryInit doesn't add gates, so we
606 // adjust num_acir_opcodes to track only the MemoryOp gates
607 constraint_system.num_acir_opcodes = 1;
609
610 AcirProgram program{ constraint_system, witness };
611 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
612 auto builder = create_circuit<TypeParam>(program, metadata);
613
614 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ BLOCK_CALLDATA<TypeParam> }));
615 }
616
617 // Secondary calldata
618 {
619 BlockConstraint block_constraint{
620 .init = init,
621 .trace = trace,
622 .type = BlockType::CallData,
623 .calldata_id = CallDataType::Secondary,
624 };
625
626 AcirFormat constraint_system = constraint_to_acir_format(block_constraint);
627 // The block constraint creates 2 opcodes (MemoryInit + MemoryOp), but MemoryInit doesn't add gates, so we
628 // adjust num_acir_opcodes to track only the MemoryOp gates
629 constraint_system.num_acir_opcodes = 1;
631
632 AcirProgram program{ constraint_system, witness };
633 const ProgramMetadata metadata{ .collect_gates_per_opcode = true };
634 auto builder = create_circuit<TypeParam>(program, metadata);
635
636 EXPECT_EQ(program.constraints.gates_per_opcode, std::vector<size_t>({ BLOCK_CALLDATA<TypeParam> }));
637 }
638}
639
641{
642 if constexpr (!IsMegaBuilder<TypeParam>) {
643 GTEST_SKIP() << "ReturnData only supported on MegaCircuitBuilder";
644 }
645
646 WitnessVector witness{ 10, 20 };
647
648 // Create a simple ReturnData block with 2 elements
649 std::vector<uint32_t> init;
650 init.push_back(0); // 10
651 init.push_back(1); // 20
652
653 BlockConstraint block_constraint{
654 .init = init,
655 .trace = {},
656 .type = BlockType::ReturnData,
657 .calldata_id = CallDataType::None,
658 };
659
660 AcirFormat constraint_system = constraint_to_acir_format(block_constraint);
661 // The block constraint creates 2 opcodes (MemoryInit + MemoryOp), but MemoryInit doesn't add gates, so we
662 // adjust num_acir_opcodes to track only the MemoryOp gates
663 constraint_system.num_acir_opcodes = 1;
665
666 AcirProgram program{ constraint_system, witness };
667 const ProgramMetadata metadata{
669 }; // We need to set it to false because ReturnData BlockConstraints do not have any trace, so we would be dividing
670 // by zero, and this would throw an error.
671 auto builder = create_circuit<TypeParam>(program, metadata);
672
673 EXPECT_EQ(builder.get_num_finalized_gates_inefficient(/*ensure_nonzero=*/false), BLOCK_RETURNDATA<TypeParam>);
674}
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
Applies the Poseidon2 permutation function from https://eprint.iacr.org/2023/323.
group_elements::affine_element< Fq, Fr, Params > affine_element
Definition group.hpp:42
AluTraceBuilder builder
Definition alu.test.cpp:124
TestTraceContainer trace
void ethash_keccakf1600(uint64_t state[KECCAKF1600_LANES]) NOEXCEPT
const auto init
Definition fr.bench.cpp:135
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
constexpr size_t ZERO_GATE
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
field< Bn254FrParams > fr
Definition fr.hpp:155
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
@ SECP256K1
Definition types.hpp:10
@ SECP256R1
Definition types.hpp:10
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
::testing::Types< UltraCircuitBuilder, MegaCircuitBuilder > BuilderTypes
std::array< WitnessOrConstant< bb::fr >, 16 > iv
std::vector< uint32_t > outputs
std::vector< WitnessOrConstant< bb::fr > > inputs
std::array< WitnessOrConstant< bb::fr >, 16 > key
Barretenberg's representation of ACIR constraints.
AcirFormatOriginalOpcodeIndices original_opcode_indices
Indices of the original opcode that originated each constraint in AcirFormat.
std::vector< std::vector< size_t > > block_constraints
Struct containing both the constraints to be added to the circuit and the witness vector.
std::vector< WitnessOrConstant< bb::fr > > inputs
std::array< uint32_t, 32 > result
std::array< uint32_t, 32 > result
std::vector< WitnessOrConstant< bb::fr > > inputs
Struct holding the data required to add memory constraints to a circuit.
std::vector< uint32_t > init
Constraints for addition of two points on the Grumpkin curve.
WitnessOrConstant< bb::fr > input1_x
std::array< uint32_t, 25 > result
std::array< WitnessOrConstant< bb::fr >, 25 > state
Logic constraint representation in ACIR format.
WitnessOrConstant< fr > a
Memory operation. Index and value store the index of the memory location, and value is the value to b...
std::vector< WitnessOrConstant< bb::fr > > scalars
WitnessOrConstant< bb::fr > predicate
std::vector< WitnessOrConstant< bb::fr > > points
std::vector< WitnessOrConstant< bb::fr > > state
Metadata required to create a circuit.
std::array< WitnessOrConstant< bb::fr >, 8 > hash_values
std::array< uint32_t, 8 > result
std::array< WitnessOrConstant< bb::fr >, 16 > inputs
static WitnessOrConstant from_index(uint32_t index)
static constexpr field neg_one()
static constexpr field one()