Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
eccvm_verifier.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
12
13namespace bb {
14
20{
21 using Curve = typename Flavor::Curve;
22 using Shplemini = ShpleminiVerifier_<Curve>;
23 using Shplonk = ShplonkVerifier_<Curve>;
25 using ClaimBatcher = ClaimBatcher_<Curve>;
26 using ClaimBatch = typename ClaimBatcher::Batch;
27
28 RelationParameters<FF> relation_parameters;
29
30 // Load proof into transcript
31 transcript->load_proof(proof);
32
33 // Fiat-Shamir the vk hash (computed in constructor)
34 transcript->add_to_hash_buffer("vk_hash", vk_hash);
35 vinfo("ECCVM vk hash: ", vk_hash);
36
37 VerifierCommitments commitments{ key };
38 CommitmentLabels commitment_labels;
39
40 // Receive Gemini masking polynomial commitment (for ZK-PCS)
41 commitments.gemini_masking_poly = transcript->template receive_from_prover<Commitment>("Gemini:masking_poly_comm");
42 for (auto [comm, label] : zip_view(commitments.get_wires(), commitment_labels.get_wires())) {
43 comm = transcript->template receive_from_prover<Commitment>(label);
44 }
45
46 // Get challenge for sorted list batching and wire four memory records
47 auto [beta, gamma] = transcript->template get_challenges<FF>(std::array<std::string, 2>{ "beta", "gamma" });
48
49 auto beta_sqr = beta * beta;
50 relation_parameters.gamma = gamma;
51 relation_parameters.beta = beta;
52 relation_parameters.beta_sqr = beta * beta;
53 relation_parameters.beta_cube = beta_sqr * beta;
54 relation_parameters.eccvm_set_permutation_delta =
55 gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr);
56 relation_parameters.eccvm_set_permutation_delta = relation_parameters.eccvm_set_permutation_delta.invert();
57
58 // Get commitment to permutation and lookup grand products
59 commitments.lookup_inverses =
60 transcript->template receive_from_prover<Commitment>(commitment_labels.lookup_inverses);
61 commitments.z_perm = transcript->template receive_from_prover<Commitment>(commitment_labels.z_perm);
62
63 // Each linearly independent subrelation contribution is multiplied by `alpha^i`, where
64 // i = 0, ..., NUM_SUBRELATIONS- 1.
65 const FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");
66
67 // Execute Sumcheck Verifier
68 SumcheckVerifier<Flavor> sumcheck(transcript, alpha, CONST_ECCVM_LOG_N);
69
70 std::vector<FF> gate_challenges(CONST_ECCVM_LOG_N);
71 for (size_t idx = 0; idx < gate_challenges.size(); idx++) {
72 gate_challenges[idx] = transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx));
73 }
74
75 // Receive commitments to Libra masking polynomials
77
78 libra_commitments[0] = transcript->template receive_from_prover<Commitment>("Libra:concatenation_commitment");
79 std::vector<FF> padding_indicator_array(CONST_ECCVM_LOG_N, FF(1));
80
81 auto sumcheck_output = sumcheck.verify(relation_parameters, gate_challenges, padding_indicator_array);
82
83 libra_commitments[1] = transcript->template receive_from_prover<Commitment>("Libra:grand_sum_commitment");
84 libra_commitments[2] = transcript->template receive_from_prover<Commitment>("Libra:quotient_commitment");
85
86 // Compute the Shplemini accumulator consisting of the Shplonk evaluation and the commitments and scalars vector
87 // produced by the unified protocol
88 consistency_checked = true;
89 ClaimBatcher claim_batcher{
90 .unshifted = ClaimBatch{ commitments.get_unshifted(), sumcheck_output.claimed_evaluations.get_unshifted() },
91 .shifted = ClaimBatch{ commitments.get_to_be_shifted(), sumcheck_output.claimed_evaluations.get_shifted() }
92 };
93
94 BatchOpeningClaim<Curve> sumcheck_batch_opening_claims =
95 Shplemini::compute_batch_opening_claim(padding_indicator_array,
96 claim_batcher,
97 sumcheck_output.challenge,
98 key->pcs_verification_key.get_g1_identity(),
99 transcript,
102 &consistency_checked,
103 libra_commitments,
104 sumcheck_output.claimed_libra_evaluation,
105 sumcheck_output.round_univariate_commitments,
106 sumcheck_output.round_univariate_evaluations);
107
108 // Reduce the accumulator to a single opening claim
109 OpeningClaim multivariate_to_univariate_opening_claim =
110 PCS::reduce_batch_opening_claim(sumcheck_batch_opening_claims);
111
112 // Produce the opening claim for batch opening of `op`, `Px`, `Py`, `z1`, and `z2` wires as univariate
113 // polynomials
114
115 std::vector<Commitment> translation_commitments = { commitments.transcript_op,
116 commitments.transcript_Px,
117 commitments.transcript_Py,
118 commitments.transcript_z1,
119 commitments.transcript_z2 };
120 compute_translation_opening_claims(translation_commitments);
121
122 opening_claims.back() = multivariate_to_univariate_opening_claim;
123
124 // Construct the combined opening claim
125 const OpeningClaim batch_opening_claim =
126 Shplonk::reduce_verification(key->pcs_verification_key.get_g1_identity(), opening_claims, transcript);
127
128 sumcheck_verified = sumcheck_output.verified;
129 vinfo("eccvm sumcheck verified?: ", sumcheck_verified);
130 vinfo("eccvm consistency check verified?: ", consistency_checked);
131 vinfo("translation masking consistency checked?: ", translation_masking_consistency_checked);
132
133 compute_accumulated_result();
134
135 return batch_opening_claim;
136}
137
147template <typename Flavor>
148void ECCVMVerifier_<Flavor>::compute_translation_opening_claims(const std::vector<Commitment>& translation_commitments)
149{
150 // Used to capture the batched evaluation of unmasked `translation_polynomials` while preserving ZK
151 using SmallIPA = SmallSubgroupIPAVerifier<Curve>;
152
153 // Initialize SmallSubgroupIPA structures
154 SmallSubgroupIPACommitments<Commitment> small_ipa_commitments;
155 std::array<FF, NUM_SMALL_IPA_EVALUATIONS> small_ipa_evaluations;
156 const auto labels = SmallIPA::evaluation_labels("Translation:");
157
158 // Get a commitment to M + Z_H * R, where M is a concatenation of the masking terms of
159 // `translation_polynomials`, Z_H = X^{|H|} - 1, and R is a random degree 2 polynomial
160 small_ipa_commitments.concatenated =
161 transcript->template receive_from_prover<Commitment>("Translation:concatenated_masking_term_commitment");
162
163 // Get a challenge to evaluate `translation_polynomials` as univariates
164 evaluation_challenge_x = transcript->template get_challenge<FF>("Translation:evaluation_challenge_x");
165
166 // Populate the translation evaluations {`op(x)`, `Px(x)`, `Py(x)`, `z1(x)`, `z2(x)`} to be batched
167 for (auto [eval, label] : zip_view(translation_evaluations.get_all(), translation_evaluations.labels)) {
168 eval = transcript->template receive_from_prover<FF>(label);
169 }
170
171 // Get the batching challenge for commitments and evaluations
172 batching_challenge_v = transcript->template get_challenge<FF>("Translation:batching_challenge_v");
173
174 // Get the value ∑ mᵢ(x) ⋅ vⁱ
175 translation_masking_term_eval = transcript->template receive_from_prover<FF>("Translation:masking_term_eval");
176
177 // Receive commitments to the SmallSubgroupIPA witnesses that are computed once x and v are available
178 small_ipa_commitments.grand_sum =
179 transcript->template receive_from_prover<Commitment>("Translation:grand_sum_commitment");
180 small_ipa_commitments.quotient =
181 transcript->template receive_from_prover<Commitment>("Translation:quotient_commitment");
182
183 // Get a challenge for the evaluations of the concatenated masking term G, grand sum A, its shift, and grand sum
184 // identity quotient Q
185 const FF small_ipa_evaluation_challenge =
186 transcript->template get_challenge<FF>("Translation:small_ipa_evaluation_challenge");
187
188 // Compute {r, r * g, r, r}, where r = `small_ipa_evaluation_challenge`
190 SmallIPA::evaluation_points(small_ipa_evaluation_challenge);
191
192 // Get the evaluations G(r), A(g * r), A(r), Q(r)
193 for (size_t idx = 0; idx < NUM_SMALL_IPA_EVALUATIONS; idx++) {
194 small_ipa_evaluations[idx] = transcript->template receive_from_prover<FF>(labels[idx]);
195 opening_claims[idx] = { { evaluation_points[idx], small_ipa_evaluations[idx] },
196 small_ipa_commitments.get_all()[idx] };
197 }
198
199 // OriginTag false positive: Small IPA evaluations need to satisfy an identity where they are mixing without
200 // challenges, it is safe because these evaluations are opened in Shplonk.
201 if constexpr (IsRecursive) {
202 for (auto& eval : small_ipa_evaluations) {
203 eval.clear_round_provenance();
204 }
205 }
206
207 // Check Grand Sum Identity at r
208
209 translation_masking_consistency_checked =
210 SmallIPA::check_eccvm_evaluations_consistency(small_ipa_evaluations,
211 small_ipa_evaluation_challenge,
212 evaluation_challenge_x,
213 batching_challenge_v,
214 translation_masking_term_eval);
215
216 // Compute the batched commitment and batched evaluation for the univariate opening claim
217 FF batched_translation_evaluation = translation_evaluations.get_all()[0];
218 FF batching_scalar = batching_challenge_v;
219
220 Commitment batched_commitment;
221 std::vector<FF> batching_challenges = { FF::one() };
222 for (size_t idx = 1; idx < NUM_TRANSLATION_EVALUATIONS; ++idx) {
223 batched_translation_evaluation += batching_scalar * translation_evaluations.get_all()[idx];
224 batching_challenges.push_back(batching_scalar);
225 batching_scalar *= batching_challenge_v;
226 }
227 if constexpr (IsRecursive) {
228 batched_commitment = Commitment::batch_mul(translation_commitments, batching_challenges);
229 } else {
230 batched_commitment = batch_mul_native<Curve>(translation_commitments, batching_challenges);
231 }
232
233 // Place the claim to the array containing the SmallSubgroupIPA opening claims
234 opening_claims[NUM_SMALL_IPA_EVALUATIONS] = { { evaluation_challenge_x, batched_translation_evaluation },
235 batched_commitment };
236
237 // Compute `translation_masking_term_eval` * `evaluation_challenge_x`^{circuit_size -
238 // NUM_DISABLED_ROWS_IN_SUMCHECK}
239 shift_translation_masking_term_eval(evaluation_challenge_x, translation_masking_term_eval);
240}
241
242// Compute the accumulated result from translation evaluations
243// This is the value that Translator will use in its relations
244// Formula: accumulated_result = (op + v*Px + v²*Py + v³*z1 + v⁴*z2 - masking_term) / x
246{
247 FF v = batching_challenge_v;
248 FF v_squared = v * v;
249 FF v_cubed = v_squared * v;
250 FF v_fourth = v_cubed * v;
251
252 FF batched_eval_minus_masking = translation_evaluations.op + v * translation_evaluations.Px +
253 v_squared * translation_evaluations.Py + v_cubed * translation_evaluations.z1 +
254 v_fourth * translation_evaluations.z2 - translation_masking_term_eval;
255
256 accumulated_result = batched_eval_minus_masking / evaluation_challenge_x;
257}
258
259// Explicit template instantiations
260template class ECCVMVerifier_<ECCVMFlavor>;
262
263} // namespace bb
bb::field< bb::Bn254FrParams > FF
Definition field.cpp:22
A container for commitment labels.
static constexpr bool HasZK
curve::Grumpkin Curve
static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS
Unified ECCVM verifier class for both native and recursive verification.
void compute_translation_opening_claims(const std::vector< Commitment > &translation_commitments)
To link the ECCVM Transcript wires op, Px, Py, z1, and z2 to the accumulator computed by the translat...
OpeningClaim< Curve > verify_proof()
Verifies an ECCVM Honk proof for given program settings.
Flavor::Commitment Commitment
Unverified claim (C,r,v) for some witness polynomial p(X) such that.
Definition claim.hpp:53
An efficient verifier for the evaluation proofs of multilinear polynomials and their shifts.
Shplonk Verifier.
Definition shplonk.hpp:343
Verifies the consistency of polynomial evaluations provided by the the prover.
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
#define vinfo(...)
Definition log.hpp:80
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
An accumulator consisting of the Shplonk evaluation challenge and vectors of commitments and scalars.
Definition claim.hpp:169
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 commitments to polynomials [G], [A], and [Q]. See SmallSubgroupIPAProver docs.
RefArray< Commitment, NUM_SMALL_IPA_EVALUATIONS > get_all()