Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
hypernova_recursion_constraint.test.cpp
Go to the documentation of this file.
2#include "acir_format.hpp"
14
15#include <gtest/gtest.h>
16#include <vector>
17
18using namespace acir_format;
19using namespace bb;
20
21class HypernovaRecursionConstraintTest : public ::testing::Test {
22
23 public:
27 using FF = Flavor::FF;
32
33 static constexpr size_t NUM_TRAILING_KERNELS = 3; // reset, tail, hiding
34
47
48 static std::shared_ptr<VerificationKey> get_verification_key(Builder& builder_in)
49 {
50 // This is a workaround to ensure that the circuit is finalized before we create the verification key
51 // In practice, this should not be needed as the circuit will be finalized when it is accumulated into the IVC
52 // but this is a workaround for the test setup.
53 // Create a copy of the input circuit
55
56 // Deepcopy the opqueue to avoid modifying the original one
59 std::shared_ptr<VerificationKey> vk = std::make_shared<VerificationKey>(prover_instance->get_precomputed());
60 return vk;
61 }
62
64 {
65
66 // Reset kernel
67 EXPECT_EQ(ivc->verification_queue.size(), 1);
68 EXPECT_EQ(ivc->verification_queue[0].type, QUEUE_TYPE::HN);
70
71 // Tail kernel
72 EXPECT_EQ(ivc->verification_queue.size(), 1);
73 EXPECT_EQ(ivc->verification_queue[0].type, QUEUE_TYPE::HN_TAIL);
75
76 // Hiding kernel
77 EXPECT_EQ(ivc->verification_queue.size(), 1);
78 EXPECT_EQ(ivc->verification_queue[0].type, QUEUE_TYPE::HN_FINAL);
80 }
81
82 static UltraCircuitBuilder create_inner_circuit(size_t log_num_gates = 10)
83 {
85
86 // Create 2^log_n many add gates based on input log num gates
87 const size_t num_gates = (1 << log_num_gates);
88 for (size_t i = 0; i < num_gates; ++i) {
90 uint32_t a_idx = builder.add_variable(a);
91
94 fr d = a + b + c;
95 uint32_t b_idx = builder.add_variable(b);
96 uint32_t c_idx = builder.add_variable(c);
97 uint32_t d_idx = builder.add_variable(d);
98
99 builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, fr(1), fr(1), fr(1), fr(-1), fr(0) });
100 }
101
103 return builder;
104 }
105
111 {
112 AcirProgram program;
113 std::vector<RecursionConstraint> recursion_constraints;
114
115 Builder circuit{ ivc->goblin.op_queue };
118
119 {
120 using RecursiveFlavor = UltraRecursiveFlavor_<Builder>;
122 using StdlibProof = bb::stdlib::Proof<Builder>;
124
125 // Create an arbitrary inner circuit
126 auto inner_circuit = create_inner_circuit();
127
128 // Compute native verification key
129 auto prover_instance = std::make_shared<ProverInstance_<UltraFlavor>>(inner_circuit);
130 auto honk_vk = std::make_shared<UltraFlavor::VerificationKey>(prover_instance->get_precomputed());
131 UltraProver prover(prover_instance, honk_vk); // A prerequisite for computing VK
132 auto inner_proof = prover.construct_proof();
133
134 if (tamper_vk) {
135 honk_vk->q_l = g1::one;
136 auto honk_vk_and_hash = std::make_shared<UltraFlavor::VKAndHash>(honk_vk);
137 UltraVerifier_<UltraFlavor, DefaultIO> verifier(honk_vk_and_hash);
138 EXPECT_FALSE(verifier.verify_proof(inner_proof).result);
139 }
140 // Instantiate the recursive verifier using the native verification key
141 auto stdlib_vk_and_hash = std::make_shared<RecursiveFlavor::VKAndHash>(circuit, honk_vk);
142 bb::UltraVerifier_<RecursiveFlavor, StdlibIO> verifier(stdlib_vk_and_hash);
143
144 StdlibProof stdlib_inner_proof(circuit, inner_proof);
145 VerifierOutput output = verifier.verify_proof(stdlib_inner_proof);
146
147 // IO
148 StdlibIO inputs;
149 inputs.pairing_inputs = output.points_accumulator;
150 inputs.set_public(); // propagate resulting pairing points on the public inputs
151 }
152
153 return circuit;
154 }
155
164 static RecursionConstraint create_recursion_constraint(const VerifierInputs& input, std::vector<FF>& witness)
165 {
166 // The proof type can be either Oink or HN or PG_FINAL
167 PROOF_TYPE proof_type;
168 switch (input.type) {
169 case QUEUE_TYPE::OINK:
170 proof_type = OINK;
171 break;
172 case QUEUE_TYPE::HN:
173 proof_type = HN;
174 break;
175 case QUEUE_TYPE::HN_FINAL:
176 proof_type = HN_FINAL;
177 break;
178 case QUEUE_TYPE::HN_TAIL:
179 proof_type = HN_TAIL;
180 break;
181 default:
182 throw std::runtime_error("Invalid proof type");
183 }
184
185 RecursionConstraint constraint =
187 input.proof, // proof contains the public inputs at this stage
188 input.honk_vk->to_field_elements(),
189 input.honk_vk->hash(),
190 bb::fr::zero(),
191 /*num_public_inputs_to_extract=*/0,
192 proof_type);
193
194 constraint.proof = {}; // the proof witness indices are not needed in an ivc recursion constraint
195
196 return constraint;
197 }
198
213 {
214 AcirProgram program;
215
216 // Construct recursion constraints based on the ivc verification queue; populate the witness along the way
217 std::vector<RecursionConstraint> hn_recursion_constraints;
218 hn_recursion_constraints.reserve(verification_queue.size());
219 for (const auto& queue_entry : verification_queue) {
220 hn_recursion_constraints.push_back(create_recursion_constraint(queue_entry, program.witness));
221 }
222
223 // Construct a constraint system containing the business logic and ivc recursion constraints
224 program.constraints.max_witness_index = static_cast<uint32_t>(program.witness.size() - 1);
225 program.constraints.num_acir_opcodes = static_cast<uint32_t>(hn_recursion_constraints.size());
226 program.constraints.hn_recursion_constraints = hn_recursion_constraints;
228 hn_recursion_constraints.size() == 1
231
232 return program;
233 }
234
236 {
237 // construct a mock kernel program (acir) from the ivc verification queue
238 const ProgramMetadata metadata{ ivc };
239 AcirProgram mock_kernel_program = construct_mock_kernel_program(ivc->verification_queue);
240 auto kernel = acir_format::create_circuit<Builder>(mock_kernel_program, metadata);
241 auto kernel_vk = get_kernel_vk_from_circuit(kernel);
242 ivc->accumulate(kernel, kernel_vk);
243 }
244
246 {
247 // construct a mock kernel program (acir) from the ivc verification queue
248 auto app_circuit = construct_mock_app_circuit(ivc);
249 ivc->accumulate(app_circuit, get_verification_key(app_circuit));
250 }
251
259 {
260 // Create kernel circuit from the kernel program
261 auto kernel = acir_format::create_circuit<Builder>(program);
262
263 // Manually construct the VK for the kernel circuit
264 auto prover_instance = std::make_shared<Chonk::ProverInstance>(kernel);
265 auto verification_key = std::make_shared<Chonk::MegaVerificationKey>(prover_instance->get_precomputed());
266 return verification_key;
267 }
268
270 {
271 auto prover_instance = std::make_shared<Chonk::ProverInstance>(kernel);
272 auto verification_key = std::make_shared<Chonk::MegaVerificationKey>(prover_instance->get_precomputed());
273 return verification_key;
274 }
275
276 protected:
278};
279
284{
286 EXPECT_EQ(merge_proof.size(), MERGE_PROOF_SIZE);
287}
288
294{
295 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5 /* app, kernel, reset, tail, hiding */);
296
297 // construct a mock app_circuit
298 construct_and_accumulate_mock_app(ivc);
299
300 // Construct kernel consisting only of the kernel completion logic
301 construct_and_accumulate_mock_kernel(ivc);
302
303 // add the trailing kernels
304 construct_and_accumulate_trailing_kernels(ivc);
305
306 auto proof = ivc->prove();
307 {
308 auto vk_and_hash = ivc->get_hiding_kernel_vk_and_hash();
309 ChonkNativeVerifier verifier(vk_and_hash);
310 EXPECT_TRUE(verifier.verify(proof));
311 }
312}
313
319{
320 // 4 ciruits and the tail kernel
321 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/7);
322
323 // construct a mock app_circuit
324 construct_and_accumulate_mock_app(ivc);
325
326 const ProgramMetadata metadata{ ivc };
327
328 // Construct kernel_0; consists of a single oink recursive verification for app (plus databus/merge logic)
329 construct_and_accumulate_mock_kernel(ivc);
330
331 // construct a mock app_circuit
332 construct_and_accumulate_mock_app(ivc);
333
334 // Construct and accumulate another Kernel circuit
335 construct_and_accumulate_mock_kernel(ivc);
336
337 // Accumulate the trailing kernels
338 construct_and_accumulate_trailing_kernels(ivc);
339
340 auto proof = ivc->prove();
341 {
342 ChonkNativeVerifier verifier(ivc->get_hiding_kernel_vk_and_hash());
343 EXPECT_TRUE(verifier.verify(proof));
344 }
345}
346
347// Test generation of "init" kernel VK via dummy IVC data
348TEST_F(HypernovaRecursionConstraintTest, GenerateInitKernelVKFromConstraints)
349{
351 // First, construct the kernel VK by running the full IVC (accumulate one app and one kernel)
353 {
354 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
355
356 // Construct and accumulate mock app_circuit
357 construct_and_accumulate_mock_app(ivc);
358
359 // Construct and accumulate kernel consisting only of the kernel completion logic
360 construct_and_accumulate_mock_kernel(ivc);
361 expected_kernel_vk = ivc->verification_queue.back().honk_vk;
362 }
363
364 // Now, construct the kernel VK by mocking the post app accumulation state of the IVC
366 {
367 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
368
369 // Construct kernel consisting only of the kernel completion logic
370 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::OINK, /*is_kernel=*/false);
371 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
372 program.witness = {}; // remove the witness to mimick VK construction context
373
374 kernel_vk = construct_kernel_vk_from_acir_program(program);
375 }
376
377 // Compare the VK constructed via running the IVc with the one constructed via mocking
378 EXPECT_EQ(*kernel_vk.get(), *expected_kernel_vk.get());
379}
380
381// Test generation of "reset" kernel VK via dummy IVC data
382TEST_F(HypernovaRecursionConstraintTest, GenerateResetKernelVKFromConstraints)
383{
385 // First, construct the kernel VK by running the full IVC (accumulate one app and one kernel)
387 {
388 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
389
390 const ProgramMetadata metadata{ ivc };
391
392 // Construct and accumulate mock app_circuit
393 construct_and_accumulate_mock_app(ivc);
394
395 // Construct and accumulate a mock INIT kernel (oink recursion for app accumulation)
396 construct_and_accumulate_mock_kernel(ivc);
397 EXPECT_TRUE(ivc->verification_queue.size() == 1);
398 EXPECT_TRUE(ivc->verification_queue[0].type == bb::Chonk::QUEUE_TYPE::HN);
399
400 // Construct and accumulate a mock RESET kernel (HN recursion for kernel accumulation)
401 construct_and_accumulate_mock_kernel(ivc);
402 expected_kernel_vk = ivc->verification_queue.back().honk_vk;
403 }
404
405 // Now, construct the kernel VK by mocking the IVC state prior to kernel construction
407 {
408 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
409
410 // Construct kernel consisting only of the kernel completion logic
411 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/true);
412 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
413 program.witness = {}; // remove the witness to mimick VK construction context
414 kernel_vk = construct_kernel_vk_from_acir_program(program);
415 }
416
417 // Compare the VK constructed via running the IVc with the one constructed via mocking
418 EXPECT_EQ(*kernel_vk.get(), *expected_kernel_vk.get());
419}
420
421// Test generation of "tail" kernel VK via dummy IVC data
422TEST_F(HypernovaRecursionConstraintTest, GenerateTailKernelVKFromConstraints)
423{
425 // First, construct the kernel VK by running the full IVC (accumulate one app and one kernel)
427 {
428 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
429
430 const ProgramMetadata metadata{ ivc };
431
432 // Construct and accumulate mock app_circuit
433 construct_and_accumulate_mock_app(ivc);
434
435 // Construct and accumulate a mock INIT kernel (oink recursion for app accumulation)
436 construct_and_accumulate_mock_kernel(ivc);
437
438 // Construct and accumulate a mock RESET kernel (HN recursion for kernel accumulation)
439 construct_and_accumulate_mock_kernel(ivc);
440
441 // Construct and accumulate a mock TAIL kernel (HN recursion for kernel accumulation)
442 EXPECT_TRUE(ivc->verification_queue.size() == 1);
443 EXPECT_TRUE(ivc->verification_queue[0].type == bb::Chonk::QUEUE_TYPE::HN_TAIL);
444 construct_and_accumulate_mock_kernel(ivc);
445
446 expected_kernel_vk = ivc->verification_queue.back().honk_vk;
447 }
448
449 // Now, construct the kernel VK by mocking the IVC state prior to kernel construction
451 {
452 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
453
454 // Construct kernel consisting only of the kernel completion logic
455 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN_TAIL, /*is_kernel=*/true);
456 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
457 program.witness = {}; // remove the witness to mimick VK construction context
458
459 kernel_vk = construct_kernel_vk_from_acir_program(program);
460 }
461
462 // Compare the VK constructed via running the IVc with the one constructed via mocking
463 EXPECT_EQ(*kernel_vk.get(), *expected_kernel_vk.get());
464}
465
466// Test generation of "inner" kernel VK via dummy IVC data
467TEST_F(HypernovaRecursionConstraintTest, GenerateInnerKernelVKFromConstraints)
468{
470 // First, construct the kernel VK by running the full IVC (accumulate one app and one kernel)
472 {
473 // we have to set the number of circuits one more than the number of circuits we're accumulating as otherwise
474 // the last circuit will be seen as a tail
475 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/6);
476
477 const ProgramMetadata metadata{ ivc };
478
479 { // Construct and accumulate mock app_circuit
480 construct_and_accumulate_mock_app(ivc);
481 }
482
483 // Construct and accumulate a mock INIT kernel (oink recursion for app accumulation)
484 construct_and_accumulate_mock_kernel(ivc);
485
486 { // Construct and accumulate a second mock app_circuit
487 construct_and_accumulate_mock_app(ivc);
488 }
489
490 { // Construct and accumulate a mock INNER kernel (HN recursion for kernel accumulation)
491 EXPECT_TRUE(ivc->verification_queue.size() == 2);
492 EXPECT_TRUE(ivc->verification_queue[1].type == bb::Chonk::QUEUE_TYPE::HN);
493 construct_and_accumulate_mock_kernel(ivc);
494 }
495
496 expected_kernel_vk = ivc->verification_queue.back().honk_vk;
497 }
498
499 // Now, construct the kernel VK by mocking the IVC state prior to kernel construction
501 {
502 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/4);
503
504 // Construct kernel consisting only of the kernel completion logic
505 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/true);
506 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/false);
507 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
508 program.witness = {}; // remove the witness to mimick VK construction context
509
510 kernel_vk = construct_kernel_vk_from_acir_program(program);
511 }
512
513 // Compare the VK constructed via running the IVc with the one constructed via mocking
514 EXPECT_EQ(*kernel_vk.get(), *expected_kernel_vk.get());
515}
516
517// Test generation of "hiding" kernel VK via dummy IVC data
518TEST_F(HypernovaRecursionConstraintTest, GenerateMegaVerificationKeyFromConstraints)
519{
521 // First, construct the kernel VK by running the full IVC
522 std::shared_ptr<MegaFlavor::VerificationKey> expected_hiding_kernel_vk;
523 {
524 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
525 const ProgramMetadata metadata{ ivc };
526
527 {
528 // Construct and accumulate mock app_circuit
529 construct_and_accumulate_mock_app(ivc);
530 }
531
532 {
533 // Construct and accumulate a mock INIT kernel (oink recursion for app accumulation)
534 construct_and_accumulate_mock_kernel(ivc);
535 }
536
537 construct_and_accumulate_trailing_kernels(ivc);
538
539 // The single entry in the verification queue corresponds to the hiding kernel
540 expected_hiding_kernel_vk = ivc->verification_queue[0].honk_vk;
541 }
542
543 // Now, construct the kernel VK by mocking the IVC state prior to kernel construction
545 {
546 // mock IVC accumulation increases the num_circuits_accumualted, hence we need to assume the tail kernel has
547 // been accumulated
548 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
549 // construct a mock tail kernel
551 Chonk::QUEUE_TYPE::HN_FINAL,
552 /*is_kernel=*/true);
553 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
554 program.witness = {}; // remove the witness to mimick VK construction context
555 kernel_vk = construct_kernel_vk_from_acir_program(program);
556 }
557
558 // Compare the VK constructed via running the IVc with the one constructed via mocking
559 EXPECT_EQ(*kernel_vk.get(), *expected_hiding_kernel_vk.get());
560}
561
565TEST_F(HypernovaRecursionConstraintTest, RecursiveVerifierAppCircuit)
566{
567 auto ivc = std::make_shared<Chonk>(/*num_circuits*/ 5);
568
569 // construct a mock app_circuit with an UH recursion call
570 Builder app_circuit = construct_mock_UH_recursion_app_circuit(ivc, /*tamper_vk=*/false);
571
572 // Complete instance and generate an oink proof
573 ivc->accumulate(app_circuit, get_verification_key(app_circuit));
574
575 // Construct kernel consisting only of the kernel completion logic
576 construct_and_accumulate_mock_kernel(ivc);
577
578 construct_and_accumulate_trailing_kernels(ivc);
579
580 auto proof = ivc->prove();
581 {
582 ChonkNativeVerifier verifier(ivc->get_hiding_kernel_vk_and_hash());
583 EXPECT_TRUE(verifier.verify(proof));
584 }
585}
586
591TEST_F(HypernovaRecursionConstraintTest, RecursiveVerifierAppCircuitFailure)
592{
593 BB_DISABLE_ASSERTS(); // Disable assert in HN prover
594
595 auto ivc = std::make_shared<Chonk>(/*num_circuits*/ 5);
596
597 // construct and accumulate mock app_circuit that has bad pairing point object
598 Builder app_circuit = construct_mock_UH_recursion_app_circuit(ivc, /*tamper_vk=*/true);
599 ivc->accumulate(app_circuit, get_verification_key(app_circuit));
600
601 // Construct kernel consisting only of the kernel completion logic
602 construct_and_accumulate_mock_kernel(ivc);
603
604 // add the trailing kernels
605 construct_and_accumulate_trailing_kernels(ivc);
606
607 // We expect the Chonk proof to fail due to the app with a failed UH recursive verification
608 auto proof = ivc->prove();
609 {
610 ChonkNativeVerifier verifier(ivc->get_hiding_kernel_vk_and_hash());
611 EXPECT_FALSE(verifier.verify(proof));
612 }
613}
614
619{
621 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
622
623 // Mock the post-app accumulation state (OINK proof ready to be verified)
624 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::OINK, /*is_kernel=*/false);
625
626 // Construct kernel program with gate counting enabled
627 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
628 ProgramMetadata metadata{ .ivc = ivc, .collect_gates_per_opcode = true };
629
630 auto kernel = acir_format::create_circuit<Builder>(program, metadata);
631
632 // Verify the gate count was recorded
633 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 1);
634
635 // Assert gate count
637
638 // Assert ECC row count
639 size_t actual_ecc_rows = kernel.op_queue->get_num_rows();
640 EXPECT_EQ(actual_ecc_rows, INIT_KERNEL_ECC_ROWS);
641
642 // Assert ultra ops count
643 size_t actual_ultra_ops = kernel.op_queue->get_current_subtable_size();
644 EXPECT_EQ(actual_ultra_ops, INIT_KERNEL_ULTRA_OPS);
645}
646
651{
653 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/4);
654
655 // Mock the state where we need to verify a previous kernel (HN) and a new app (HN)
656 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/true);
657 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/false);
658
659 // Construct kernel program with gate counting enabled
660 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
661 ProgramMetadata metadata{ .ivc = ivc, .collect_gates_per_opcode = true };
662
663 auto kernel = acir_format::create_circuit<Builder>(program, metadata);
664
665 // Verify the gate count was recorded
666 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 2);
667
668 // Assert gate counts (HN verification + OINK verification)
670
671 // Assert ECC row count
672 size_t actual_ecc_rows = kernel.op_queue->get_num_rows();
673 EXPECT_EQ(actual_ecc_rows, INNER_KERNEL_ECC_ROWS);
674
675 // Assert ultra ops count
676 size_t actual_ultra_ops = kernel.op_queue->get_current_subtable_size();
677 EXPECT_EQ(actual_ultra_ops, INNER_KERNEL_ULTRA_OPS);
678}
679
684{
686 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
687
688 // Mock the state where we need to verify a tail kernel proof
689 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN_TAIL, /*is_kernel=*/true);
690
691 // Construct kernel program with gate counting enabled
692 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
693 ProgramMetadata metadata{ .ivc = ivc, .collect_gates_per_opcode = true };
694
695 auto kernel = acir_format::create_circuit<Builder>(program, metadata);
696
697 // Verify the gate count was recorded
698 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 1);
699
700 // Assert gate count
702
703 // Assert ECC row count
704 size_t actual_ecc_rows = kernel.op_queue->get_num_rows();
705 EXPECT_EQ(actual_ecc_rows, TAIL_KERNEL_ECC_ROWS);
706
707 // Assert ultra ops count
708 size_t actual_ultra_ops = kernel.op_queue->get_current_subtable_size();
709 EXPECT_EQ(actual_ultra_ops, TAIL_KERNEL_ULTRA_OPS);
710}
711
716{
718 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
719
720 // Mock the state where we need to verify a hiding kernel proof
721 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN_FINAL, /*is_kernel=*/true);
722
723 // Construct kernel program with gate counting enabled
724 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
725 ProgramMetadata metadata{ .ivc = ivc, .collect_gates_per_opcode = true };
726
727 auto kernel = acir_format::create_circuit<Builder>(program, metadata);
728
729 // Verify the gate count was recorded
730 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 1);
731
732 // Assert gate count
734
735 // Assert ECC row count
736 size_t actual_ecc_rows = kernel.op_queue->get_num_rows();
737 EXPECT_EQ(actual_ecc_rows, HIDING_KERNEL_ECC_ROWS);
738
739 // Assert ultra ops count
740 size_t actual_ultra_ops = kernel.op_queue->get_current_subtable_size();
741 EXPECT_EQ(actual_ultra_ops, HIDING_KERNEL_ULTRA_OPS);
742}
#define BB_DISABLE_ASSERTS()
Definition assert.hpp:33
Shared type definitions for the Barretenberg RPC API.
static void construct_and_accumulate_mock_app(std::shared_ptr< Chonk > ivc)
static void construct_and_accumulate_mock_kernel(std::shared_ptr< Chonk > ivc)
static UltraCircuitBuilder create_inner_circuit(size_t log_num_gates=10)
static AcirProgram construct_mock_kernel_program(const VerificationQueue &verification_queue)
Generate an acir program {constraints, witness} for a mock kernel.
static void construct_and_accumulate_trailing_kernels(const std::shared_ptr< Chonk > &ivc)
static std::shared_ptr< Chonk::MegaVerificationKey > construct_kernel_vk_from_acir_program(AcirProgram &program)
Construct a kernel circuit VK from an acir program with IVC recursion constraints.
static std::shared_ptr< Chonk::MegaVerificationKey > get_kernel_vk_from_circuit(Builder &kernel)
static Builder construct_mock_app_circuit(const std::shared_ptr< Chonk > &ivc)
Constuct a simple arbitrary circuit to represent a mock app circuit.
static std::shared_ptr< VerificationKey > get_verification_key(Builder &builder_in)
static Builder construct_mock_UH_recursion_app_circuit(const std::shared_ptr< Chonk > &ivc, const bool tamper_vk)
Constuct a mock app circuit with a UH recursive verifier.
static RecursionConstraint create_recursion_constraint(const VerifierInputs &input, std::vector< FF > &witness)
Create an ACIR RecursionConstraint given the corresponding verifier inputs.
QUEUE_TYPE
Proof type determining recursive verification logic in kernel circuits.
Definition chonk.hpp:105
std::deque< VerifierInputs > VerificationQueue
Definition chonk.hpp:114
stdlib::recursion::PairingPoints< stdlib::bn254< ClientCircuit > > PairingPoints
Definition chonk.hpp:65
Verifier for Chonk IVC proofs (both native and recursive).
Output verify(const Proof &proof)
Verify a Chonk proof.
MergeProver::MergeProof MergeProof
Definition goblin.hpp:34
static void add_some_ecc_op_gates(MegaBuilder &builder)
Generate a simple test circuit with some ECC op gates and conventional arithmetic gates.
std::shared_ptr< ECCOpQueue > op_queue
Curve::ScalarField FF
NativeVerificationKey_< PrecomputedEntities< Commitment >, Codec, HashFunction, CommitmentKey > VerificationKey
The verification key is responsible for storing the commitments to the precomputed (non-witness) poly...
static void add_arithmetic_gates(Builder &builder, const size_t num_gates=4)
Add a specified number of arithmetic gates to the provided circuit.
Base Native verification key class.
Definition flavor.hpp:141
The recursive counterpart to the "native" Ultra flavor.
Output verify_proof(const Proof &proof)
Perform ultra verification.
static constexpr element one
Definition group.hpp:46
A simple wrapper around a vector of stdlib field elements representing a proof.
Definition proof.hpp:19
Manages the data that is propagated on the public inputs of an application/function circuit.
static void add_default(Builder &builder)
Add default public inputs when they are not present.
AluTraceBuilder builder
Definition alu.test.cpp:124
FF a
FF b
AvmProvingInputs inputs
constexpr size_t INIT_KERNEL_ECC_ROWS
constexpr size_t HIDING_KERNEL_ULTRA_OPS
Goblin::MergeProof create_mock_merge_proof()
Create a mock merge proof which has the correct structure but is not necessarily valid.
RecursionConstraint recursion_data_to_recursion_constraint(std::vector< bb::fr > &witness, const std::vector< bb::fr > &proof, const std::vector< bb::fr > &key, const bb::fr &key_hash, const bb::fr &predicate, const size_t num_public_inputs_to_extract, const uint32_t proof_type)
========== TESTING UTILITIES ========== ///
Definition utils.cpp:53
constexpr size_t HIDING_KERNEL_ECC_ROWS
constexpr size_t TAIL_KERNEL_GATE_COUNT
constexpr size_t TAIL_KERNEL_ULTRA_OPS
constexpr size_t INIT_KERNEL_GATE_COUNT
constexpr size_t INIT_KERNEL_ULTRA_OPS
constexpr size_t INNER_KERNEL_GATE_COUNT_HN
constexpr size_t TAIL_KERNEL_ECC_ROWS
constexpr size_t INNER_KERNEL_ULTRA_OPS
constexpr size_t HIDING_KERNEL_GATE_COUNT
constexpr size_t INNER_KERNEL_ECC_ROWS
void mock_chonk_accumulation(const std::shared_ptr< Chonk > &ivc, Chonk::QUEUE_TYPE type, const bool is_kernel)
Populate an IVC instance with data that mimics the state after a single IVC accumulation.
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
TEST_F(BoomerangGoblinRecursiveVerifierTests, graph_description_basic)
Construct and check a goblin recursive verification circuit.
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
field< Bn254FrParams > fr
Definition fr.hpp:174
MegaCircuitBuilder_< field< Bn254FrParams > > MegaCircuitBuilder
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
AcirFormatOriginalOpcodeIndices original_opcode_indices
std::vector< RecursionConstraint > hn_recursion_constraints
std::vector< size_t > gates_per_opcode
Indices of the original opcode that originated each constraint in AcirFormat.
Struct containing both the constraints to be added to the circuit and the witness vector.
Metadata required to create a circuit.
std::shared_ptr< bb::IVCBase > ivc
RecursionConstraint struct contains information required to recursively verify a proof.
std::shared_ptr< MegaVerificationKey > honk_vk
Definition chonk.hpp:110
std::vector< FF > proof
Definition chonk.hpp:109
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()
An object storing two EC points that represent the inputs to a pairing check.
Output type for recursive ultra verification.