Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
verifier.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Completed, auditors: [Federico], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
7
13#include <numeric>
14
15namespace bb::avm2 {
16
18 : key(std::move(other.key))
19 , transcript(std::move(other.transcript))
20{}
21
23{
24 key = other.key;
25 transcript = other.transcript;
26 return *this;
27}
28
42 const std::vector<FF>& challenges)
43{
44 Polynomial<FF> polynomial(points, MAX_AVM_TRACE_SIZE);
45 return polynomial.evaluate_mle(challenges);
46}
47
52bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vector<std::vector<FF>>& public_inputs)
53{
54 using PCS = Flavor::PCS;
55 using Curve = Flavor::Curve;
56 using VerifierCommitments = Flavor::VerifierCommitments;
58 using ClaimBatcher = ClaimBatcher_<Curve>;
59 using ClaimBatch = ClaimBatcher::Batch;
61 using Challenges = Flavor::AllEntities<FF>;
62
63 RelationParameters<FF> relation_parameters;
64
65 transcript->load_proof(proof);
66
67 // ========== Execute preamble round ==========
68
69 // Add vk hash to transcript
70 FF vk_hash = key->get_hash();
71 transcript->add_to_hash_buffer("avm_vk_hash", vk_hash);
72 vinfo("AVM vk hash in verifier: ", vk_hash);
73
74 // ========== Execute public inputs round ==========
75
76 // Validate number of public input columns
77 if (public_inputs.size() != AVM_NUM_PUBLIC_INPUT_COLUMNS) {
78 vinfo("Public inputs size mismatch");
79 return false;
80 }
81
82 // Add public inputs to transcript. This ensures that the Sumcheck challenge depends both on the public inputs sent
83 // in the clear and on the committed columns.
84 for (size_t i = 0; i < AVM_NUM_PUBLIC_INPUT_COLUMNS; i++) {
85 // Validate public input column size
86 if (public_inputs[i].size() != AVM_PUBLIC_INPUTS_COLUMNS_MAX_LENGTH) {
87 vinfo("Public input size mismatch");
88 return false;
89 }
90 for (size_t j = 0; j < public_inputs[i].size(); j++) {
91 transcript->add_to_hash_buffer("public_input_" + std::to_string(i) + "_" + std::to_string(j),
92 public_inputs[i][j]);
93 }
94 }
95
96 // ========== Execute wire commitments round ==========
97
98 // Receive commitments to all polynomials except the logderivate ones
99 VerifierCommitments commitments{ key };
100 for (auto [comm, label] : zip_view(commitments.get_wires(), commitments.get_wires_labels())) {
101 comm = transcript->template receive_from_prover<Commitment>(label);
102 }
103
104 // ========== Execute log derivative inverse round ==========
105
106 // Generate randomness required by Lookup and Permutation relations
107 auto [beta, gamma] = transcript->template get_challenges<FF>(std::array<std::string, 2>{ "beta", "gamma" });
108 relation_parameters.beta = beta;
109 relation_parameters.gamma = gamma;
110
111 // Receive commitments to all logderivative inverse polynomials
112 for (auto [commitment, label] : zip_view(commitments.get_derived(), commitments.get_derived_labels())) {
113 commitment = transcript->template receive_from_prover<Commitment>(label);
114 }
115
116 // ========== Execute relation check rounds ==========
117
118 // Construct padding indicator array: it is a vector of constant ones as the AVM verifier performs verification of
119 // the AVM circuit, so the number of rounds is fixed.
120 std::vector<FF> padding_indicator_array(MAX_AVM_TRACE_LOG_SIZE, 1);
121
122 // Multiply each linearly independent subrelation contribution by `alpha^i` for i = 0, ..., NUM_SUBRELATIONS - 1.
123 const FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");
124
126
127 // Get the gate challenges for sumcheck computation
128 std::vector<FF> gate_challenges =
129 transcript->template get_dyadic_powers_of_challenge<FF>("Sumcheck:gate_challenge", MAX_AVM_TRACE_LOG_SIZE);
130 SumcheckOutput<Flavor> output = sumcheck.verify(relation_parameters, gate_challenges, padding_indicator_array);
131
132 // If Sumcheck did not verify, return false
133 if (!output.verified) {
134 vinfo("Sumcheck verification failed");
135 return false;
136 }
137
138 // Validate that the public inputs committed in the public input columns match the public inputs sent in the clear
139 // by the Prover
140 using C = ColumnAndShifts;
142 output.claimed_evaluations.get(C::public_inputs_cols_0_),
143 output.claimed_evaluations.get(C::public_inputs_cols_1_),
144 output.claimed_evaluations.get(C::public_inputs_cols_2_),
145 output.claimed_evaluations.get(C::public_inputs_cols_3_),
146 };
147 for (size_t idx = 0;
148 const auto& [public_input_column, claimed_evaluation] : zip_view(public_inputs, claimed_evaluations)) {
149 FF public_input_evaluation = evaluate_public_input_column(public_input_column, output.challenge);
150 if (public_input_evaluation != claimed_evaluation) {
151 vinfo("public_input_evaluation failed, public inputs col ", idx);
152 return false;
153 }
154 idx++;
155 }
156
157 // ========== Execute PCS verification ==========
158
159 // Batch commitments and evaluations using short scalars to reduce ECCVM circuit size
160 std::span<const Commitment> unshifted_comms = commitments.get_unshifted();
161 std::span<const FF> unshifted_evals = output.claimed_evaluations.get_unshifted();
162 std::span<const Commitment> shifted_comms = commitments.get_to_be_shifted();
163 std::span<const FF> shifted_evals = output.claimed_evaluations.get_shifted();
164
165 // Get short batching challenges from transcript
166 Challenges challenges;
167 auto unshifted_challenges_vec = transcript->template get_challenges<FF>(challenges.get_unshifted_labels());
168 std::ranges::move(unshifted_challenges_vec, challenges.get_unshifted().begin());
169 auto unshifted_challenges = challenges.get_unshifted();
170 auto shifted_challenges = challenges.get_to_be_shifted();
171
172 // Batch shifted commitments
173 Commitment batched_shifted = Commitment::batch_mul(shifted_comms, shifted_challenges);
174
175 // Batch unshifted commitments: We reuse the calculation performed for shifted commitments.
176 Commitment batched_unshifted =
177 batched_shifted +
178 Commitment::batch_mul(unshifted_comms.subspan(0, WIRES_TO_BE_SHIFTED_START_IDX),
179 unshifted_challenges.subspan(0, WIRES_TO_BE_SHIFTED_START_IDX)) +
180 Commitment::batch_mul(unshifted_comms.subspan(WIRES_TO_BE_SHIFTED_END_IDX),
181 unshifted_challenges.subspan(WIRES_TO_BE_SHIFTED_END_IDX));
182
183 // Batch evaluations: compute inner product with first eval as initial value for unshifted
184 FF batched_unshifted_eval =
185 std::inner_product(unshifted_challenges.begin(), unshifted_challenges.end(), unshifted_evals.begin(), FF(0));
186
187 FF batched_shifted_eval =
188 std::inner_product(shifted_challenges.begin(), shifted_challenges.end(), shifted_evals.begin(), FF(0));
189
190 // Execute Shplemini rounds with batched claims
191 ClaimBatcher batched_claim_batcher{ .unshifted = ClaimBatch{ .commitments = RefVector(batched_unshifted),
192 .evaluations = RefVector(batched_unshifted_eval) },
193 .shifted = ClaimBatch{ .commitments = RefVector(batched_shifted),
194 .evaluations = RefVector(batched_shifted_eval) } };
195 auto opening_claim =
196 Shplemini::compute_batch_opening_claim(
197 padding_indicator_array, batched_claim_batcher, output.challenge, Commitment::one(), transcript)
198 .batch_opening_claim;
199
200 const auto pairing_points = PCS::reduce_verify_batch_opening_claim(std::move(opening_claim), transcript);
201 VerifierCommitmentKey pcs_vkey{};
202 const auto shplemini_verified = pcs_vkey.pairing_check(pairing_points[0], pairing_points[1]);
203
204 if (!shplemini_verified) {
205 vinfo("Shplemini verification failed");
206 return false;
207 }
208
209 return true;
210}
211
212} // namespace bb::avm2
#define AVM_NUM_PUBLIC_INPUT_COLUMNS
#define AVM_PUBLIC_INPUTS_COLUMNS_MAX_LENGTH
IPA (inner product argument) commitment scheme class.
Definition ipa.hpp:85
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
Fr evaluate_mle(std::span< const Fr > evaluation_points, bool shift=false) const
evaluate multi-linear extension p(X_0,…,X_{n-1}) = \sum_i a_i*L_i(X_0,…,X_{n-1}) at u = (u_0,...
A template class for a reference vector. Behaves as if std::vector<T&> was possible.
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:721
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:777
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
AvmFlavorSettings::VerifierCommitmentKey VerifierCommitmentKey
Definition flavor.hpp:49
VerifierCommitments_< Commitment, VerificationKey > VerifierCommitments
Definition flavor.hpp:320
AvmFlavorSettings::PCS PCS
Definition flavor.hpp:40
AvmFlavorSettings::Curve Curve
Definition flavor.hpp:38
std::shared_ptr< Transcript > transcript
Definition verifier.hpp:33
AvmVerifier & operator=(const AvmVerifier &other)=delete
static FF evaluate_public_input_column(const std::vector< FF > &points, const std::vector< FF > &challenges)
Evaluate the given public input column over the multivariate challenge points.
Definition verifier.cpp:41
std::shared_ptr< VerificationKey > key
Definition verifier.hpp:32
bool verify_proof(const HonkProof &proof, const std::vector< std::vector< FF > > &public_inputs)
Verify an AVM proof.
Definition verifier.cpp:52
Flavor::Commitment Commitment
Definition verifier.hpp:17
#define vinfo(...)
Definition log.hpp:94
constexpr auto WIRES_TO_BE_SHIFTED_END_IDX
Definition columns.hpp:67
constexpr std::size_t MAX_AVM_TRACE_SIZE
Definition constants.hpp:13
constexpr std::size_t MAX_AVM_TRACE_LOG_SIZE
Definition constants.hpp:12
constexpr auto WIRES_TO_BE_SHIFTED_START_IDX
Definition columns.hpp:66
ColumnAndShifts
Definition columns.hpp:34
std::vector< fr > HonkProof
Definition proof.hpp:15
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
Logic to support batching opening claims for unshifted, shifted and interleaved polynomials in Shplem...
Container for parameters used by the grand product (permutation, lookup) Honk relations.
Contains the evaluations of multilinear polynomials at the challenge point . These are computed by S...
ClaimedEvaluations claimed_evaluations
std::vector< FF > challenge