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