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"
13#include "proof_surgeon.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 UltraVerifier_<UltraFlavor> verifier(honk_vk);
137 EXPECT_FALSE(verifier.template verify_proof<DefaultIO>(inner_proof).result);
138 }
139 // Instantiate the recursive verifier using the native verification key
140 auto stdlib_vk_and_hash = std::make_shared<RecursiveFlavor::VKAndHash>(circuit, honk_vk);
141 stdlib::recursion::honk::UltraRecursiveVerifier_<RecursiveFlavor> verifier(&circuit, stdlib_vk_and_hash);
142
143 StdlibProof stdlib_inner_proof(circuit, inner_proof);
144 VerifierOutput output = verifier.template verify_proof<StdlibIO>(stdlib_inner_proof);
145
146 // IO
147 StdlibIO inputs;
148 inputs.pairing_inputs = output.points_accumulator;
149 inputs.set_public(); // propagate resulting pairing points on the public inputs
150 }
151
152 return circuit;
153 }
154
163 static RecursionConstraint create_recursion_constraint(const VerifierInputs& input, std::vector<FF>& witness)
164 {
165 // Assemble simple vectors of witnesses for vkey and proof
166 std::vector<FF> key_witnesses = input.honk_vk->to_field_elements();
167 FF key_hash_witness = input.honk_vk->hash();
168 std::vector<FF> proof_witnesses = input.proof; // proof contains the public inputs at this stage
169
170 // Construct witness indices for each component in the constraint; populate the witness array
171 auto [key_indices, key_hash_index, proof_indices, public_inputs_indices] =
173 witness, proof_witnesses, key_witnesses, key_hash_witness, /*num_public_inputs_to_extract=*/0);
174
175 // The proof type can be either Oink or HN or PG_FINAL
176 PROOF_TYPE proof_type;
177 switch (input.type) {
178 case QUEUE_TYPE::OINK:
179 proof_type = OINK;
180 break;
181 case QUEUE_TYPE::HN:
182 proof_type = HN;
183 break;
184 case QUEUE_TYPE::HN_FINAL:
185 proof_type = HN_FINAL;
186 break;
187 case QUEUE_TYPE::HN_TAIL:
188 proof_type = HN_TAIL;
189 break;
190 default:
191 throw std::runtime_error("Invalid proof type");
192 }
193
194 return RecursionConstraint{
195 .key = key_indices,
196 .proof = {}, // the proof witness indices are not needed in an ivc recursion constraint
197 .public_inputs = public_inputs_indices,
198 .key_hash = key_hash_index,
199 .proof_type = proof_type,
200 };
201 }
202
217 {
218 AcirProgram program;
219
220 // Construct recursion constraints based on the ivc verification queue; populate the witness along the way
221 std::vector<RecursionConstraint> hn_recursion_constraints;
222 hn_recursion_constraints.reserve(verification_queue.size());
223 for (const auto& queue_entry : verification_queue) {
224 hn_recursion_constraints.push_back(create_recursion_constraint(queue_entry, program.witness));
225 }
226
227 // Construct a constraint system containing the business logic and ivc recursion constraints
228 program.constraints.max_witness_index = static_cast<uint32_t>(program.witness.size() - 1);
229 program.constraints.num_acir_opcodes = static_cast<uint32_t>(hn_recursion_constraints.size());
230 program.constraints.hn_recursion_constraints = hn_recursion_constraints;
233
234 return program;
235 }
236
238 {
239 // construct a mock kernel program (acir) from the ivc verification queue
240 const ProgramMetadata metadata{ ivc };
241 AcirProgram mock_kernel_program = construct_mock_kernel_program(ivc->verification_queue);
242 auto kernel = acir_format::create_circuit<Builder>(mock_kernel_program, metadata);
243 auto kernel_vk = get_kernel_vk_from_circuit(kernel);
244 ivc->accumulate(kernel, kernel_vk);
245 }
246
248 {
249 // construct a mock kernel program (acir) from the ivc verification queue
250 auto app_circuit = construct_mock_app_circuit(ivc);
251 ivc->accumulate(app_circuit, get_verification_key(app_circuit));
252 }
253
261 {
262 // Create kernel circuit from the kernel program
263 auto kernel = acir_format::create_circuit<Builder>(program);
264
265 // Manually construct the VK for the kernel circuit
266 auto prover_instance = std::make_shared<Chonk::ProverInstance>(kernel);
267 auto verification_key = std::make_shared<Chonk::MegaVerificationKey>(prover_instance->get_precomputed());
268 return verification_key;
269 }
270
272 {
273 auto prover_instance = std::make_shared<Chonk::ProverInstance>(kernel);
274 auto verification_key = std::make_shared<Chonk::MegaVerificationKey>(prover_instance->get_precomputed());
275 return verification_key;
276 }
277
278 protected:
280};
281
286{
288 EXPECT_EQ(merge_proof.size(), MERGE_PROOF_SIZE);
289}
290
296{
297 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5 /* app, kernel, reset, tail, hiding */);
298
299 // construct a mock app_circuit
300 construct_and_accumulate_mock_app(ivc);
301
302 // Construct kernel consisting only of the kernel completion logic
303 construct_and_accumulate_mock_kernel(ivc);
304
305 // add the trailing kernels
306 construct_and_accumulate_trailing_kernels(ivc);
307
308 auto proof = ivc->prove();
309 EXPECT_TRUE(Chonk::verify(proof, ivc->get_vk()));
310}
311
317{
318 // 4 ciruits and the tail kernel
319 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/7);
320
321 // construct a mock app_circuit
322 construct_and_accumulate_mock_app(ivc);
323
324 const ProgramMetadata metadata{ ivc };
325
326 // Construct kernel_0; consists of a single oink recursive verification for app (plus databus/merge logic)
327 construct_and_accumulate_mock_kernel(ivc);
328
329 // construct a mock app_circuit
330 construct_and_accumulate_mock_app(ivc);
331
332 // Construct and accumulate another Kernel circuit
333 construct_and_accumulate_mock_kernel(ivc);
334
335 // Accumulate the trailing kernels
336 construct_and_accumulate_trailing_kernels(ivc);
337
338 auto proof = ivc->prove();
339 EXPECT_TRUE(Chonk::verify(proof, ivc->get_vk()));
340}
341
342// Test generation of "init" kernel VK via dummy IVC data
343TEST_F(HypernovaRecursionConstraintTest, GenerateInitKernelVKFromConstraints)
344{
346 // First, construct the kernel VK by running the full IVC (accumulate one app and one kernel)
348 {
349 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
350
351 // Construct and accumulate mock app_circuit
352 construct_and_accumulate_mock_app(ivc);
353
354 // Construct and accumulate kernel consisting only of the kernel completion logic
355 construct_and_accumulate_mock_kernel(ivc);
356 expected_kernel_vk = ivc->verification_queue.back().honk_vk;
357 }
358
359 // Now, construct the kernel VK by mocking the post app accumulation state of the IVC
361 {
362 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
363
364 // Construct kernel consisting only of the kernel completion logic
365 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::OINK, /*is_kernel=*/false);
366 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
367 program.witness = {}; // remove the witness to mimick VK construction context
368
369 kernel_vk = construct_kernel_vk_from_acir_program(program);
370 }
371
372 // Compare the VK constructed via running the IVc with the one constructed via mocking
373 EXPECT_EQ(*kernel_vk.get(), *expected_kernel_vk.get());
374}
375
376// Test generation of "reset" kernel VK via dummy IVC data
377TEST_F(HypernovaRecursionConstraintTest, GenerateResetKernelVKFromConstraints)
378{
380 // First, construct the kernel VK by running the full IVC (accumulate one app and one kernel)
382 {
383 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
384
385 const ProgramMetadata metadata{ ivc };
386
387 // Construct and accumulate mock app_circuit
388 construct_and_accumulate_mock_app(ivc);
389
390 // Construct and accumulate a mock INIT kernel (oink recursion for app accumulation)
391 construct_and_accumulate_mock_kernel(ivc);
392 EXPECT_TRUE(ivc->verification_queue.size() == 1);
393 EXPECT_TRUE(ivc->verification_queue[0].type == bb::Chonk::QUEUE_TYPE::HN);
394
395 // Construct and accumulate a mock RESET kernel (HN recursion for kernel accumulation)
396 construct_and_accumulate_mock_kernel(ivc);
397 expected_kernel_vk = ivc->verification_queue.back().honk_vk;
398 }
399
400 // Now, construct the kernel VK by mocking the IVC state prior to kernel construction
402 {
403 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
404
405 // Construct kernel consisting only of the kernel completion logic
406 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/true);
407 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
408 program.witness = {}; // remove the witness to mimick VK construction context
409 kernel_vk = construct_kernel_vk_from_acir_program(program);
410 }
411
412 // Compare the VK constructed via running the IVc with the one constructed via mocking
413 EXPECT_EQ(*kernel_vk.get(), *expected_kernel_vk.get());
414}
415
416// Test generation of "tail" kernel VK via dummy IVC data
417TEST_F(HypernovaRecursionConstraintTest, GenerateTailKernelVKFromConstraints)
418{
420 // First, construct the kernel VK by running the full IVC (accumulate one app and one kernel)
422 {
423 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
424
425 const ProgramMetadata metadata{ ivc };
426
427 // Construct and accumulate mock app_circuit
428 construct_and_accumulate_mock_app(ivc);
429
430 // Construct and accumulate a mock INIT kernel (oink recursion for app accumulation)
431 construct_and_accumulate_mock_kernel(ivc);
432
433 // Construct and accumulate a mock RESET kernel (HN recursion for kernel accumulation)
434 construct_and_accumulate_mock_kernel(ivc);
435
436 // Construct and accumulate a mock TAIL kernel (HN recursion for kernel accumulation)
437 EXPECT_TRUE(ivc->verification_queue.size() == 1);
438 EXPECT_TRUE(ivc->verification_queue[0].type == bb::Chonk::QUEUE_TYPE::HN_TAIL);
439 construct_and_accumulate_mock_kernel(ivc);
440
441 expected_kernel_vk = ivc->verification_queue.back().honk_vk;
442 }
443
444 // Now, construct the kernel VK by mocking the IVC state prior to kernel construction
446 {
447 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
448
449 // Construct kernel consisting only of the kernel completion logic
450 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN_TAIL, /*is_kernel=*/true);
451 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
452 program.witness = {}; // remove the witness to mimick VK construction context
453
454 kernel_vk = construct_kernel_vk_from_acir_program(program);
455 }
456
457 // Compare the VK constructed via running the IVc with the one constructed via mocking
458 EXPECT_EQ(*kernel_vk.get(), *expected_kernel_vk.get());
459}
460
461// Test generation of "inner" kernel VK via dummy IVC data
462TEST_F(HypernovaRecursionConstraintTest, GenerateInnerKernelVKFromConstraints)
463{
465 // First, construct the kernel VK by running the full IVC (accumulate one app and one kernel)
467 {
468 // we have to set the number of circuits one more than the number of circuits we're accumulating as otherwise
469 // the last circuit will be seen as a tail
470 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/6);
471
472 const ProgramMetadata metadata{ ivc };
473
474 { // Construct and accumulate mock app_circuit
475 construct_and_accumulate_mock_app(ivc);
476 }
477
478 // Construct and accumulate a mock INIT kernel (oink recursion for app accumulation)
479 construct_and_accumulate_mock_kernel(ivc);
480
481 { // Construct and accumulate a second mock app_circuit
482 construct_and_accumulate_mock_app(ivc);
483 }
484
485 { // Construct and accumulate a mock INNER kernel (HN recursion for kernel accumulation)
486 EXPECT_TRUE(ivc->verification_queue.size() == 2);
487 EXPECT_TRUE(ivc->verification_queue[1].type == bb::Chonk::QUEUE_TYPE::HN);
488 construct_and_accumulate_mock_kernel(ivc);
489 }
490
491 expected_kernel_vk = ivc->verification_queue.back().honk_vk;
492 }
493
494 // Now, construct the kernel VK by mocking the IVC state prior to kernel construction
496 {
497 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/4);
498
499 // Construct kernel consisting only of the kernel completion logic
500 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/true);
501 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/false);
502 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
503 program.witness = {}; // remove the witness to mimick VK construction context
504
505 kernel_vk = construct_kernel_vk_from_acir_program(program);
506 }
507
508 // Compare the VK constructed via running the IVc with the one constructed via mocking
509 EXPECT_EQ(*kernel_vk.get(), *expected_kernel_vk.get());
510}
511
512// Test generation of "hiding" kernel VK via dummy IVC data
513TEST_F(HypernovaRecursionConstraintTest, GenerateHidingKernelVKFromConstraints)
514{
516 // First, construct the kernel VK by running the full IVC
517 std::shared_ptr<MegaFlavor::VerificationKey> expected_hiding_kernel_vk;
518 {
519 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
520 const ProgramMetadata metadata{ ivc };
521
522 {
523 // Construct and accumulate mock app_circuit
524 construct_and_accumulate_mock_app(ivc);
525 }
526
527 {
528 // Construct and accumulate a mock INIT kernel (oink recursion for app accumulation)
529 construct_and_accumulate_mock_kernel(ivc);
530 }
531
532 construct_and_accumulate_trailing_kernels(ivc);
533
534 // The single entry in the verification queue corresponds to the hiding kernel
535 expected_hiding_kernel_vk = ivc->verification_queue[0].honk_vk;
536 }
537
538 // Now, construct the kernel VK by mocking the IVC state prior to kernel construction
540 {
541 // mock IVC accumulation increases the num_circuits_accumualted, hence we need to assume the tail kernel has
542 // been accumulated
543 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
544 // construct a mock tail kernel
546 Chonk::QUEUE_TYPE::HN_FINAL,
547 /*is_kernel=*/true);
548 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
549 program.witness = {}; // remove the witness to mimick VK construction context
550 kernel_vk = construct_kernel_vk_from_acir_program(program);
551 }
552
553 // Compare the VK constructed via running the IVc with the one constructed via mocking
554 EXPECT_EQ(*kernel_vk.get(), *expected_hiding_kernel_vk.get());
555}
556
560TEST_F(HypernovaRecursionConstraintTest, RecursiveVerifierAppCircuit)
561{
562 auto ivc = std::make_shared<Chonk>(/*num_circuits*/ 5);
563
564 // construct a mock app_circuit with an UH recursion call
565 Builder app_circuit = construct_mock_UH_recursion_app_circuit(ivc, /*tamper_vk=*/false);
566
567 // Complete instance and generate an oink proof
568 ivc->accumulate(app_circuit, get_verification_key(app_circuit));
569
570 // Construct kernel consisting only of the kernel completion logic
571 construct_and_accumulate_mock_kernel(ivc);
572
573 construct_and_accumulate_trailing_kernels(ivc);
574
575 auto proof = ivc->prove();
576 EXPECT_TRUE(Chonk::verify(proof, ivc->get_vk()));
577}
578
583TEST_F(HypernovaRecursionConstraintTest, RecursiveVerifierAppCircuitFailure)
584{
585 BB_DISABLE_ASSERTS(); // Disable assert in HN prover
586
587 auto ivc = std::make_shared<Chonk>(/*num_circuits*/ 5);
588
589 // construct and accumulate mock app_circuit that has bad pairing point object
590 Builder app_circuit = construct_mock_UH_recursion_app_circuit(ivc, /*tamper_vk=*/true);
591 ivc->accumulate(app_circuit, get_verification_key(app_circuit));
592
593 // Construct kernel consisting only of the kernel completion logic
594 construct_and_accumulate_mock_kernel(ivc);
595
596 // add the trailing kernels
597 construct_and_accumulate_trailing_kernels(ivc);
598
599 // We expect the Chonk proof to fail due to the app with a failed UH recursive verification
600 auto proof = ivc->prove();
601 EXPECT_FALSE(Chonk::verify(proof, ivc->get_vk()));
602}
603
608{
610 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
611
612 // Mock the post-app accumulation state (OINK proof ready to be verified)
613 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::OINK, /*is_kernel=*/false);
614
615 // Construct kernel program with gate counting enabled
616 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
617 ProgramMetadata metadata{ .ivc = ivc, .collect_gates_per_opcode = true };
618
619 auto kernel = acir_format::create_circuit<Builder>(program, metadata);
620
621 // Verify the gate count was recorded
622 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 1);
623
624 // Assert gate count
626
627 // Assert ECC row count
628 size_t actual_ecc_rows = kernel.op_queue->get_num_rows();
629 EXPECT_EQ(actual_ecc_rows, INIT_KERNEL_ECC_ROWS);
630
631 // Assert ultra ops count
632 size_t actual_ultra_ops = kernel.op_queue->get_current_subtable_size();
633 EXPECT_EQ(actual_ultra_ops, INIT_KERNEL_ULTRA_OPS);
634}
635
640{
642 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/4);
643
644 // Mock the state where we need to verify a previous kernel (HN) and a new app (HN)
645 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/true);
646 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN, /*is_kernel=*/false);
647
648 // Construct kernel program with gate counting enabled
649 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
650 ProgramMetadata metadata{ .ivc = ivc, .collect_gates_per_opcode = true };
651
652 auto kernel = acir_format::create_circuit<Builder>(program, metadata);
653
654 // Verify the gate count was recorded
655 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 2);
656
657 // Assert gate counts (HN verification + OINK verification)
659
660 // Assert ECC row count
661 size_t actual_ecc_rows = kernel.op_queue->get_num_rows();
662 EXPECT_EQ(actual_ecc_rows, INNER_KERNEL_ECC_ROWS);
663
664 // Assert ultra ops count
665 size_t actual_ultra_ops = kernel.op_queue->get_current_subtable_size();
666 EXPECT_EQ(actual_ultra_ops, INNER_KERNEL_ULTRA_OPS);
667}
668
673{
675 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
676
677 // Mock the state where we need to verify a tail kernel proof
678 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN_TAIL, /*is_kernel=*/true);
679
680 // Construct kernel program with gate counting enabled
681 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
682 ProgramMetadata metadata{ .ivc = ivc, .collect_gates_per_opcode = true };
683
684 auto kernel = acir_format::create_circuit<Builder>(program, metadata);
685
686 // Verify the gate count was recorded
687 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 1);
688
689 // Assert gate count
691
692 // Assert ECC row count
693 size_t actual_ecc_rows = kernel.op_queue->get_num_rows();
694 EXPECT_EQ(actual_ecc_rows, TAIL_KERNEL_ECC_ROWS);
695
696 // Assert ultra ops count
697 size_t actual_ultra_ops = kernel.op_queue->get_current_subtable_size();
698 EXPECT_EQ(actual_ultra_ops, TAIL_KERNEL_ULTRA_OPS);
699}
700
705{
707 auto ivc = std::make_shared<Chonk>(/*num_circuits=*/5);
708
709 // Mock the state where we need to verify a hiding kernel proof
710 acir_format::mock_chonk_accumulation(ivc, Chonk::QUEUE_TYPE::HN_FINAL, /*is_kernel=*/true);
711
712 // Construct kernel program with gate counting enabled
713 AcirProgram program = construct_mock_kernel_program(ivc->verification_queue);
714 ProgramMetadata metadata{ .ivc = ivc, .collect_gates_per_opcode = true };
715
716 auto kernel = acir_format::create_circuit<Builder>(program, metadata);
717
718 // Verify the gate count was recorded
719 EXPECT_EQ(program.constraints.gates_per_opcode.size(), 1);
720
721 // Assert gate count
723
724 // Assert ECC row count
725 size_t actual_ecc_rows = kernel.op_queue->get_num_rows();
726 EXPECT_EQ(actual_ecc_rows, HIDING_KERNEL_ECC_ROWS);
727
728 // Assert ultra ops count
729 size_t actual_ultra_ops = kernel.op_queue->get_current_subtable_size();
730 EXPECT_EQ(actual_ultra_ops, HIDING_KERNEL_ULTRA_OPS);
731}
acir_format::AcirFormatOriginalOpcodeIndices create_empty_original_opcode_indices()
void mock_opcode_indices(acir_format::AcirFormat &constraint_system)
#define BB_DISABLE_ASSERTS()
Definition assert.hpp:32
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.
static RecursionWitnessData populate_recursion_witness_data(std::vector< FF > &witness, std::vector< FF > &proof_witnesses, const std::vector< FF > &key_witnesses, const FF &key_hash_witness, const size_t num_public_inputs_to_extract)
Populate a witness vector with key, proof, and public inputs; track witness indices for each componen...
std::deque< VerifierInputs > VerificationQueue
Definition chonk.hpp:240
static bool verify(const Proof &proof, const VerificationKey &vk)
Definition chonk.cpp:528
stdlib::recursion::PairingPoints< stdlib::bn254< ClientCircuit > > PairingPoints
Definition chonk.hpp:66
MergeProver::MergeProof MergeProof
Definition goblin.hpp:35
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
The verification key is responsible for storing the commitments to the precomputed (non-witness) poly...
Curve::ScalarField FF
static void add_arithmetic_gates(Builder &builder, const size_t num_gates=4)
Add a specified number of arithmetic gates to the provided circuit.
The recursive counterpart to the "native" Ultra flavor.
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.
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
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:236
std::vector< FF > proof
Definition chonk.hpp:235
static field random_element(numeric::RNG *engine=nullptr) noexcept
An object storing two EC points that represent the inputs to a pairing check.