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;
51 using ClaimBatcher = ClaimBatcher_<Curve>;
52 using ClaimBatch = ClaimBatcher::Batch;
54
55 RelationParameters<FF> relation_parameters;
56
57 transcript->load_proof(proof);
58
59 FF vk_hash = key->hash();
60 transcript->add_to_hash_buffer("avm_vk_hash", vk_hash);
61 vinfo("AVM vk hash in verifier: ", vk_hash);
62
63 // Check public inputs size.
64 if (public_inputs.size() != AVM_NUM_PUBLIC_INPUT_COLUMNS) {
65 vinfo("Public inputs size mismatch");
66 return false;
67 }
68 // Public inputs from proof
69 for (size_t i = 0; i < AVM_NUM_PUBLIC_INPUT_COLUMNS; i++) {
70 if (public_inputs[i].size() != AVM_PUBLIC_INPUTS_COLUMNS_MAX_LENGTH) {
71 vinfo("Public input size mismatch");
72 return false;
73 }
74 for (size_t j = 0; j < public_inputs[i].size(); j++) {
75 transcript->add_to_hash_buffer("public_input_" + std::to_string(i) + "_" + std::to_string(j),
76 public_inputs[i][j]);
77 }
78 }
79 VerifierCommitments commitments{ key };
80 // Get commitments to VM wires
81 for (auto [comm, label] : zip_view(commitments.get_wires(), commitments.get_wires_labels())) {
82 comm = transcript->template receive_from_prover<Commitment>(label);
83 }
84
85 auto [beta, gamma] = transcript->template get_challenges<FF>(std::array<std::string, 2>{ "beta", "gamma" });
86 relation_parameters.beta = beta;
87 relation_parameters.gamma = gamma;
88
89 // Get commitments to inverses
90 for (auto [label, commitment] : zip_view(commitments.get_derived_labels(), commitments.get_derived())) {
91 commitment = transcript->template receive_from_prover<Commitment>(label);
92 }
93
94 // Execute Sumcheck Verifier
95 std::vector<FF> padding_indicator_array(key->log_circuit_size, 1);
96
97 // Multiply each linearly independent subrelation contribution by `alpha^i` for i = 0, ..., NUM_SUBRELATIONS - 1.
98 const FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");
99
100 SumcheckVerifier<Flavor> sumcheck(transcript, alpha, key->log_circuit_size);
101
102 // Get the gate challenges for sumcheck computation
103 std::vector<FF> gate_challenges =
104 transcript->template get_dyadic_powers_of_challenge<FF>("Sumcheck:gate_challenge", key->log_circuit_size);
105
106 SumcheckOutput<Flavor> output = sumcheck.verify(relation_parameters, gate_challenges, padding_indicator_array);
107
108 // If Sumcheck did not verify, return false
109 if (!output.verified) {
110 vinfo("Sumcheck verification failed");
111 return false;
112 }
113
114 using C = ColumnAndShifts;
116 output.claimed_evaluations.get(C::public_inputs_cols_0_),
117 output.claimed_evaluations.get(C::public_inputs_cols_1_),
118 output.claimed_evaluations.get(C::public_inputs_cols_2_),
119 output.claimed_evaluations.get(C::public_inputs_cols_3_),
120 };
121 for (size_t i = 0; i < AVM_NUM_PUBLIC_INPUT_COLUMNS; i++) {
122 FF public_input_evaluation = evaluate_public_input_column(public_inputs[i], output.challenge);
123 if (public_input_evaluation != claimed_evaluations[i]) {
124 vinfo("public_input_evaluation failed, public inputs col ", i);
125 return false;
126 }
127 }
128
129 // Batch commitments and evaluations using short scalars to reduce ECCVM circuit size
130 std::span<const Commitment> unshifted_comms = commitments.get_unshifted();
131 std::span<const FF> unshifted_evals = output.claimed_evaluations.get_unshifted();
132 std::span<const Commitment> shifted_comms = commitments.get_to_be_shifted();
133 std::span<const FF> shifted_evals = output.claimed_evaluations.get_shifted();
134
135 // Generate batching challenge labels
136 // Note: We get N-1 challenges for N unshifted commitments (first commitment has implicit coefficient 1)
137 std::vector<std::string> unshifted_batching_challenge_labels;
138 unshifted_batching_challenge_labels.reserve(unshifted_comms.size() - 1);
139 for (size_t idx = 0; idx < unshifted_comms.size() - 1; idx++) {
140 unshifted_batching_challenge_labels.push_back("rho_" + std::to_string(idx));
141 }
142 std::vector<std::string> shifted_batching_challenge_labels;
143 shifted_batching_challenge_labels.reserve(shifted_comms.size());
144 for (size_t idx = 0; idx < shifted_comms.size(); idx++) {
145 shifted_batching_challenge_labels.push_back("rho_" + std::to_string(unshifted_comms.size() - 1 + idx));
146 }
147
148 // Get short batching challenges from transcript
149 auto unshifted_challenges = transcript->template get_challenges<FF>(unshifted_batching_challenge_labels);
150 auto shifted_challenges = transcript->template get_challenges<FF>(shifted_batching_challenge_labels);
151
152 // Batch commitments: first commitment has coefficient 1, rest are batched with challenges
153 Commitment squashed_unshifted =
154 unshifted_comms[0] + batch_mul_native<Curve>(unshifted_comms.subspan(1), unshifted_challenges);
155
156 Commitment squashed_shifted = batch_mul_native<Curve>(shifted_comms, shifted_challenges);
157
158 // Batch evaluations: compute inner product with first eval as initial value for unshifted
159 FF squashed_unshifted_eval = std::inner_product(
160 unshifted_challenges.begin(), unshifted_challenges.end(), unshifted_evals.begin() + 1, unshifted_evals[0]);
161
162 FF squashed_shifted_eval =
163 std::inner_product(shifted_challenges.begin(), shifted_challenges.end(), shifted_evals.begin(), FF(0));
164
165 // Execute Shplemini rounds with squashed claims
166 ClaimBatcher squashed_claim_batcher{ .unshifted = ClaimBatch{ .commitments = RefVector(squashed_unshifted),
167 .evaluations = RefVector(squashed_unshifted_eval) },
168 .shifted = ClaimBatch{ .commitments = RefVector(squashed_shifted),
169 .evaluations = RefVector(squashed_shifted_eval) } };
170 auto opening_claim =
171 Shplemini::compute_batch_opening_claim(
172 padding_indicator_array, squashed_claim_batcher, output.challenge, Commitment::one(), transcript)
173 .batch_opening_claim;
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
IPA (inner product argument) commitment scheme class.
Definition ipa.hpp:93
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: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
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
AvmFlavorSettings::FF FF
Definition flavor.hpp:36
AvmFlavorSettings::VerifierCommitmentKey VerifierCommitmentKey
Definition flavor.hpp:43
VerifierCommitments_< Commitment, VerificationKey > VerifierCommitments
Definition flavor.hpp:367
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:94
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, 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