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: 0e37cb8}
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;
60 using Challenges = Flavor::AllEntities<FF>;
61
62 RelationParameters<FF> relation_parameters;
63
64 transcript->load_proof(proof);
65
66 // ========== Execute preamble round ==========
67
68 // Add vk hash to transcript
69 FF vk_hash = key->get_hash();
70 transcript->add_to_hash_buffer("avm_vk_hash", vk_hash);
71 vinfo("AVM vk hash in verifier: ", vk_hash);
72
73 // ========== Execute public inputs round ==========
74
75 // Validate number of public input columns
76 if (public_inputs.size() != AVM_NUM_PUBLIC_INPUT_COLUMNS) {
77 vinfo("Public inputs size mismatch");
78 return false;
79 }
80
81 // Add public inputs to transcript. This ensures that the Sumcheck challenge depends both on the public inputs sent
82 // in the clear and on the committed columns.
83 for (size_t i = 0; i < AVM_NUM_PUBLIC_INPUT_COLUMNS; i++) {
84 // Validate public input column size
85 if (public_inputs[i].size() != AVM_PUBLIC_INPUTS_COLUMNS_MAX_LENGTH) {
86 vinfo("Public input size mismatch");
87 return false;
88 }
89 for (size_t j = 0; j < public_inputs[i].size(); j++) {
90 transcript->add_to_hash_buffer("public_input_" + std::to_string(i) + "_" + std::to_string(j),
91 public_inputs[i][j]);
92 }
93 }
94
95 // ========== Execute wire commitments round ==========
96
97 // Receive commitments to all polynomials except the logderivate ones
98 VerifierCommitments commitments{ key };
99 for (auto [comm, label] : zip_view(commitments.get_wires(), commitments.get_wires_labels())) {
100 comm = transcript->template receive_from_prover<Commitment>(label);
101 }
102
103 // ========== Execute log derivative inverse round ==========
104
105 // Generate randomness required by Lookup and Permutation relations
106 auto [beta, gamma] = transcript->template get_challenges<FF>(std::array<std::string, 2>{ "beta", "gamma" });
107 relation_parameters.beta = beta;
108 relation_parameters.gamma = gamma;
109
110 // Receive commitments to all logderivative inverse polynomials
111 for (auto [commitment, label] : zip_view(commitments.get_derived(), commitments.get_derived_labels())) {
112 commitment = transcript->template receive_from_prover<Commitment>(label);
113 }
114
115 // ========== Execute relation check rounds ==========
116
117 // Multiply each linearly independent subrelation contribution by `alpha^i` for i = 0, ..., NUM_SUBRELATIONS - 1.
118 const FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");
119
121
122 // Get the gate challenges for sumcheck computation
123 std::vector<FF> gate_challenges =
124 transcript->template get_dyadic_powers_of_challenge<FF>("Sumcheck:gate_challenge", MAX_AVM_TRACE_LOG_SIZE);
125 SumcheckOutput<Flavor> output = sumcheck.verify(relation_parameters, gate_challenges);
126
127 // If Sumcheck did not verify, return false
128 if (!output.verified) {
129 vinfo("Sumcheck verification failed");
130 return false;
131 }
132
133 // Validate that the public inputs committed in the public input columns match the public inputs sent in the clear
134 // by the Prover
135 using C = ColumnAndShifts;
137 output.claimed_evaluations.get(C::public_inputs_cols_0_),
138 output.claimed_evaluations.get(C::public_inputs_cols_1_),
139 output.claimed_evaluations.get(C::public_inputs_cols_2_),
140 output.claimed_evaluations.get(C::public_inputs_cols_3_),
141 };
142 for (size_t idx = 0;
143 const auto& [public_input_column, claimed_evaluation] : zip_view(public_inputs, claimed_evaluations)) {
144 FF public_input_evaluation = evaluate_public_input_column(public_input_column, output.challenge);
145 if (public_input_evaluation != claimed_evaluation) {
146 vinfo("public_input_evaluation failed, public inputs col ", idx);
147 return false;
148 }
149 idx++;
150 }
151
152 // ========== Execute PCS verification ==========
153
154 // Batch commitments and evaluations using short scalars to reduce ECCVM circuit size
155 std::span<const Commitment> unshifted_comms = commitments.get_unshifted();
156 std::span<const FF> unshifted_evals = output.claimed_evaluations.get_unshifted();
157 std::span<const Commitment> shifted_comms = commitments.get_to_be_shifted();
158 std::span<const FF> shifted_evals = output.claimed_evaluations.get_shifted();
159
160 // Get short batching challenges from transcript
161 Challenges challenges;
162 auto unshifted_challenges_vec = transcript->template get_challenges<FF>(challenges.get_unshifted_labels());
163 std::ranges::move(unshifted_challenges_vec, challenges.get_unshifted().begin());
164 auto unshifted_challenges = challenges.get_unshifted();
165 auto shifted_challenges = challenges.get_to_be_shifted();
166
167 // Batch shifted commitments
168 Commitment batched_shifted = Commitment::batch_mul(shifted_comms, shifted_challenges);
169
170 // Batch unshifted commitments: We reuse the calculation performed for shifted commitments.
171 Commitment batched_unshifted =
172 batched_shifted +
173 Commitment::batch_mul(unshifted_comms.subspan(0, WIRES_TO_BE_SHIFTED_START_IDX),
174 unshifted_challenges.subspan(0, WIRES_TO_BE_SHIFTED_START_IDX)) +
175 Commitment::batch_mul(unshifted_comms.subspan(WIRES_TO_BE_SHIFTED_END_IDX),
176 unshifted_challenges.subspan(WIRES_TO_BE_SHIFTED_END_IDX));
177
178 // Batch evaluations: compute inner product with first eval as initial value for unshifted
179 FF batched_unshifted_eval =
180 std::inner_product(unshifted_challenges.begin(), unshifted_challenges.end(), unshifted_evals.begin(), FF(0));
181
182 FF batched_shifted_eval =
183 std::inner_product(shifted_challenges.begin(), shifted_challenges.end(), shifted_evals.begin(), FF(0));
184
185 // Execute Shplemini rounds with batched claims
186 ClaimBatcher batched_claim_batcher{ .unshifted = ClaimBatch{ .commitments = RefVector(batched_unshifted),
187 .evaluations = RefVector(batched_unshifted_eval) },
188 .shifted = ClaimBatch{ .commitments = RefVector(batched_shifted),
189 .evaluations = RefVector(batched_shifted_eval) } };
190 auto opening_claim =
191 Shplemini::compute_batch_opening_claim(batched_claim_batcher, output.challenge, Commitment::one(), transcript)
192 .batch_opening_claim;
193
194 const auto pairing_points = PCS::reduce_verify_batch_opening_claim(std::move(opening_claim), transcript);
195 const auto shplemini_verified = pairing_points.check();
196
197 if (!shplemini_verified) {
198 vinfo("Shplemini verification failed");
199 return false;
200 }
201
202 return true;
203}
204
205} // 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:86
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:804
SumcheckOutput< Flavor > verify(const bb::RelationParameters< FF > &relation_parameters, const std::vector< FF > &gate_challenges)
The Sumcheck verification method. First it extracts round univariate, checks sum (the sumcheck univar...
Definition sumcheck.hpp:859
VerifierCommitments_< Commitment, VerificationKey > VerifierCommitments
Definition flavor.hpp:322
AvmFlavorSettings::PCS PCS
Definition flavor.hpp:41
AvmFlavorSettings::Curve Curve
Definition flavor.hpp:39
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 and shifted polynomials in Shplemini.
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