Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
recursive_verifier.test.cpp
Go to the documentation of this file.
15
16#include <gtest/gtest.h>
17
18namespace bb::avm2::constraining {
19
20class AvmRecursiveTests : public ::testing::Test {
21 public:
26
28
29 // Helper function to create and verify native proof
36
37 // Helper function to create and verify native proof. Due to the way ASSERT_TRUE
38 // works, this routine needs to return void and therefore we feed proof_result
39 // by reference.
41 {
42 auto [trace, public_inputs] = testing::get_minimal_trace_with_pi();
43
44 InnerProver prover;
45 const auto [proof, vk_data] = prover.prove(std::move(trace));
46 const auto verification_key = InnerProver::create_verification_key(vk_data);
47 InnerVerifier verifier(verification_key);
48
49 const auto public_inputs_cols = public_inputs.to_columns();
50 const bool verified = verifier.verify_proof(proof, public_inputs_cols);
51
52 // Should be in principle ASSERT_TRUE, but compiler does not like it.
53 EXPECT_TRUE(verified) << "native proof verification failed";
54
55 proof_result = { proof, verification_key, public_inputs_cols };
56 }
57};
58
66TEST_F(AvmRecursiveTests, GoblinRecursion)
67{
68 // Type aliases specific to GoblinRecursion test
70 using OuterBuilder = typename UltraRollupFlavor::CircuitBuilder;
72 using UltraRollupProver = UltraProver_<UltraRollupFlavor>;
73 using NativeVerifierCommitmentKey = typename AvmFlavor::VerifierCommitmentKey;
74
75 NativeProofResult proof_result;
76 std::cout << "Creating and verifying native proof..." << std::endl;
77 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
78 ASSERT_NO_FATAL_FAILURE({ create_and_verify_native_proof(proof_result); });
79 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
80 std::cout << "Time taken (native proof): " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count()
81 << "s" << std::endl;
82
83 auto [proof, verification_key, public_inputs_cols] = proof_result;
84 proof.insert(proof.begin(), 0); // TODO(#14234)[Unconditional PIs validation]: remove this
85
86 // Construct stdlib representations of the proof, public inputs and verification key
87 OuterBuilder outer_circuit;
88 stdlib::Proof<OuterBuilder> stdlib_proof(outer_circuit, proof);
89
90 std::vector<std::vector<UltraFF>> public_inputs_ct;
91 public_inputs_ct.reserve(public_inputs_cols.size());
92 for (const auto& vec : public_inputs_cols) {
94 vec_ct.reserve(vec.size());
95 for (const auto& val : vec) {
96 vec_ct.push_back(UltraFF::from_witness(&outer_circuit, val));
97 }
98 public_inputs_ct.push_back(vec_ct);
99 }
100
101 auto key_fields_native = verification_key->to_field_elements();
102 std::vector<UltraFF> outer_key_fields;
103 for (const auto& f : key_fields_native) {
104 UltraFF val = UltraFF::from_witness(&outer_circuit, f);
105 outer_key_fields.push_back(val);
106 }
107
108 // Construct the AVM recursive verifier and verify the proof
109 // Scoped to free memory of AvmRecursiveVerifier.
110 auto verifier_output = [&]() {
111 std::cout << "Constructing AvmRecursiveVerifier and verifying proof..." << std::endl;
112 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
113 AvmRecursiveVerifier avm_rec_verifier(outer_circuit, outer_key_fields);
114 auto result = avm_rec_verifier.verify_proof(stdlib_proof, public_inputs_ct);
115 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
116 std::cout << "Time taken (recursive verification): "
117 << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() << "s" << std::endl;
118 return result;
119 }();
120
121 verifier_output.points_accumulator.set_public();
122 verifier_output.ipa_claim.set_public();
123 outer_circuit.ipa_proof = verifier_output.ipa_proof.get_value();
124
125 // Ensure that the pairing check is satisfied on the outputs of the recursive verifier
126 NativeVerifierCommitmentKey pcs_vkey{};
127 bool agg_output_valid = pcs_vkey.pairing_check(verifier_output.points_accumulator.P0.get_value(),
128 verifier_output.points_accumulator.P1.get_value());
129 ASSERT_TRUE(agg_output_valid) << "Pairing points (aggregation state) are not valid.";
130 ASSERT_FALSE(outer_circuit.failed()) << "Outer circuit has failed.";
131
132 vinfo("Recursive verifier: finalized num gates = ", outer_circuit.num_gates);
133
134 // Construct and verify an Ultra Rollup proof of the AVM recursive verifier circuit. This proof carries an IPA claim
135 // from ECCVM recursive verification in its public inputs that will be verified as part of the UltraRollupVerifier.
136 auto outer_proving_key = std::make_shared<DeciderProvingKey_<UltraRollupFlavor>>(outer_circuit);
137
138 // Scoped to free memory of UltraRollupProver.
139 auto outer_proof = [&]() {
140 auto verification_key =
141 std::make_shared<UltraRollupFlavor::VerificationKey>(outer_proving_key->get_precomputed());
142 UltraRollupProver outer_prover(outer_proving_key, verification_key);
143 return outer_prover.construct_proof();
144 }();
145
146 // Verify the proof of the Ultra circuit that verified the AVM recursive verifier circuit
147 auto outer_verification_key =
148 std::make_shared<UltraRollupFlavor::VerificationKey>(outer_proving_key->get_precomputed());
149 VerifierCommitmentKey<curve::Grumpkin> ipa_verification_key(1 << CONST_ECCVM_LOG_N);
150 UltraRollupVerifier final_verifier(outer_verification_key, ipa_verification_key);
151
152 bool result = final_verifier.template verify_proof<bb::RollupIO>(outer_proof, outer_proving_key->ipa_proof).result;
153 EXPECT_TRUE(result);
154}
155
156} // namespace bb::avm2::constraining
UltraCircuitBuilder CircuitBuilder
typename Curve::ScalarField FF
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
AvmFlavorSettings::VerifierCommitmentKey VerifierCommitmentKey
Definition flavor.hpp:41
Recursive verifier of AVM2 proofs that utilizes the Goblin mechanism for efficient EC operations.
std::pair< Proof, VkData > prove(tracegen::TraceContainer &&trace)
static std::shared_ptr< AvmVerifier::VerificationKey > create_verification_key(const VkData &vk_data)
AvmRecursiveFlavorSettings::CircuitBuilder CircuitBuilder
PairingPoints verify_proof(const HonkProof &proof, const std::vector< std::vector< fr > > &public_inputs_vec_nt)
virtual bool verify_proof(const HonkProof &proof, const std::vector< std::vector< FF > > &public_inputs)
This function verifies an Avm Honk proof for given program settings.
Definition verifier.cpp:41
typename RecursiveFlavor::CircuitBuilder OuterBuilder
static void create_and_verify_native_proof(NativeProofResult &proof_result)
A simple wrapper around a vector of stdlib field elements representing a proof.
Definition proof.hpp:19
void vinfo(Args... args)
Definition log.hpp:76
TestTraceContainer trace
TEST_F(AvmRecursiveTests, GoblinRecursion)
A test of the Goblinized AVM recursive verifier.
std::pair< tracegen::TraceContainer, PublicInputs > get_minimal_trace_with_pi()
Definition fixtures.cpp:182
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13