Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
verifier.cpp
Go to the documentation of this file.
2
8#include <numeric>
9
10namespace bb::avm2 {
11
13 : key(std::move(verifier_key))
14{}
15
17 : key(std::move(other.key))
18 , transcript(std::move(other.transcript))
19{}
20
22{
23 key = other.key;
24 transcript = other.transcript;
25 commitments.clear();
26 return *this;
27}
28
29using FF = AvmFlavor::FF;
30
31// Evaluate the given public input column over the multivariate challenge points
32inline FF AvmVerifier::evaluate_public_input_column(const std::vector<FF>& points, std::vector<FF> challenges)
33{
34 Polynomial<FF> polynomial(points, (1 << key->log_circuit_size));
35 return polynomial.evaluate_mle(challenges);
36}
37
42bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vector<std::vector<FF>>& public_inputs)
43{
44 using Flavor = AvmFlavor;
45 using FF = Flavor::FF;
47 using PCS = Flavor::PCS;
48 using Curve = Flavor::Curve;
49 using VerifierCommitments = Flavor::VerifierCommitments;
50 using Shplemini = ShpleminiVerifier_<Curve>;
51 using ClaimBatcher = ClaimBatcher_<Curve>;
52 using ClaimBatch = ClaimBatcher::Batch;
54
55 RelationParameters<FF> relation_parameters;
56
57 transcript->load_proof(proof);
58
59 // TODO(#15892): Fiat-Shamir the vk hash by uncommenting the line below.
60 FF vk_hash = key->hash();
61 // transcript->add_to_hash_buffer("avm_vk_hash", vk_hash);
62 vinfo("AVM vk hash in verifier: ", vk_hash);
63
64 // Check public inputs size.
65 if (public_inputs.size() != AVM_NUM_PUBLIC_INPUT_COLUMNS) {
66 vinfo("Public inputs size mismatch");
67 return false;
68 }
69 // Public inputs from proof
70 for (size_t i = 0; i < AVM_NUM_PUBLIC_INPUT_COLUMNS; i++) {
71 if (public_inputs[i].size() != AVM_PUBLIC_INPUTS_COLUMNS_MAX_LENGTH) {
72 vinfo("Public input size mismatch");
73 return false;
74 }
75 // TODO(https://github.com/AztecProtocol/aztec-packages/pull/17045): make the protocols secure at some point
76 // for (size_t j = 0; j < public_inputs[i].size(); j++) {
77 // transcript->add_to_hash_buffer("public_input_" + std::to_string(i) + "_" + std::to_string(j),
78 // public_inputs[i][j]);
79 // }
80 }
81 VerifierCommitments commitments{ key };
82 // Get commitments to VM wires
83 for (auto [comm, label] : zip_view(commitments.get_wires(), commitments.get_wires_labels())) {
84 comm = transcript->template receive_from_prover<Commitment>(label);
85 }
86
87 auto [beta, gamma] = transcript->template get_challenges<FF>(std::array<std::string, 2>{ "beta", "gamma" });
88 relation_parameters.beta = beta;
89 relation_parameters.gamma = gamma;
90
91 // Get commitments to inverses
92 for (auto [label, commitment] : zip_view(commitments.get_derived_labels(), commitments.get_derived())) {
93 commitment = transcript->template receive_from_prover<Commitment>(label);
94 }
95
96 // Execute Sumcheck Verifier
97 std::vector<FF> padding_indicator_array(key->log_circuit_size, 1);
98
99 // Multiply each linearly independent subrelation contribution by `alpha^i` for i = 0, ..., NUM_SUBRELATIONS - 1.
100 const FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");
101
102 SumcheckVerifier<Flavor> sumcheck(transcript, alpha, key->log_circuit_size);
103
104 // Get the gate challenges for sumcheck computation
105 std::vector<FF> gate_challenges =
106 transcript->template get_dyadic_powers_of_challenge<FF>("Sumcheck:gate_challenge", key->log_circuit_size);
107
108 SumcheckOutput<Flavor> output = sumcheck.verify(relation_parameters, gate_challenges, padding_indicator_array);
109
110 // If Sumcheck did not verify, return false
111 if (!output.verified) {
112 vinfo("Sumcheck verification failed");
113 return false;
114 }
115
116 using C = ColumnAndShifts;
118 output.claimed_evaluations.get(C::public_inputs_cols_0_),
119 output.claimed_evaluations.get(C::public_inputs_cols_1_),
120 output.claimed_evaluations.get(C::public_inputs_cols_2_),
121 output.claimed_evaluations.get(C::public_inputs_cols_3_),
122 };
123 for (size_t i = 0; i < AVM_NUM_PUBLIC_INPUT_COLUMNS; i++) {
124 FF public_input_evaluation = evaluate_public_input_column(public_inputs[i], output.challenge);
125 if (public_input_evaluation != claimed_evaluations[i]) {
126 vinfo("public_input_evaluation failed, public inputs col ", i);
127 return false;
128 }
129 }
130
131 // Batch commitments and evaluations using short scalars to reduce ECCVM circuit size
132 std::span<const Commitment> unshifted_comms = commitments.get_unshifted();
133 std::span<const FF> unshifted_evals = output.claimed_evaluations.get_unshifted();
134 std::span<const Commitment> shifted_comms = commitments.get_to_be_shifted();
135 std::span<const FF> shifted_evals = output.claimed_evaluations.get_shifted();
136
137 // Generate batching challenge labels
138 // Note: We get N-1 challenges for N unshifted commitments (first commitment has implicit coefficient 1)
139 std::vector<std::string> unshifted_batching_challenge_labels;
140 unshifted_batching_challenge_labels.reserve(unshifted_comms.size() - 1);
141 for (size_t idx = 0; idx < unshifted_comms.size() - 1; idx++) {
142 unshifted_batching_challenge_labels.push_back("rho_" + std::to_string(idx));
143 }
144 std::vector<std::string> shifted_batching_challenge_labels;
145 shifted_batching_challenge_labels.reserve(shifted_comms.size());
146 for (size_t idx = 0; idx < shifted_comms.size(); idx++) {
147 shifted_batching_challenge_labels.push_back("rho_" + std::to_string(unshifted_comms.size() - 1 + idx));
148 }
149
150 // Get short batching challenges from transcript
151 auto unshifted_challenges = transcript->template get_challenges<FF>(unshifted_batching_challenge_labels);
152 auto shifted_challenges = transcript->template get_challenges<FF>(shifted_batching_challenge_labels);
153
154 // Batch commitments: first commitment has coefficient 1, rest are batched with challenges
155 Commitment squashed_unshifted =
156 unshifted_comms[0] + batch_mul_native<Curve>(unshifted_comms.subspan(1), unshifted_challenges);
157
158 Commitment squashed_shifted = batch_mul_native<Curve>(shifted_comms, shifted_challenges);
159
160 // Batch evaluations: compute inner product with first eval as initial value for unshifted
161 FF squashed_unshifted_eval = std::inner_product(
162 unshifted_challenges.begin(), unshifted_challenges.end(), unshifted_evals.begin() + 1, unshifted_evals[0]);
163
164 FF squashed_shifted_eval =
165 std::inner_product(shifted_challenges.begin(), shifted_challenges.end(), shifted_evals.begin(), FF(0));
166
167 // Execute Shplemini rounds with squashed claims
168 ClaimBatcher squashed_claim_batcher{ .unshifted = ClaimBatch{ .commitments = RefVector(squashed_unshifted),
169 .evaluations = RefVector(squashed_unshifted_eval) },
170 .shifted = ClaimBatch{ .commitments = RefVector(squashed_shifted),
171 .evaluations = RefVector(squashed_shifted_eval) } };
172 auto opening_claim = Shplemini::compute_batch_opening_claim(
173 padding_indicator_array, squashed_claim_batcher, output.challenge, Commitment::one(), transcript);
174
175 const auto pairing_points = PCS::reduce_verify_batch_opening_claim(std::move(opening_claim), transcript);
176 VerifierCommitmentKey pcs_vkey{};
177 const auto shplemini_verified = pcs_vkey.pairing_check(pairing_points[0], pairing_points[1]);
178
179 if (!shplemini_verified) {
180 vinfo("Shplemini verification failed");
181 return false;
182 }
183
184 return true;
185}
186
187} // namespace bb::avm2
#define AVM_NUM_PUBLIC_INPUT_COLUMNS
#define AVM_PUBLIC_INPUTS_COLUMNS_MAX_LENGTH
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.
An efficient verifier for the evaluation proofs of multilinear polynomials and their shifts.
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:786
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:844
AvmFlavorSettings::FF FF
Definition flavor.hpp:36
AvmFlavorSettings::VerifierCommitmentKey VerifierCommitmentKey
Definition flavor.hpp:43
VerifierCommitments_< Commitment, VerificationKey > VerifierCommitments
Definition flavor.hpp:351
AvmFlavorSettings::PCS PCS
Definition flavor.hpp:34
AvmFlavorSettings::Commitment Commitment
Definition flavor.hpp:40
AvmFlavorSettings::Curve Curve
Definition flavor.hpp:32
AvmVerifier(std::shared_ptr< VerificationKey > verifier_key)
Definition verifier.cpp:12
std::shared_ptr< Transcript > transcript
Definition verifier.hpp:31
AvmVerifier & operator=(const AvmVerifier &other)=delete
FF evaluate_public_input_column(const std::vector< FF > &points, std::vector< FF > challenges)
Definition verifier.cpp:32
std::shared_ptr< VerificationKey > key
Definition verifier.hpp:29
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:42
std::map< std::string, Commitment > commitments
Definition verifier.hpp:30
Flavor::Commitment Commitment
Definition verifier.hpp:12
#define vinfo(...)
Definition log.hpp:80
ColumnAndShifts
Definition columns.hpp:34
AvmFlavorSettings::FF FF
Definition field.hpp:10
std::vector< fr > HonkProof
Definition proof.hpp:15
STL namespace.
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