Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
eccvm_recursive_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 {
15 const std::shared_ptr<NativeVerificationKey>& native_verifier_key,
16 const std::shared_ptr<Transcript>& transcript)
17 : key(std::make_shared<VerificationKey>(builder, native_verifier_key))
18 , vk_hash(stdlib::witness_t<Builder>(builder, native_verifier_key->hash()))
20 , transcript(transcript)
21{
22 key->fix_witness(); // fixed to a constant
23 vk_hash.fix_witness(); // fixed to a constant
24}
25
38
46{
47 using Curve = Flavor::Curve;
48 using Shplemini = ShpleminiVerifier_<Curve>;
49 using Shplonk = ShplonkVerifier_<Curve>;
51 using ClaimBatcher = ClaimBatcher_<Curve>;
52 using ClaimBatch = ClaimBatcher::Batch;
53 using Sumcheck = SumcheckVerifier<Flavor>;
54
55 RelationParameters<FF> relation_parameters;
56
57 transcript->load_proof(proof.pre_ipa_proof);
58
59 // Fiat-Shamir the vk hash
60 // We do not need to hash the vk in-circuit because both the vk and vk hash are hardcoded as constants.
61 transcript->add_to_hash_buffer("vk_hash", vk_hash);
62 vinfo("ECCVM vk hash in recursive verifier: ", vk_hash);
63
64 VerifierCommitments commitments{ key };
65 CommitmentLabels commitment_labels;
66
67 for (auto [comm, label] : zip_view(commitments.get_wires(), commitment_labels.get_wires())) {
68 comm = transcript->template receive_from_prover<Commitment>(label);
69 }
70
71 // Get challenge for sorted list batching and wire four memory records
72 const auto [beta, gamma] = transcript->template get_challenges<FF>("beta", "gamma");
73
74 auto beta_sqr = beta * beta;
75
76 relation_parameters.gamma = gamma;
77 relation_parameters.beta = beta;
78 relation_parameters.beta_sqr = beta * beta;
79 relation_parameters.beta_cube = beta_sqr * beta;
80 relation_parameters.eccvm_set_permutation_delta =
81 gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr);
82 relation_parameters.eccvm_set_permutation_delta = relation_parameters.eccvm_set_permutation_delta.invert();
83
84 // Get commitment to permutation and lookup grand products
85 commitments.lookup_inverses =
86 transcript->template receive_from_prover<Commitment>(commitment_labels.lookup_inverses);
87 commitments.z_perm = transcript->template receive_from_prover<Commitment>(commitment_labels.z_perm);
88
89 // Execute Sumcheck Verifier
90 // Each linearly independent subrelation contribution is multiplied by `alpha^i`, where
91 // i = 0, ..., NUM_SUBRELATIONS- 1.
92 const FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");
93 Sumcheck sumcheck(transcript, alpha, CONST_ECCVM_LOG_N);
94
95 std::vector<FF> gate_challenges(CONST_ECCVM_LOG_N);
96 for (size_t idx = 0; idx < gate_challenges.size(); idx++) {
97 gate_challenges[idx] = transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx));
98 }
99
100 // Receive commitments to Libra masking polynomials
102
103 libra_commitments[0] = transcript->template receive_from_prover<Commitment>("Libra:concatenation_commitment");
104
105 auto sumcheck_output = sumcheck.verify(relation_parameters, gate_challenges);
106
107 libra_commitments[1] = transcript->template receive_from_prover<Commitment>("Libra:grand_sum_commitment");
108 libra_commitments[2] = transcript->template receive_from_prover<Commitment>("Libra:quotient_commitment");
109
110 // Compute the Shplemini accumulator consisting of the Shplonk evaluation and the commitments and scalars vector
111 // produced by the unified protocol
112 bool consistency_checked = true;
113 ClaimBatcher claim_batcher{
114 .unshifted = ClaimBatch{ commitments.get_unshifted(), sumcheck_output.claimed_evaluations.get_unshifted() },
115 .shifted = ClaimBatch{ commitments.get_to_be_shifted(), sumcheck_output.claimed_evaluations.get_shifted() }
116 };
117
118 FF one{ 1 };
120
121 std::array<FF, CONST_ECCVM_LOG_N> padding_indicator_array;
122 std::ranges::fill(padding_indicator_array, one);
123
124 BatchOpeningClaim<Curve> sumcheck_batch_opening_claims =
125 Shplemini::compute_batch_opening_claim(padding_indicator_array,
126 claim_batcher,
127 sumcheck_output.challenge,
128 key->pcs_verification_key.get_g1_identity(),
132 &consistency_checked,
133 libra_commitments,
134 sumcheck_output.claimed_libra_evaluation,
135 sumcheck_output.round_univariate_commitments,
136 sumcheck_output.round_univariate_evaluations);
137
138 // Reduce the accumulator to a single opening claim
139 const OpeningClaim multivariate_to_univariate_opening_claim =
140 PCS::reduce_batch_opening_claim(sumcheck_batch_opening_claims);
141
142 // Construct the vector of commitments (needs to be vector for the batch_mul)
143 const std::vector<Commitment> translation_commitments = { commitments.transcript_op,
144 commitments.transcript_Px,
145 commitments.transcript_Py,
146 commitments.transcript_z1,
147 commitments.transcript_z2 };
148 // Reduce the univariate evaluations claims to a single claim to be batched by Shplonk
149 compute_translation_opening_claims(translation_commitments);
150
151 opening_claims.back() = std::move(multivariate_to_univariate_opening_claim);
152
153 const OpeningClaim batch_opening_claim =
154 Shplonk::reduce_verification(key->pcs_verification_key.get_g1_identity(), opening_claims, transcript);
155
156 return { batch_opening_claim, proof.ipa_proof };
157}
158
168void ECCVMRecursiveVerifier::compute_translation_opening_claims(const std::vector<Commitment>& translation_commitments)
169{
170 // Used to capture the batched evaluation of unmasked `translation_polynomials` while preserving ZK
172
173 // Initialize SmallSubgroupIPA structures
174 SmallSubgroupIPACommitments<Commitment> small_ipa_commitments;
175 std::array<FF, NUM_SMALL_IPA_EVALUATIONS> small_ipa_evaluations;
176 std::array<std::string, NUM_SMALL_IPA_EVALUATIONS> labels = SmallIPA::evaluation_labels("Translation:");
177
178 // Get a commitment to M + Z_H * R, where M is a concatenation of the masking terms of
179 // `translation_polynomials`, Z_H = X^{|H|} - 1, and R is a random degree 2 polynomial
180 small_ipa_commitments.concatenated =
181 transcript->template receive_from_prover<Commitment>("Translation:concatenated_masking_term_commitment");
182
183 // Get a challenge to evaluate `translation_polynomials` as univariates
184 evaluation_challenge_x = transcript->template get_challenge<FF>("Translation:evaluation_challenge_x");
185
186 // Populate the translation evaluations {`op(x)`, `Px(x)`, `Py(x)`, `z1(x)`, `z2(x)`} to be batched
188 eval = transcript->template receive_from_prover<FF>(label);
189 }
190
191 // Get the batching challenge for commitments and evaluations
192 batching_challenge_v = transcript->template get_challenge<FF>("Translation:batching_challenge_v");
193
194 // Get the value ∑ mᵢ(x) ⋅ vⁱ
195 translation_masking_term_eval = transcript->template receive_from_prover<FF>("Translation:masking_term_eval");
196
197 // Receive commitments to the SmallSubgroupIPA witnesses that are computed once x and v are available
198 small_ipa_commitments.grand_sum =
199 transcript->template receive_from_prover<Commitment>("Translation:grand_sum_commitment");
200 small_ipa_commitments.quotient =
201 transcript->template receive_from_prover<Commitment>("Translation:quotient_commitment");
202
203 // Get a challenge for the evaluations of the concatenated masking term G, grand sum A, its shift, and grand sum
204 // idenity qutient Q
205 const FF small_ipa_evaluation_challenge =
206 transcript->template get_challenge<FF>("Translation:small_ipa_evaluation_challenge");
207
208 // Compute {r, r * g, r , r}, where r = `small_ipa_evaluation_challenge`
210 SmallIPA::evaluation_points(small_ipa_evaluation_challenge);
211
212 // Get the evaluations G(r), A(r), A(g*r), Q(r)
213 for (size_t idx = 0; idx < NUM_SMALL_IPA_EVALUATIONS; idx++) {
214 small_ipa_evaluations[idx] = transcript->template receive_from_prover<FF>(labels[idx]);
215 opening_claims[idx] = { { evaluation_points[idx], small_ipa_evaluations[idx] },
216 small_ipa_commitments.get_all()[idx] };
217 }
218
219 // Check Grand Sum Identity at r
220 SmallIPA::check_eccvm_evaluations_consistency(small_ipa_evaluations,
221 small_ipa_evaluation_challenge,
225
226 // Compute the batched commitment and batched evaluation for the univariate opening claim
227 auto batched_translation_evaluation = translation_evaluations.get_all()[0];
228 auto batching_scalar = batching_challenge_v;
229
230 std::vector<FF> batching_challenges = { FF::one() };
231 for (size_t idx = 1; idx < NUM_TRANSLATION_EVALUATIONS; ++idx) {
232 batched_translation_evaluation += batching_scalar * translation_evaluations.get_all()[idx];
233 batching_challenges.emplace_back(batching_scalar);
234 batching_scalar *= batching_challenge_v;
235 }
236 const Commitment batched_commitment = Commitment::batch_mul(translation_commitments, batching_challenges);
237
238 // Place the claim to the array containing the SmallSubgroupIPA opening claims
239 opening_claims[NUM_SMALL_IPA_EVALUATIONS] = { { evaluation_challenge_x, batched_translation_evaluation },
240 batched_commitment };
241
242 // Compute `translation_masking_term_eval` * `evaluation_challenge_x`^{circuit_size -
243 // NUM_DISABLED_ROWS_IN_SUMCHECK}
244 shift_translation_masking_term_eval(evaluation_challenge_x, translation_masking_term_eval);
245};
246} // namespace bb
A container for commitment labels.
The verification key is responsible for storing the commitments to the precomputed (non-witness) poly...
stdlib::grumpkin< CircuitBuilder > Curve
static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS
std::array< OpeningClaim< Curve >, NUM_OPENING_CLAIMS > opening_claims
IpaClaimAndProof verify_proof(const ECCVMProof &proof)
Creates a circuit that executes the ECCVM verifier algorithm up to IPA verification.
std::shared_ptr< VerificationKey > key
TranslationEvaluations_< FF > translation_evaluations
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...
ECCVMRecursiveVerifier(Builder *builder, const std::shared_ptr< NativeVerificationKey > &native_verifier_key, const std::shared_ptr< Transcript > &transcript)
std::pair< OpeningClaim< Curve >, StdlibIpaProof > IpaClaimAndProof
std::shared_ptr< Transcript > transcript
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:698
void convert_constant_to_fixed_witness(Builder *builder)
Definition bigfield.hpp:677
cycle_group represents a group Element of the proving system's embedded curve, i.e....
static cycle_group batch_mul(const std::vector< cycle_group > &base_points, const std::vector< BigScalarField > &scalars, GeneratorContext context={})
#define vinfo(...)
Definition log.hpp:79
AluTraceBuilder builder
Definition alu.test.cpp:123
void hash(State &state) noexcept
Entry point for Barretenberg command-line interface.
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
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()
RefArray< BF, NUM_TRANSLATION_EVALUATIONS > get_all()
std::array< std::string, NUM_TRANSLATION_EVALUATIONS > labels
Curve grumpkin in circuit setting.
Definition grumpkin.hpp:21