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