Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
two_layer_avm_recursive_verifier.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Completed, auditors: [Federico], commit: 54146acfe3568e22f80648f4092e10cb2c8702c2}
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6#pragma once
7
23
24namespace bb::avm2 {
25
26static constexpr size_t NUM_AVM_ULTRA_OPS = 2909;
27static_assert(2 * NUM_AVM_ULTRA_OPS < (1 << CONST_TRANSLATOR_MINI_CIRCUIT_LOG_SIZE) - NUM_DISABLED_ROWS_IN_SUMCHECK,
28 "AVM ultra ops land in the range reserved for randomness in the Translator mini circuit. If this "
29 "assertion fails, we need to increase CONST_TRANSLATOR_MINI_CIRCUIT_LOG_SIZE.");
30
60 public:
62
65
66 // The output of the goblinized AVM2 recursive verifier
71
72 // Output of prover for inner Mega-arithmetized AVM recursive verifier circuit; input to the outer verifier
78
79 private:
81
82 public:
94 [[nodiscard("TripleIPA opening and pairing points should be accumulated")]] TwoLayerAvmRecursiveVerifierOutput
96 const std::vector<std::vector<UltraFF>>& public_inputs) const
97 {
98 // Construct and prove the inner Mega-arithmetized AVM recursive verifier circuit; proof is {\pi_M, \pi_G}
99 InnerProverOutput inner_output =
101
102 // Construct the outer Ultra-arithmetized Mega/Goblin recursive verifier circuit
104 construct_outer_recursive_verification_circuit(stdlib_proof, public_inputs, inner_output);
105
106 return result;
107 }
108
117 [[nodiscard("TripleIPA opening and pairing points should be accumulated")]] TwoLayerAvmRecursiveVerifierOutput
119 const std::vector<std::vector<UltraFF>>& public_inputs,
120 const InnerProverOutput& inner_output) const
121 {
122 // Types for MegaRecursiveVerifier specialized for the AVM
123 using MegaAvmRecursiveFlavor = MegaAvmRecursiveFlavor_<UltraCircuitBuilder>;
124 using MegaRecursiveVKAndHash = MegaAvmRecursiveFlavor::VKAndHash;
126 using MegaAvmRecursiveVerifier = UltraVerifier_<MegaAvmRecursiveFlavor, IO>;
127
128 // Step 1: Recursively verify the Mega proof \pi_M
129 auto transcript = std::make_shared<MegaAvmRecursiveFlavor::Transcript>(); // Single shared transcript
130 auto mega_vk_and_hash = std::make_shared<MegaRecursiveVKAndHash>(*outer_builder, inner_output.mega_vk);
131
132 // The vk of the inner Mega arithmetized AVM recursive verifier circuit must be fixed to ensure that the outer
133 // circuit verifies the validity of the intended inner circuit.
134 mega_vk_and_hash->vk->fix_witness();
135 mega_vk_and_hash->hash.fix_witness();
136
137 MegaAvmRecursiveVerifier mega_verifier(mega_vk_and_hash, transcript);
139 auto mega_verifier_output = mega_verifier.verify_proof(mega_proof);
140
141 // Step 2: Recursively verify the goblin proof \pi_G
142 GoblinAvmStdlibProof stdlib_goblin_proof(*outer_builder, inner_output.goblin_proof);
143 GoblinAvmRecursiveVerifier goblin_verifier{ transcript, stdlib_goblin_proof, mega_verifier.get_ecc_op_wires() };
144 auto goblin_verifier_output = goblin_verifier.reduce_to_pairing_check_and_triple_ipa_opening();
145
146 // Step 3: Aggregate pairing points coming from Mega verification and Goblin verification
147 mega_verifier_output.points_accumulator.aggregate(goblin_verifier_output.translator_pairing_points);
148
149 // Step 4: Validate the consistency of the AVM2 verifier inputs {\pi, pub_inputs}_{AVM2} between the inner
150 // (Mega) circuit and the outer (Ultra) by asserting equality on the independently computed hashes
151 const UltraFF computed_transcript_hash =
153 mega_verifier_output.transcript_hash.assert_equal(computed_transcript_hash);
154
155 return { .points_accumulator = std::move(mega_verifier_output.points_accumulator),
156 .triple_ipa_opening = std::move(goblin_verifier_output.triple_ipa_opening) };
157 }
158
167 const stdlib::Proof<UltraCircuitBuilder>& stdlib_proof, const std::vector<std::vector<UltraFF>>& public_inputs)
168 {
169 using MegaAvmProverInstance = ProverInstance_<MegaAvmFlavor>;
170 using MegaAvmVerificationKey = MegaAvmFlavor::VerificationKey;
171 using MegaAvmProver = UltraProver_<MegaAvmFlavor>;
172
173 // Instantiate Mega builder for the inner circuit (AVM2 proof recursive verifier)
174 MegaCircuitBuilder inner_builder;
175 GoblinAvm goblin(inner_builder);
176
177 // Construct the inner recursive verification circuit
178 construct_inner_recursive_verification_circuit(inner_builder, stdlib_proof, public_inputs);
179
180 // Construct the Mega proof \pi_M of the AVM recursive verifier circuit
181 auto transcript = std::make_shared<NativeTranscript>(); // Single shared transcript
182 auto mega_proving_key = std::make_shared<MegaAvmProverInstance>(inner_builder);
183 // Detect when MEGA_AVM_LOG_N needs to be bumped.
185 mega_proving_key->log_dyadic_size(),
186 MEGA_AVM_LOG_N,
187 "AVMRecursiveVerifier: circuit size exceeded current upper bound. If expected, bump MEGA_AVM_LOG_N");
188 auto mega_vk = std::make_shared<MegaAvmVerificationKey>(mega_proving_key->get_precomputed());
189 MegaAvmProver mega_prover(mega_proving_key, mega_vk, transcript);
190 HonkProof mega_proof = mega_prover.construct_proof();
191
192 // Construct the GoblinAvm proof \pi_G (includes ECCVM, IPA, and Translator proofs)
193 goblin.transcript = transcript;
194 GoblinAvmProof goblin_proof = goblin.prove();
195 BB_ASSERT_EQ(goblin.op_queue->get_ultra_ops_count(),
196 NUM_AVM_ULTRA_OPS,
197 "The number of ultra ops in the AVM proof has changed. This should only happen if the number of "
198 "columns in the AVM changed.");
199
200 return {
201 .mega_proof = mega_proof,
202 .goblin_proof = goblin_proof,
203 .mega_vk = mega_vk,
204 };
205 }
206
212 const stdlib::Proof<UltraCircuitBuilder>& stdlib_proof,
213 const std::vector<std::vector<UltraFF>>& public_inputs)
214 {
216
217 // Create free witnesses representing the AVM proof and public inputs in the inner circuit.
218 // The honest prover sets these values to match the values of the proof and public inputs in the outer circuit.
219 // Consistency between these witnesses and the ones in the outer circuit is enforced via a hash check.
220 stdlib::Proof<MegaCircuitBuilder> inner_stdlib_proof(inner_builder, stdlib_proof.get_value());
221 std::vector<std::vector<MegaFF>> inner_public_inputs;
222 inner_public_inputs.reserve(AVM_NUM_PUBLIC_INPUT_COLUMNS);
223 for (const auto& public_input_column : public_inputs) {
224 std::vector<MegaFF> inner_public_input_column;
225 inner_public_input_column.reserve(public_input_column.size());
226 for (const auto& public_input : public_input_column) {
227 inner_public_input_column.push_back(MegaFF::from_witness(&inner_builder, public_input.get_value()));
228 }
229 inner_public_inputs.push_back(std::move(inner_public_input_column));
230 }
231
232 // Construct a Mega-arithmetized AVM2 recursive verifier circuit
233 // The constructor of AvmRecursiveVerifier hard-codes the VK and the VK hash of the AVM2 by copying the values
234 // into the selectors.
235 AvmRecursiveVerifier recursive_verifier{ inner_builder };
236 MegaPairingPoints points_accumulator = recursive_verifier.verify_proof(inner_stdlib_proof, inner_public_inputs);
237
238 // Generate a challenge to record the final state of the transcript of the AVM recursive verifier
239 const MegaFF transcript_hash = recursive_verifier.hash_avm_transcript();
240
241 // Public inputs
242 IO inputs;
243 inputs.transcript_hash = transcript_hash;
244 inputs.pairing_inputs = points_accumulator;
246 }
247};
248
249} // namespace bb::avm2
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
#define BB_ASSERT_LTE(left, right,...)
Definition assert.hpp:158
Specialization of Goblin for the AVM.
GoblinAvmProof prove()
Constuct a full GoblinAvm proof (ECCVM, Translator)
typename ECCVMVerifier::DeferredTripleIpaOpening DeferredTripleIpaOpening
Result of GoblinAvm verification.
std::shared_ptr< OpQueue > op_queue
Definition goblin.hpp:59
std::shared_ptr< Transcript > transcript
Definition goblin.hpp:65
NativeVerificationKey_< PrecomputedEntities< Commitment >, Codec, HashFunction, CommitmentKey > VerificationKey
Recursive counterpart to MegaAvmFlavor.
Contains all the information required by a Honk prover to create a proof, constructed from a finalize...
static stdlib::field_t< Builder > hash_avm_transcript(Builder &builder, const stdlib::Proof< Builder > &stdlib_proof, const std::vector< std::vector< stdlib::field_t< Builder > > > &public_inputs)
Construct a transcript replicating the operations performed on the AVM transcript during proof verifi...
Recursive verifier of AVM2 proofs that utilizes the Goblin mechanism for efficient EC operations.
TwoLayerAvmRecursiveVerifierOutput verify_proof(const stdlib::Proof< UltraCircuitBuilder > &stdlib_proof, const std::vector< std::vector< UltraFF > > &public_inputs) const
Recursively verify an AVM proof using Goblin and two layers of recursive verification.
static void construct_inner_recursive_verification_circuit(MegaCircuitBuilder &inner_builder, const stdlib::Proof< UltraCircuitBuilder > &stdlib_proof, const std::vector< std::vector< UltraFF > > &public_inputs)
Construct the inner recursive verification circuit for the AVM2 recursive verifier.
static InnerProverOutput construct_and_prove_inner_recursive_verification_circuit(const stdlib::Proof< UltraCircuitBuilder > &stdlib_proof, const std::vector< std::vector< UltraFF > > &public_inputs)
Construct and prove the inner Mega-arithmetized AVM recursive verifier circuit.
TwoLayerAvmRecursiveVerifierOutput construct_outer_recursive_verification_circuit(const stdlib::Proof< UltraCircuitBuilder > &stdlib_proof, const std::vector< std::vector< UltraFF > > &public_inputs, const InnerProverOutput &inner_output) const
Construct the outer circuit which recursively verifies a Mega proof and a Goblin proof.
A simple wrapper around a vector of stdlib field elements representing a proof.
Definition proof.hpp:20
HonkProof get_value() const
Definition proof.hpp:53
static field_t from_witness(Builder *ctx, const bb::fr &input)
Definition field.hpp:480
The data that is propagated on the public inputs of the inner GoblinAvmRecursiveVerifier circuit.
AluTraceBuilder builder
Definition alu.test.cpp:124
AvmProvingInputs inputs
std::vector< fr > HonkProof
Definition proof.hpp:15
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
stdlib::recursion::PairingPoints< stdlib::bn254< UltraCircuitBuilder > > points_accumulator
An object storing two EC points that represent the inputs to a pairing check.
uint32_t set_public(Builder *ctx=nullptr)
Set the witness indices for the pairing points to public.
VectorField result