Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ultra_verifier.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Planned, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
21
22namespace bb {
23
29template <typename Flavor, class IO>
31{
32 using FF = typename Flavor::FF;
33 using Curve = typename Flavor::Curve;
34
35 auto vk_ptr = verifier_instance->get_vk();
36
37 // Determine log_n based on whether padding is employed
38 const size_t log_n = [&]() {
39 if constexpr (Flavor::USE_PADDING) {
40 return static_cast<size_t>(Flavor::VIRTUAL_LOG_N);
41 } else if constexpr (!IsRecursive) {
42 return static_cast<size_t>(vk_ptr->log_circuit_size);
43 }
44 }();
45
46 // Construct the padding indicator array
47 // - Non-ZK flavors: all 1s (no masking needed)
48 // - ZK without padding: all 1s (log_n == log_circuit_size, no padded region)
49 // - ZK with padding: computed to mask padded rounds (1s for real, 0s for padding)
50 std::vector<FF> padding_indicator_array(log_n, FF{ 1 });
51 if constexpr (Flavor::HasZK && Flavor::USE_PADDING) {
52 if constexpr (IsRecursive) {
53 // Recursive: use in-circuit computation via Lagrange polynomials
54 padding_indicator_array =
55 stdlib::compute_padding_indicator_array<Curve, Flavor::VIRTUAL_LOG_N>(vk_ptr->log_circuit_size);
56 } else {
57 // Native: simple loop comparison
58 const size_t log_circuit_size = static_cast<size_t>(vk_ptr->log_circuit_size);
59 for (size_t idx = 0; idx < log_n; idx++) {
60 padding_indicator_array[idx] = (idx < log_circuit_size) ? FF{ 1 } : FF{ 0 };
61 }
62 }
63 }
64
65 return PaddingData{ log_n, std::move(padding_indicator_array) };
66}
67
71template <typename Flavor, class IO>
73 Flavor,
74 IO>::split_rollup_proof(const Proof& combined_proof) const
76{
77 // Use VK's num_public_inputs which includes both IO and any additional circuit public inputs
78 auto vk_ptr = verifier_instance->get_vk();
79 const size_t num_public_inputs = [&]() {
80 if constexpr (IsRecursive) {
81 return static_cast<size_t>(uint32_t(vk_ptr->num_public_inputs.get_value()));
82 } else {
83 return static_cast<size_t>(vk_ptr->num_public_inputs);
84 }
85 }();
86
87 // Calculate split point
88 const size_t HONK_PROOF_LENGTH = UltraRollupFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS() - IPA_PROOF_LENGTH;
89 const std::ptrdiff_t honk_proof_with_pub_inputs_length =
90 static_cast<std::ptrdiff_t>(HONK_PROOF_LENGTH + num_public_inputs);
91
92 // Extract proofs
93 Proof honk_proof(combined_proof.begin(), combined_proof.begin() + honk_proof_with_pub_inputs_length);
94 Proof ipa_proof(combined_proof.begin() + honk_proof_with_pub_inputs_length, combined_proof.end());
95
96 return std::make_pair(honk_proof, ipa_proof);
97}
98
102template <typename Flavor, class IO>
103bool UltraVerifier_<Flavor, IO>::verify_ipa(const Proof& ipa_proof, const IPAClaim& ipa_claim)
105{
106 VerifierCommitmentKey<curve::Grumpkin> ipa_verification_key(1 << CONST_ECCVM_LOG_N);
107 ipa_transcript->load_proof(ipa_proof);
108 bool ipa_verified = IPA<curve::Grumpkin>::reduce_verify(ipa_verification_key, ipa_claim, ipa_transcript);
109 vinfo("UltraVerifier: IPA check: ", ipa_verified ? "true" : "false");
110
111 if (!ipa_verified) {
112 info("UltraVerifier: verification failed at IPA check");
113 }
114
115 return ipa_verified;
116}
117
123template <typename Flavor, class IO>
125 const typename UltraVerifier_<Flavor, IO>::Proof& proof)
126{
127 using FF = typename Flavor::FF;
128 using PCS = typename Flavor::PCS;
129 using Curve = typename Flavor::Curve;
131 using VerifierCommitments = typename Flavor::VerifierCommitments;
132 using ClaimBatcher = ClaimBatcher_<Curve>;
133 using ClaimBatch = ClaimBatcher::Batch;
134
135 transcript->load_proof(proof);
136 OinkVerifier<Flavor> oink_verifier{ verifier_instance, transcript };
137 oink_verifier.verify();
138
139 // Compute padding data (log_n and padding_indicator_array)
140 auto [log_n, padding_indicator_array] = process_padding();
141 verifier_instance->gate_challenges =
142 transcript->template get_dyadic_powers_of_challenge<FF>("Sumcheck:gate_challenge", log_n);
143
144 // Get the witness commitments that the verifier needs to verify
145 VerifierCommitments commitments{ verifier_instance->get_vk(), verifier_instance->witness_commitments };
146 // For ZK flavors: set gemini_masking_poly commitment from accumulator
147 if constexpr (Flavor::HasZK) {
148 commitments.gemini_masking_poly = verifier_instance->gemini_masking_commitment;
149 }
150
151 // Construct the sumcheck verifier
152 SumcheckVerifier<Flavor> sumcheck(transcript, verifier_instance->alpha, log_n);
153 // Receive commitments to Libra masking polynomials for ZKFlavors
155
156 if constexpr (Flavor::HasZK) {
157 libra_commitments[0] = transcript->template receive_from_prover<Commitment>("Libra:concatenation_commitment");
158 }
159 // Run the sumcheck verifier
160 SumcheckOutput<Flavor> sumcheck_output = sumcheck.verify(
161 verifier_instance->relation_parameters, verifier_instance->gate_challenges, padding_indicator_array);
162 // Get the claimed evaluation of the Libra polynomials for ZKFlavors
163 if constexpr (Flavor::HasZK) {
164 libra_commitments[1] = transcript->template receive_from_prover<Commitment>("Libra:grand_sum_commitment");
165 libra_commitments[2] = transcript->template receive_from_prover<Commitment>("Libra:quotient_commitment");
166 }
167
168 ClaimBatcher claim_batcher{
169 .unshifted = ClaimBatch{ commitments.get_unshifted(), sumcheck_output.claimed_evaluations.get_unshifted() },
170 .shifted = ClaimBatch{ commitments.get_to_be_shifted(), sumcheck_output.claimed_evaluations.get_shifted() }
171 };
172
173 const Commitment one_commitment = [&]() {
174 if constexpr (IsRecursive) {
175 return Commitment::one(builder);
176 } else {
177 return Commitment::one();
178 }
179 }();
180
181 auto shplemini_output = Shplemini::compute_batch_opening_claim(padding_indicator_array,
182 claim_batcher,
183 sumcheck_output.challenge,
184 one_commitment,
185 transcript,
187 libra_commitments,
188 sumcheck_output.claimed_libra_evaluation);
189
190 // Build reduction result
191 ReductionResult result;
192 result.pairing_points = PCS::reduce_verify_batch_opening_claim(
193 std::move(shplemini_output.batch_opening_claim), transcript, Flavor::FINAL_PCS_MSM_SIZE(log_n));
194
195 bool consistency_checked = true;
196 if constexpr (Flavor::HasZK) {
197 consistency_checked = shplemini_output.consistency_checked;
198 vinfo("Ultra Verifier (with ZK): Libra evals consistency checked ", consistency_checked ? "true" : "false");
199 }
200 vinfo("Ultra Verifier sumcheck_verified: ", sumcheck_output.verified ? "true" : "false");
201 result.reduction_succeeded = sumcheck_output.verified && consistency_checked;
202
203 return result;
204}
205
213template <typename Flavor, class IO>
215 const typename UltraVerifier_<Flavor, IO>::Proof& proof)
216{
217 // Step 1: Split proof if needed
218 Proof honk_proof;
219 Proof ipa_proof;
220 if constexpr (HasIPAAccumulator<Flavor>) {
221 std::tie(honk_proof, ipa_proof) = split_rollup_proof(proof);
222 } else {
223 honk_proof = proof;
224 }
225
226 // Step 2: Reduce to pairing check
227 auto [pcs_pairing_points, reduction_succeeded] = reduce_to_pairing_check(honk_proof);
228 vinfo("UltraVerifier: reduced to pairing check: ", reduction_succeeded ? "true" : "false");
229
230 if constexpr (!IsRecursive) {
231 if (!reduction_succeeded) {
232 info("UltraVerifier: verification failed at reduction step");
233 return Output{};
234 }
235 }
236
237 // Step 3: Process the reduction result and public inputs
238 IO inputs;
239 inputs.reconstruct_from_public(verifier_instance->public_inputs);
240
241 // Aggregate pairing points
242 PairingPoints pi_pairing_points = inputs.pairing_inputs;
243 pi_pairing_points.aggregate(pcs_pairing_points);
244
245 // Construct output (common to both native and recursive)
246 Output output(inputs);
247
248 if constexpr (IsRecursive) {
249 // Recursive: populate output for deferred verification
250 output.points_accumulator = std::move(pi_pairing_points);
251 if constexpr (HasIPAAccumulator<Flavor>) {
252 output.ipa_proof = ipa_proof;
253 }
254 } else {
255 // Perform pairing check
256 bool pairing_verified = pi_pairing_points.check();
257 vinfo("UltraVerifier: pairing check: ", pairing_verified ? "true" : "false");
258
259 if (!pairing_verified) {
260 info("UltraVerifier: verification failed at pairing check");
261 return Output{};
262 }
263
264 // Perform IPA verification if Rollup flavor
265 if constexpr (HasIPAAccumulator<Flavor>) {
266 if (!verify_ipa(ipa_proof, inputs.ipa_claim)) {
267 return Output{};
268 }
269 }
270
271 output.result = true;
272 }
273
274 return output;
275}
276
277// ===== NATIVE FLAVOR INSTANTIATIONS =====
278
287
288#ifdef STARKNET_GARAGA_FLAVORS
291#endif
292
293// ===== RECURSIVE FLAVOR INSTANTIATIONS =====
294
295// UltraRecursiveFlavor with DefaultIO
300
301// UltraZKRecursiveFlavor with DefaultIO
306
307// UltraRollupRecursiveFlavor with RollupIO
309
310// MegaRecursiveFlavor with DefaultIO
315
316// MegaZKRecursiveFlavor with DefaultIO
321
322// MegaZKRecursiveFlavor with HidingKernelIO (Chonk)
325
326// MegaRecursiveFlavor with GoblinAvmIO
329
330} // namespace bb
static constexpr bool HasZK
typename Curve::ScalarField FF
VerifierCommitments_< Commitment, VerificationKey > VerifierCommitments
curve::Grumpkin Curve
static constexpr bool USE_PADDING
static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS
IPA (inner product argument) commitment scheme class.
Definition ipa.hpp:93
Verifier class for all the presumcheck rounds, which are shared between the folding verifier and ultr...
void verify()
Oink Verifier function that runs all the rounds of the verifier.
Unverified claim (C,r,v) for some witness polynomial p(X) such that.
Definition claim.hpp:53
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:785
SumcheckOutput< Flavor > verify(const bb::RelationParameters< FF > &relation_parameters, const std::vector< FF > &gate_challenges, const std::vector< FF > &padding_indicator_array)
The Sumcheck verification method. First it extracts round univariate, checks sum (the sumcheck univar...
Definition sumcheck.hpp:843
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS(size_t virtual_log_n=VIRTUAL_LOG_N)
ReductionResult reduce_to_pairing_check(const Proof &proof)
Reduce ultra proof to verification claims (works for both native and recursive)
typename Transcript::Proof Proof
std::conditional_t< IsRecursive, stdlib::recursion::PairingPoints< Curve >, bb::PairingPoints< Curve > > PairingPoints
bool verify_ipa(const Proof &ipa_proof, const IPAClaim &ipa_claim)
Verify IPA proof for rollup circuits (native verifier only)
std::conditional_t< IsRecursive, stdlib::recursion::honk::UltraRecursiveVerifierOutput< Builder >, UltraVerifierOutput< Flavor > > Output
PaddingData process_padding() const
Compute log_n and padding indicator array based on flavor configuration.
typename Flavor::Curve Curve
typename Flavor::Commitment Commitment
Output verify_proof(const Proof &proof)
Perform ultra verification.
typename Flavor::FF FF
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
Manages the data that is propagated on the public inputs of an application/function circuit.
The data that is propagated on the public inputs of the inner GoblinAvmRecursiveVerifier circuit.
Manages the data that is propagated on the public inputs of a hiding kernel circuit.
The data that is propagated on the public inputs of a rollup circuit.
#define vinfo(...)
Definition log.hpp:94
void info(Args... args)
Definition log.hpp:89
AluTraceBuilder builder
Definition alu.test.cpp:124
ECCVMFlavor Flavor
AvmProvingInputs inputs
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
For a small integer N = virtual_log_n and a given witness x = log_n, compute in-circuit an indicator_...
Logic to support batching opening claims for unshifted, shifted and interleaved polynomials in Shplem...
Contains the evaluations of multilinear polynomials at the challenge point . These are computed by S...
ClaimedEvaluations claimed_evaluations
std::vector< FF > challenge
Result of padding computation.
Result of reducing ultra proof to pairing points check. Contains pairing points and the aggrefate res...