15using Flavors = testing::Types<MegaRecursiveFlavor_<MegaCircuitBuilder>,
16 MegaRecursiveFlavor_<UltraCircuitBuilder>,
17 UltraRecursiveFlavor_<UltraCircuitBuilder>,
18 UltraRecursiveFlavor_<MegaCircuitBuilder>,
19 UltraZKRecursiveFlavor_<UltraCircuitBuilder>,
20 UltraZKRecursiveFlavor_<MegaCircuitBuilder>,
21 UltraRollupRecursiveFlavor_<UltraCircuitBuilder>,
22 MegaZKRecursiveFlavor_<MegaCircuitBuilder>,
23 MegaZKRecursiveFlavor_<UltraCircuitBuilder>>;
89 const size_t num_gates = (1 << log_num_gates);
90 for (
size_t i = 0; i < num_gates; ++i) {
92 uint32_t a_idx =
builder.add_variable(
a);
97 uint32_t b_idx =
builder.add_variable(
b);
98 uint32_t c_idx =
builder.add_variable(c);
99 uint32_t d_idx =
builder.add_variable(d);
101 builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx,
fr(1),
fr(1),
fr(1),
fr(-1),
fr(0) });
122 EXPECT_EQ(result,
true);
145 static_cast<uint64_t
>(verifier.get_verifier_instance()->vk_and_hash->vk->log_circuit_size.get_value()),
146 honk_vk->log_circuit_size);
148 static_cast<uint64_t
>(verifier.get_verifier_instance()->vk_and_hash->vk->num_public_inputs.get_value()),
149 honk_vk->num_public_inputs);
150 for (
auto [vk_poly, native_vk_poly] :
151 zip_view(verifier.get_verifier_instance()->vk_and_hash->vk->get_all(), honk_vk->get_all())) {
152 EXPECT_EQ(vk_poly.get_value(), native_vk_poly);
165 auto get_blocks = [](
size_t inner_size) -> std::tuple<
typename OuterBuilder::ExecutionTrace,
172 auto verification_key =
174 InnerProver inner_prover(inner_prover_instance, verification_key);
175 info(
"test circuit size: ", inner_prover_instance->dyadic_size());
180 auto stdlib_vk_and_hash =
190 inputs.pairing_inputs = verifier_output.points_accumulator;
193 inputs.ipa_claim = verifier_output.ipa_claim;
196 outer_circuit.ipa_proof = verifier_output.ipa_proof.get_value();
201 auto outer_verification_key =
204 return { outer_circuit.blocks, outer_verification_key };
207 auto [blocks_10, verification_key_10] = get_blocks(10);
208 auto [blocks_14, verification_key_14] = get_blocks(14);
210 compare_ultra_blocks_and_verification_keys<OuterFlavor>({ blocks_10, blocks_14 },
211 { verification_key_10, verification_key_14 });
225 auto verification_key =
227 InnerProver inner_prover(prover_instance, verification_key);
232 auto stdlib_vk_and_hash =
235 recursive_transcript->enable_manifest();
239 VerifierOutput output = verifier.verify_proof(stdlib_inner_proof);
249 outer_circuit.ipa_proof = output.
ipa_proof.get_value();
254 EXPECT_EQ(outer_circuit.failed(),
false) << outer_circuit.err();
260 native_transcript->enable_manifest();
261 InnerVerifier native_verifier(vk_and_hash, native_transcript);
263 bool native_result = native_verifier.
verify_proof(inner_proof).result;
268 info(
"input pairing points result: ", result);
269 auto recursive_result =
271 EXPECT_EQ(recursive_result, native_result);
275 auto recursive_manifest = verifier.get_transcript()->get_manifest();
276 auto native_manifest = native_verifier.
get_transcript()->get_manifest();
277 for (
size_t i = 0; i < recursive_manifest.size(); ++i) {
278 EXPECT_EQ(recursive_manifest[i], native_manifest[i]);
284 auto verification_key =
286 info(
"Recursive Verifier: num gates = ", outer_circuit.get_num_finalized_gates());
287 OuterProver prover(prover_instance, verification_key);
297 const auto expected_gate_count =
std::get<0>(acir_format::HONK_RECURSION_CONSTANTS<RecursiveFlavor>());
298 ASSERT_EQ(outer_circuit.get_num_finalized_gates(), expected_gate_count)
299 <<
"MegaZKHonk Recursive verifier changed in Ultra gate count! Update this value if you "
300 "are sure this is expected.";
311 for (
size_t idx = 0; idx < static_cast<size_t>(
TamperType::END); idx++) {
318 auto inner_verification_key =
320 InnerProver inner_prover(prover_instance, inner_verification_key);
325 tamper_with_proof<InnerProver, InnerFlavor>(inner_prover, inner_proof, tamper_type);
329 auto stdlib_vk_and_hash =
333 VerifierOutput output = verifier.verify_proof(stdlib_inner_proof);
346 EXPECT_FALSE(result);
360 for (
size_t idx = 0; idx < 2; idx++) {
367 auto inner_verification_key =
369 InnerProver inner_prover(prover_instance, inner_verification_key);
373 tamper_with_proof<InnerProver, InnerFlavor>(inner_proof,
static_cast<bool>(idx));
377 auto stdlib_vk_and_hash =
381 VerifierOutput output = verifier.verify_proof(stdlib_inner_proof);
394 EXPECT_FALSE(result);
404 TestFixture::test_inner_circuit();
409 TestFixture::test_recursive_verification_key_creation();
414 TestFixture::test_recursive_verification();
419 if constexpr (
IsAnyOf<TypeParam,
424 TestFixture::test_independent_vk_hash();
426 GTEST_SKIP() <<
"Not built for this parameter";
432 TestFixture::test_recursive_verification_fails();
435#ifdef DISABLE_HEAVY_TESTS
437TEST(RecursiveVerifierTest, DoNothingTestToEnsureATestExists) {}
Manages the data that is propagated on the public inputs of an application/function circuit.
The recursive counterpart to the "native" MegaZKFlavor.
A ProverInstance is normally constructed from a finalized circuit and it contains all the information...
The data that is propagated on the public inputs of a rollup circuit.
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
The recursive counterpart to the "native" Ultra flavor.
UltraRollupFlavor extends UltraFlavor with IPA proof support.
The recursive counterpart to the "native" UltraRollupFlavor.
typename Flavor::VerificationKey VerificationKey
std::conditional_t< IsRecursive, stdlib::recursion::honk::UltraRecursiveVerifierOutput< Builder >, UltraVerifierOutput< Flavor > > Output
const std::shared_ptr< Transcript > & get_transcript() const
Get the transcript (for accessing manifest in tests)
Output verify_proof(const Proof &proof)
Perform ultra verification.
The recursive counterpart to the Ultra flavor with ZK.
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.
Test suite for recursive verification of Honk proofs for both Ultra and Mega arithmetisation.
std::vector< InnerFF > InnerProof
std::conditional_t< HasIPAAccumulator< InnerFlavor >, bb::RollupIO, bb::DefaultIO > NativeInnerIO
std::conditional_t< HasIPAAccumulator< OuterFlavor >, bb::RollupIO, bb::DefaultIO > NativeOuterIO
InnerFlavor::Commitment InnerCommitment
typename RecursiveFlavor::NativeFlavor InnerFlavor
std::conditional_t< HasIPAAccumulator< RecursiveFlavor >, bb::stdlib::recursion::honk::RollupIO, bb::stdlib::recursion::honk::DefaultIO< OuterBuilder > > OuterIO
static InnerBuilder create_inner_circuit(size_t log_num_gates=10)
Create a non-trivial arbitrary inner circuit, the proof of which will be recursively verified.
typename InnerFlavor::VerifierCommitmentKey NativeVerifierCommitmentKey
std::conditional_t< IsMegaBuilder< OuterBuilder >, MegaFlavor, std::conditional_t< HasIPAAccumulator< RecursiveFlavor >, UltraRollupFlavor, UltraFlavor > > OuterFlavor
static void test_recursive_verification()
Construct a recursive verification circuit for the proof of an inner circuit then call check_circuit ...
static void test_recursive_verification_fails()
Construct verifier circuits for proofs whose data have been tampered with. Expect failure.
typename RecursiveVerifier::VerificationKey VerificationKey
static void test_recursive_verification_key_creation()
Instantiate a recursive verification key from the native verification key produced by the inner cicui...
static void test_recursive_verification_fails()
Tamper with a MegaZK proof in two ways. First, we modify the first non-zero value in the proof,...
std::conditional_t< HasIPAAccumulator< RecursiveFlavor >, bb::stdlib::recursion::honk::RollupIO, bb::stdlib::recursion::honk::DefaultIO< InnerBuilder > > InnerIO
static void test_inner_circuit()
Create inner circuit and call check_circuit on it.
typename RecursiveFlavor::CircuitBuilder OuterBuilder
typename InnerFlavor::CircuitBuilder InnerBuilder
static void test_independent_vk_hash()
Ensures that the recursive verifier circuit for two inner circuits of different size is the same as t...
static void SetUpTestSuite()
The data that is propagated on the public inputs of a rollup circuit.
Base class templates for structures that contain data parameterized by the fundamental polynomials of...
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
testing::Types< UltraRecursiveFlavor_< UltraCircuitBuilder > > Flavors
TYPED_TEST_SUITE(BoomerangRecursiveVerifierTest, Flavors)
field< Bn254FrParams > fr
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
An object storing two EC points that represent the inputs to a pairing check.
Output type for recursive ultra verification.
OpeningClaim< grumpkin< Builder > > ipa_claim
PairingPoints< Curve > points_accumulator
stdlib::Proof< Builder > ipa_proof
#define HEAVY_TYPED_TEST(x, y)