15#include <gtest/gtest.h>
48 using VK =
typename FlavorT::VerificationKey;
58 EXPECT_EQ(ivc->verification_queue.size(), 1);
59 EXPECT_EQ(ivc->verification_queue[0].kind, CircuitKind::Kernel);
63 EXPECT_EQ(ivc->verification_queue.size(), 1);
64 EXPECT_EQ(ivc->verification_queue[0].kind, CircuitKind::Kernel);
73 const size_t num_gates = (1 << log_num_gates);
74 for (
size_t i = 0; i < num_gates; ++i) {
76 uint32_t a_idx =
builder.add_variable(
a);
81 uint32_t b_idx =
builder.add_variable(
b);
82 uint32_t c_idx =
builder.add_variable(c);
83 uint32_t d_idx =
builder.add_variable(d);
85 builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx,
fr(1),
fr(1),
fr(1),
fr(-1),
fr(0) });
124 EXPECT_FALSE(verifier.
verify_proof(inner_proof).result);
130 StdlibProof stdlib_inner_proof(circuit, inner_proof);
131 VerifierOutput output = verifier.
verify_proof(stdlib_inner_proof);
135 inputs.pairing_inputs = output.points_accumulator;
152 std::vector<FF>& witness)
165 constraint.
proof = {};
179 constraints.reserve(proof_types.size());
183 constraints.push_back(constraint);
208 const auto& verification_queue = ivc->verification_queue;
209 const bool is_init = !verification_queue.empty() && verification_queue.front().kind == CircuitKind::App;
210 const bool is_hiding = ivc->is_hiding_kernel();
214 hn_recursion_constraints.reserve(verification_queue.size());
215 for (
size_t idx = 0; idx < verification_queue.size(); ++idx) {
219 verification_queue.size(), 1U,
"The hiding kernel should recursively verify only one proof.");
220 proof_type = PROOF_TYPE::HN_FINAL;
221 }
else if (is_init && idx == 0) {
222 proof_type = PROOF_TYPE::OINK;
224 proof_type = PROOF_TYPE::HN;
226 hn_recursion_constraints.push_back(
234 for (
size_t idx = 0; idx < hn_recursion_constraints.size(); ++idx) {
247 auto kernel = acir_format::create_circuit<Builder>(mock_kernel_program, metadata);
250 using FlavorT = flavor_for<K>;
251 using VK = typename FlavorT::VerificationKey;
252 return Chonk::CircuitVerificationKey{ std::make_shared<VK>(
253 ProverInstance_<FlavorT>(kernel).get_precomputed()) };
255 ivc->accumulate(kernel,
vk);
261 auto app_circuit = construct_mock_app_circuit(ivc);
262 ivc->accumulate(app_circuit, make_circuit_vk(app_circuit, ivc->current_kind()));
271 auto kernel = acir_format::create_circuit<Builder>(program);
289 proof_types.front() = PROOF_TYPE::OINK;
303 AcirProgram program = construct_mock_kernel_program(ivc);
305 return construct_kernel_vk_from_acir_program(program);
312 AcirProgram program = construct_mock_kernel_program(ivc);
314 auto kernel = acir_format::create_circuit<Builder>(program);
330 AcirProgram program = construct_mock_kernel_program(ivc);
332 auto kernel = acir_format::create_circuit<Builder>(program, metadata);
335 kernel.op_queue->get_num_rows(),
336 kernel.op_queue->get_current_subtable_size() };
342 std::vector<CircuitKind> kinds(num_apps, CircuitKind::App);
343 kinds.push_back(CircuitKind::Kernel);
344 kinds.push_back(CircuitKind::Kernel);
345 kinds.push_back(CircuitKind::HidingKernel);
347 for (
size_t i = 0; i < num_apps; ++i) {
348 construct_and_accumulate_mock_app(ivc);
350 construct_and_accumulate_mock_kernel(ivc);
351 return ivc->verification_queue.back().kernel_honk_vk;
357 std::vector<CircuitKind> kinds = { CircuitKind::App, CircuitKind::Kernel };
358 kinds.insert(kinds.end(), num_apps, CircuitKind::App);
359 kinds.push_back(CircuitKind::Kernel);
360 kinds.push_back(CircuitKind::Kernel);
361 kinds.push_back(CircuitKind::HidingKernel);
363 construct_and_accumulate_mock_app(ivc);
364 construct_and_accumulate_mock_kernel(ivc);
365 for (
size_t i = 0; i < num_apps; ++i) {
366 construct_and_accumulate_mock_app(ivc);
368 construct_and_accumulate_mock_kernel(ivc);
369 return ivc->verification_queue.back().kernel_honk_vk;
379 CircuitKind::HidingKernel });
380 construct_and_accumulate_mock_app(ivc);
381 construct_and_accumulate_mock_kernel(ivc);
382 construct_and_accumulate_mock_kernel(ivc);
383 return ivc->verification_queue.back().kernel_honk_vk;
390 CircuitKind::App, CircuitKind::Kernel, CircuitKind::Kernel, CircuitKind::HidingKernel });
391 construct_and_accumulate_mock_app(ivc);
392 construct_and_accumulate_mock_kernel(ivc);
393 construct_and_accumulate_trailing_kernels(ivc);
394 return ivc->hiding_vk;
407 EXPECT_EQ(merge_proof.size(), MERGE_PROOF_SIZE);
417 CircuitKind::App, CircuitKind::Kernel, CircuitKind::Kernel, CircuitKind::HidingKernel });
420 construct_and_accumulate_mock_app(ivc);
423 construct_and_accumulate_mock_kernel(ivc);
426 construct_and_accumulate_trailing_kernels(ivc);
428 auto proof = ivc->prove();
430 auto vk_and_hash = ivc->get_hiding_kernel_vk_and_hash();
432 EXPECT_TRUE(verifier.
verify(proof));
448 CircuitKind::HidingKernel });
451 construct_and_accumulate_mock_app(ivc);
456 construct_and_accumulate_mock_kernel(ivc);
459 construct_and_accumulate_mock_app(ivc);
462 construct_and_accumulate_mock_kernel(ivc);
465 construct_and_accumulate_trailing_kernels(ivc);
467 auto proof = ivc->prove();
470 EXPECT_TRUE(verifier.
verify(proof));
479 for (
size_t num_apps = 1; num_apps <= MAX_APPS_PER_KERNEL; ++num_apps) {
480 auto expected_kernel_vk = real_init_kernel_vk(num_apps);
481 auto kernel_vk = mock_kernel_vk(init_kernel_proof_types(num_apps));
482 EXPECT_EQ(*kernel_vk, *expected_kernel_vk) <<
"init kernel VK mismatch for " << num_apps <<
" app(s)";
490 for (
size_t num_apps = 1; num_apps <= MAX_APPS_PER_KERNEL; ++num_apps) {
491 auto expected_kernel_vk = real_inner_kernel_vk(num_apps);
492 auto kernel_vk = mock_kernel_vk(inner_kernel_proof_types(num_apps));
493 EXPECT_EQ(*kernel_vk, *expected_kernel_vk) <<
"inner kernel VK mismatch for " << num_apps <<
" app(s)";
501 auto expected_kernel_vk = real_reset_tail_kernel_vk();
502 auto kernel_vk = mock_kernel_vk({ PROOF_TYPE::HN });
503 EXPECT_EQ(*kernel_vk, *expected_kernel_vk);
510 auto expected_hiding_kernel_vk = real_hiding_kernel_vk();
511 auto kernel_vk = mock_hiding_kernel_vk();
512 EXPECT_EQ(*kernel_vk, *expected_hiding_kernel_vk);
521 CircuitKind::App, CircuitKind::Kernel, CircuitKind::Kernel, CircuitKind::HidingKernel });
524 Builder app_circuit = construct_mock_UH_recursion_app_circuit(ivc,
false);
528 ivc->accumulate(app_circuit, make_circuit_vk(app_circuit, ivc->current_kind()));
532 construct_and_accumulate_mock_kernel(ivc);
534 construct_and_accumulate_trailing_kernels(ivc);
536 auto proof = ivc->prove();
539 EXPECT_TRUE(verifier.
verify(proof));
552 CircuitKind::App, CircuitKind::Kernel, CircuitKind::Kernel, CircuitKind::HidingKernel });
555 Builder app_circuit = construct_mock_UH_recursion_app_circuit(ivc,
true);
557 ivc->accumulate(app_circuit, make_circuit_vk(app_circuit, ivc->current_kind()));
561 construct_and_accumulate_mock_kernel(ivc);
564 construct_and_accumulate_trailing_kernels(ivc);
567 auto proof = ivc->prove();
570 EXPECT_FALSE(verifier.
verify(proof));
580 for (
size_t num_apps = 1; num_apps <= MAX_APPS_PER_KERNEL; ++num_apps) {
581 auto counts = mock_kernel_gate_counts(init_kernel_proof_types(num_apps));
582 EXPECT_EQ(counts.num_opcodes, num_apps) <<
"init kernel, " << num_apps <<
" app(s)";
583 EXPECT_EQ(counts.gate_count,
INIT_KERNEL_GATE_COUNT[num_apps - 1]) <<
"init kernel, " << num_apps <<
" app(s)";
585 <<
"init kernel, " << num_apps <<
" app(s)";
586 EXPECT_EQ(counts.ultra_ops,
INIT_KERNEL_ULTRA_OPS[num_apps - 1]) <<
"init kernel, " << num_apps <<
" app(s)";
597 for (
size_t num_apps = 1; num_apps <= MAX_APPS_PER_KERNEL; ++num_apps) {
598 auto counts = mock_kernel_gate_counts(inner_kernel_proof_types(num_apps));
599 EXPECT_EQ(counts.num_opcodes, num_apps + 1) <<
"inner kernel, " << num_apps <<
" app(s)";
601 <<
"inner kernel, " << num_apps <<
" app(s)";
603 <<
"inner kernel, " << num_apps <<
" app(s)";
604 EXPECT_EQ(counts.ultra_ops,
INNER_KERNEL_ULTRA_OPS[num_apps - 1]) <<
"inner kernel, " << num_apps <<
" app(s)";
614 auto counts = mock_kernel_gate_counts({ PROOF_TYPE::HN });
615 EXPECT_EQ(counts.num_opcodes, 1U);
628 auto counts = mock_kernel_gate_counts({ PROOF_TYPE::HN_FINAL });
629 EXPECT_EQ(counts.num_opcodes, 1U);
632 EXPECT_EQ(counts.ultra_ops, bb::HIDING_KERNEL_ULTRA_OPS);
646 AcirProgram program = construct_mock_kernel_program(ivc);
654 "hn_recursion_data constraints/indices size mismatch");
664 AcirProgram program = construct_mock_kernel_program(ivc);
673 "mismatch in number of recursive verifications");
683 AcirProgram program = construct_mock_kernel_program(ivc);
691 "unexpected non-empty public_inputs in HN constraint");
701 AcirProgram program = construct_mock_kernel_program(ivc);
710 "ACIR proof_type disagrees with circuit-kinds-derived state");
#define BB_ASSERT_NEQ(actual, expected,...)
#define BB_ASSERT_EQ(actual, expected,...)
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
#define BB_DISABLE_ASSERTS()
Shared type definitions for the Barretenberg RPC API.
static std::shared_ptr< Chonk::MegaZKVerificationKey > real_hiding_kernel_vk()
static void construct_and_accumulate_mock_app(std::shared_ptr< Chonk > ivc)
static std::shared_ptr< Chonk::KernelVerificationKey > real_inner_kernel_vk(size_t num_apps)
static std::shared_ptr< Chonk::KernelVerificationKey > 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::KernelVerificationKey > real_reset_tail_kernel_vk()
static void construct_and_accumulate_mock_kernel(std::shared_ptr< Chonk > ivc)
static std::vector< RecursionConstraint > make_hn_recursion_constraints(const std::vector< PROOF_TYPE > &proof_types)
Build a set of bare HN recursion constraints carrying only the given proof types.
static UltraCircuitBuilder create_inner_circuit(size_t log_num_gates=10)
static std::vector< PROOF_TYPE > init_kernel_proof_types(size_t num_apps)
static void construct_and_accumulate_trailing_kernels(const std::shared_ptr< Chonk > &ivc)
static KernelGateCounts mock_kernel_gate_counts(const std::vector< PROOF_TYPE > &proof_types)
static std::shared_ptr< Chonk::MegaZKVerificationKey > mock_hiding_kernel_vk()
static Chonk::CircuitVerificationKey make_circuit_vk(Builder &builder_in, CircuitKind kind)
static std::shared_ptr< Chonk::KernelVerificationKey > mock_kernel_vk(const std::vector< PROOF_TYPE > &proof_types)
static RecursionConstraint create_recursion_constraint(const VerifierInputs &input, PROOF_TYPE proof_type, std::vector< FF > &witness)
Create an ACIR RecursionConstraint given the corresponding verifier inputs.
static std::shared_ptr< Chonk::KernelVerificationKey > real_init_kernel_vk(size_t num_apps)
static Builder construct_mock_app_circuit(const std::shared_ptr< Chonk > &ivc)
Constuct a simple arbitrary circuit to represent a mock app circuit.
static AcirProgram construct_mock_kernel_program(const std::shared_ptr< Chonk > &ivc)
Generate an acir program {constraints, witness} for a mock kernel.
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 std::vector< PROOF_TYPE > inner_kernel_proof_types(size_t num_apps)
bb::CircuitVerificationKey CircuitVerificationKey
stdlib::recursion::PairingPoints< stdlib::bn254< ClientCircuit > > PairingPoints
Verifier for Chonk IVC proofs (both native and recursive).
Output verify(const Proof &proof)
Verify a Chonk proof.
MergeProver::MergeProof MergeProof
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
static void add_arithmetic_gates(Builder &builder, const size_t num_gates=4)
Add a specified number of arithmetic gates to the provided circuit.
Contains all the information required by a Honk prover to create a proof, constructed from a finalize...
The recursive counterpart to the "native" Ultra flavor.
Output verify_proof(const Proof &proof)
Perform ultra verification.
static constexpr element one
A simple wrapper around a vector of stdlib field elements representing a proof.
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.
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.
field< Bn254FrParams > fr
typename flavor_for_impl< K >::type flavor_for
MegaCircuitBuilder_< field< Bn254FrParams > > MegaCircuitBuilder
constexpr decltype(auto) dispatch_kind(CircuitKind kind, F &&f)
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()
Output type for recursive ultra verification.