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 key->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 =
125 Shplonk::reduce_verification(key->pcs_g1_identity, opening_claims, transcript);
126
127 bool sumcheck_verified = sumcheck_output.verified;
128 vinfo("ECCVM Verifier: sumcheck verified: ", sumcheck_verified);
129 vinfo("ECCVM Verifier: consistency checked: ", consistency_checked);
130 vinfo("ECCVM Verifier: translation masking consistency checked: ", translation_masking_consistency_checked);
131
132 compute_accumulated_result();
133
134 return { batch_opening_claim, sumcheck_verified && consistency_checked && translation_masking_consistency_checked };
135}
136
146template <typename Flavor>
147void ECCVMVerifier_<Flavor>::compute_translation_opening_claims(const std::vector<Commitment>& translation_commitments)
148{
149 // Used to capture the batched evaluation of unmasked `translation_polynomials` while preserving ZK
150 using SmallIPA = SmallSubgroupIPAVerifier<Curve>;
151
152 // Initialize SmallSubgroupIPA structures
153 SmallSubgroupIPACommitments<Commitment> small_ipa_commitments;
154 std::array<FF, NUM_SMALL_IPA_EVALUATIONS> small_ipa_evaluations;
155 const auto labels = SmallIPA::evaluation_labels("Translation:");
156
157 // Get a commitment to M + Z_H * R, where M is a concatenation of the masking terms of
158 // `translation_polynomials`, Z_H = X^{|H|} - 1, and R is a random degree 2 polynomial
159 small_ipa_commitments.concatenated =
160 transcript->template receive_from_prover<Commitment>("Translation:concatenated_masking_term_commitment");
161
162 // Get a challenge to evaluate `translation_polynomials` as univariates
163 evaluation_challenge_x = transcript->template get_challenge<FF>("Translation:evaluation_challenge_x");
164
165 // Populate the translation evaluations {`op(x)`, `Px(x)`, `Py(x)`, `z1(x)`, `z2(x)`} to be batched
166 for (auto [eval, label] : zip_view(translation_evaluations.get_all(), translation_evaluations.labels)) {
167 eval = transcript->template receive_from_prover<FF>(label);
168 }
169
170 // Get the batching challenge for commitments and evaluations
171 batching_challenge_v = transcript->template get_challenge<FF>("Translation:batching_challenge_v");
172
173 // Get the value ∑ mᵢ(x) ⋅ vⁱ
174 translation_masking_term_eval = transcript->template receive_from_prover<FF>("Translation:masking_term_eval");
175
176 // Receive commitments to the SmallSubgroupIPA witnesses that are computed once x and v are available
177 small_ipa_commitments.grand_sum =
178 transcript->template receive_from_prover<Commitment>("Translation:grand_sum_commitment");
179 small_ipa_commitments.quotient =
180 transcript->template receive_from_prover<Commitment>("Translation:quotient_commitment");
181
182 // Get a challenge for the evaluations of the concatenated masking term G, grand sum A, its shift, and grand sum
183 // identity quotient Q
184 const FF small_ipa_evaluation_challenge =
185 transcript->template get_challenge<FF>("Translation:small_ipa_evaluation_challenge");
186
187 // Compute {r, r * g, r, r}, where r = `small_ipa_evaluation_challenge`
189 SmallIPA::evaluation_points(small_ipa_evaluation_challenge);
190
191 // Get the evaluations G(r), A(g * r), A(r), Q(r)
192 for (size_t idx = 0; idx < NUM_SMALL_IPA_EVALUATIONS; idx++) {
193 small_ipa_evaluations[idx] = transcript->template receive_from_prover<FF>(labels[idx]);
194 opening_claims[idx] = { { evaluation_points[idx], small_ipa_evaluations[idx] },
195 small_ipa_commitments.get_all()[idx] };
196 }
197
198 // OriginTag false positive: Small IPA evaluations need to satisfy an identity where they are mixing without
199 // challenges, it is safe because these evaluations are opened in Shplonk.
200 if constexpr (IsRecursive) {
201 for (auto& eval : small_ipa_evaluations) {
202 eval.clear_round_provenance();
203 }
204 }
205
206 // Check Grand Sum Identity at r
207
208 translation_masking_consistency_checked =
209 SmallIPA::check_eccvm_evaluations_consistency(small_ipa_evaluations,
210 small_ipa_evaluation_challenge,
211 evaluation_challenge_x,
212 batching_challenge_v,
213 translation_masking_term_eval);
214
215 // Compute the batched commitment and batched evaluation for the univariate opening claim
216 FF batched_translation_evaluation = translation_evaluations.get_all()[0];
217 FF batching_scalar = batching_challenge_v;
218
219 Commitment batched_commitment;
220 std::vector<FF> batching_challenges = { FF::one() };
221 for (size_t idx = 1; idx < NUM_TRANSLATION_EVALUATIONS; ++idx) {
222 batched_translation_evaluation += batching_scalar * translation_evaluations.get_all()[idx];
223 batching_challenges.push_back(batching_scalar);
224 batching_scalar *= batching_challenge_v;
225 }
226 if constexpr (IsRecursive) {
227 batched_commitment = Commitment::batch_mul(translation_commitments, batching_challenges);
228 } else {
229 batched_commitment = batch_mul_native<Curve>(translation_commitments, batching_challenges);
230 }
231
232 // Place the claim to the array containing the SmallSubgroupIPA opening claims
233 opening_claims[NUM_SMALL_IPA_EVALUATIONS] = { { evaluation_challenge_x, batched_translation_evaluation },
234 batched_commitment };
235
236 // Compute `translation_masking_term_eval` * `evaluation_challenge_x`^{circuit_size -
237 // NUM_DISABLED_ROWS_IN_SUMCHECK}
238 shift_translation_masking_term_eval(evaluation_challenge_x, translation_masking_term_eval);
239}
240
241// Compute the accumulated result from translation evaluations
242// This is the value that Translator will use in its relations
243// Formula: accumulated_result = (op + v*Px + v²*Py + v³*z1 + v⁴*z2 - masking_term) / x
245{
246 FF v = batching_challenge_v;
247 FF v_squared = v * v;
248 FF v_cubed = v_squared * v;
249 FF v_fourth = v_cubed * v;
250
251 FF batched_eval_minus_masking = translation_evaluations.op + v * translation_evaluations.Px +
252 v_squared * translation_evaluations.Py + v_cubed * translation_evaluations.z1 +
253 v_fourth * translation_evaluations.z2 - translation_masking_term_eval;
254
255 accumulated_result = batched_eval_minus_masking / evaluation_challenge_x;
256}
257
258// Explicit template instantiations
259template class ECCVMVerifier_<ECCVMFlavor>;
261
262} // namespace bb
bb::field< bb::Bn254FrParams > FF
Definition field.cpp:22
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: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
#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()