Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
eccvm_prover.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
7#include "eccvm_prover.hpp"
18
19namespace bb {
20
22 const std::shared_ptr<Transcript>& transcript,
23 const std::shared_ptr<Transcript>& ipa_transcript)
24 : transcript(transcript)
25 , ipa_transcript(ipa_transcript)
26{
27 PROFILE_THIS_NAME("ECCVMProver(CircuitBuilder&)");
28
29 // TODO(https://github.com/AztecProtocol/barretenberg/issues/939): Remove redundancy between
30 // ProvingKey/ProverPolynomials and update the model to reflect what's done in all other proving systems.
31
32 // Construct the proving key; populates all polynomials except for witness polys
34
35 key->commitment_key = CommitmentKey(key->circuit_size);
36}
37
43{
45
46 // Fiat-Shamir the vk hash
48 typename Flavor::BF vk_hash = vk.hash();
49 transcript->add_to_hash_buffer("vk_hash", vk_hash);
50 vinfo("ECCVM vk hash in prover: ", vk_hash);
51}
52
58{
59 // To commit to the masked wires when `real_size` < `circuit_size`, we use
60 // `commit_structured` that ignores 0 coefficients between the real size and the last NUM_DISABLED_ROWS_IN_SUMCHECK
61 // wire entries.
62 const size_t circuit_size = key->circuit_size;
63 unmasked_witness_size = circuit_size - NUM_DISABLED_ROWS_IN_SUMCHECK;
64
65 CommitmentKey::CommitType commit_type =
67
68 // Commit to wires whose length is bounded by the real size of the ECCVM
69 for (const auto& [wire, label] : zip_view(key->polynomials.get_wires_without_accumulators(),
71 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1240) Structured Polynomials in
72 // ECCVM/Translator/MegaZK
73 const size_t start = circuit_size == wire.size() ? 0 : 1;
74 std::vector<std::pair<size_t, size_t>> active_ranges{ { start, key->real_size + start },
75 { unmasked_witness_size, circuit_size } };
76 commit_to_witness_polynomial(wire, label, commit_type, active_ranges);
77 }
78
79 // The accumulators are populated until the 2^{CONST_ECCVM_LOG_N}, therefore we commit to a full-sized polynomial
80 for (const auto& [wire, label] :
81 zip_view(key->polynomials.get_accumulators(), commitment_labels.get_accumulators())) {
83 }
84}
85
91{
92
93 // Compute and add beta to relation parameters
94 auto [beta, gamma] = transcript->template get_challenges<FF>("beta", "gamma");
95
96 // TODO(#583)(@zac-williamson): fix Transcript to be able to generate more than 2 challenges per round! oof.
97 auto beta_sqr = beta * beta;
100 relation_parameters.beta_sqr = beta_sqr;
101 relation_parameters.beta_cube = beta_sqr * beta;
103 gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr);
105 // Compute inverse polynomial for our logarithmic-derivative lookup method
107 typename Flavor::LookupRelation,
109 true>(key->polynomials, relation_parameters, unmasked_witness_size);
110 commit_to_witness_polynomial(key->polynomials.lookup_inverses, commitment_labels.lookup_inverses);
111}
112
118{
119 // Compute permutation grand product and their commitments
120 compute_grand_products<Flavor>(key->polynomials, relation_parameters, unmasked_witness_size);
121 commit_to_witness_polynomial(key->polynomials.z_perm, commitment_labels.z_perm);
122}
123
129{
130
131 using Sumcheck = SumcheckProver<Flavor>;
132
133 // Each linearly independent subrelation contribution is multiplied by `alpha^i`, where
134 // i = 0, ..., NUM_SUBRELATIONS- 1.
135 FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");
136
137 std::vector<FF> gate_challenges(CONST_ECCVM_LOG_N);
138 for (size_t idx = 0; idx < gate_challenges.size(); idx++) {
139 gate_challenges[idx] = transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx));
140 }
141
142 Sumcheck sumcheck(key->circuit_size,
143 key->polynomials,
145 alpha,
146 gate_challenges,
148 CONST_ECCVM_LOG_N);
149
150 zk_sumcheck_data = ZKData(key->log_circuit_size, transcript, key->commitment_key);
151
152 sumcheck_output = sumcheck.prove(zk_sumcheck_data);
153}
154
162{
163 using Curve = typename Flavor::Curve;
164 using Shplemini = ShpleminiProver_<Curve>;
165 using Shplonk = ShplonkProver_<Curve>;
167 using PolynomialBatcher = GeminiProver_<Curve>::PolynomialBatcher;
168
169 SmallSubgroupIPA small_subgroup_ipa_prover(zk_sumcheck_data,
170 sumcheck_output.challenge,
171 sumcheck_output.claimed_libra_evaluation,
173 key->commitment_key);
174 small_subgroup_ipa_prover.prove();
175
176 // Execute the Shplemini (Gemini + Shplonk) protocol to produce a univariate opening claim for the multilinear
177 // evaluations produced by Sumcheck
178 PolynomialBatcher polynomial_batcher(key->circuit_size);
179 polynomial_batcher.set_unshifted(key->polynomials.get_unshifted());
180 polynomial_batcher.set_to_be_shifted_by_one(key->polynomials.get_to_be_shifted());
181
182 OpeningClaim multivariate_to_univariate_opening_claim =
183 Shplemini::prove(key->circuit_size,
184 polynomial_batcher,
185 sumcheck_output.challenge,
186 key->commitment_key,
188 small_subgroup_ipa_prover.get_witness_polynomials(),
189 sumcheck_output.round_univariates,
190 sumcheck_output.round_univariate_evaluations);
191
193
194 opening_claims.back() = std::move(multivariate_to_univariate_opening_claim);
195
196 // Reduce the opening claims to a single opening claim via Shplonk
197 const OpeningClaim batch_opening_claim = Shplonk::prove(key->commitment_key, opening_claims, transcript);
198
199 // Compute the opening proof for the batched opening claim with the univariate PCS
200 PCS::compute_opening_proof(key->commitment_key, batch_opening_claim, ipa_transcript);
201}
202
204{
205 return { transcript->export_proof(), ipa_transcript->export_proof() };
206}
207
221
267{
268 // Used to capture the batched evaluation of unmasked `translation_polynomials` while preserving ZK
270
271 // Initialize SmallSubgroupIPA structures
274
275 // Collect the polynomials to be batched
276 RefArray translation_polynomials{ key->polynomials.transcript_op,
277 key->polynomials.transcript_Px,
278 key->polynomials.transcript_Py,
279 key->polynomials.transcript_z1,
280 key->polynomials.transcript_z2 };
281
282 // Extract the masking terms of `translation_polynomials`, concatenate them in the Lagrange basis over SmallSubgroup
283 // H, mask the resulting polynomial, and commit to it
284 TranslationData<Transcript> translation_data(translation_polynomials, transcript, key->commitment_key);
285
286 // Get a challenge to evaluate the `translation_polynomials` as univariates
287 evaluation_challenge_x = transcript->template get_challenge<FF>("Translation:evaluation_challenge_x");
288
289 // Evaluate `translation_polynomial` as univariates and add their evaluations at x to the transcript
290 for (auto [eval, poly, label] :
292 eval = poly.evaluate(evaluation_challenge_x);
293 transcript->send_to_verifier(label, eval);
294 }
295
296 // Get another challenge to batch the evaluations of the transcript polynomials
297 batching_challenge_v = transcript->template get_challenge<FF>("Translation:batching_challenge_v");
298
299 SmallIPA translation_masking_term_prover(
300 translation_data, evaluation_challenge_x, batching_challenge_v, transcript, key->commitment_key);
301 translation_masking_term_prover.prove();
302
303 // Get the challenge to check evaluations of the SmallSubgroupIPA witness polynomials
304 FF small_ipa_evaluation_challenge =
305 transcript->template get_challenge<FF>("Translation:small_ipa_evaluation_challenge");
306
307 // Populate SmallSubgroupIPA opening claims:
308 // 1. Get the evaluation points and labels
309 evaluation_points = translation_masking_term_prover.evaluation_points(small_ipa_evaluation_challenge);
310 evaluation_labels = translation_masking_term_prover.evaluation_labels();
311 // 2. Compute the evaluations of witness polynomials at corresponding points, send them to the verifier, and create
312 // the opening claims
313 for (size_t idx = 0; idx < NUM_SMALL_IPA_EVALUATIONS; idx++) {
314 auto witness_poly = translation_masking_term_prover.get_witness_polynomials()[idx];
315 const FF evaluation = witness_poly.evaluate(evaluation_points[idx]);
316 transcript->send_to_verifier(evaluation_labels[idx], evaluation);
317 opening_claims[idx] = { .polynomial = witness_poly, .opening_pair = { evaluation_points[idx], evaluation } };
318 }
319
320 // Compute the opening claim for the masked evaluations of `op`, `Px`, `Py`, `z1`, and `z2` at
321 // `evaluation_challenge_x` batched by the powers of `batching_challenge_v`.
322 Polynomial batched_translation_univariate{ key->circuit_size };
323 FF batched_translation_evaluation{ 0 };
324 FF batching_scalar = FF(1);
325 for (auto [polynomial, eval] : zip_view(translation_polynomials, translation_evaluations.get_all())) {
326 batched_translation_univariate.add_scaled(polynomial, batching_scalar);
327 batched_translation_evaluation += eval * batching_scalar;
328 batching_scalar *= batching_challenge_v;
329 }
330
331 // Add the batched claim to the array of SmallSubgroupIPA opening claims.
332 opening_claims[NUM_SMALL_IPA_EVALUATIONS] = { batched_translation_univariate,
333 { evaluation_challenge_x, batched_translation_evaluation } };
334}
335
343 const std::string& label,
344 CommitmentKey::CommitType commit_type,
345 const std::vector<std::pair<size_t, size_t>>& active_ranges)
346{
347 // We add NUM_DISABLED_ROWS_IN_SUMCHECK-1 random values to the coefficients of each wire polynomial to not leak
348 // information via the commitment and evaluations. -1 is caused by shifts.
349 polynomial.mask();
350 transcript->send_to_verifier(label, key->commitment_key.commit_with_type(polynomial, commit_type, active_ranges));
351}
352} // namespace bb
A container for the prover polynomials.
The verification key is responsible for storing the commitments to the precomputed (non-witnessk) pol...
typename Curve::ScalarField FF
typename Curve::BaseField BF
curve::Grumpkin Curve
ECCVMLookupRelation< FF > LookupRelation
ECCVMProof construct_proof()
ECCVMProver(CircuitBuilder &builder, const std::shared_ptr< Transcript > &transcript, const std::shared_ptr< Transcript > &ipa_transcript=std::make_shared< Transcript >())
SumcheckOutput< Flavor > sumcheck_output
BB_PROFILE void execute_log_derivative_commitments_round()
Compute sorted witness-table accumulator.
size_t unmasked_witness_size
std::shared_ptr< Transcript > ipa_transcript
ZKSumcheckData< Flavor > ZKData
std::shared_ptr< Transcript > transcript
ECCVMProof export_proof()
CommitmentLabels commitment_labels
TranslationEvaluations translation_evaluations
std::shared_ptr< ProvingKey > key
void commit_to_witness_polynomial(Polynomial &polynomial, const std::string &label, CommitmentKey::CommitType commit_type=CommitmentKey::CommitType::Default, const std::vector< std::pair< size_t, size_t > > &active_ranges={})
Utility to mask and commit to a witness polynomial and send the commitment to verifier.
BB_PROFILE void execute_preamble_round()
Fiat-Shamir the VK.
BB_PROFILE void execute_wire_commitments_round()
Compute commitments to the first three wires.
Flavor::CommitmentKey CommitmentKey
std::array< OpeningClaim, NUM_OPENING_CLAIMS > opening_claims
BB_PROFILE void execute_grand_product_computation_round()
Compute permutation and lookup grand product polynomials and commitments.
BB_PROFILE void execute_relation_check_rounds()
Run Sumcheck resulting in u = (u_1,...,u_d) challenges and all evaluations at u being calculated.
BB_PROFILE void execute_pcs_rounds()
Produce a univariate opening claim for the sumcheck multivariate evalutions and a batched univariate ...
void compute_translation_opening_claims()
To link the ECCVM Transcript wires op, Px, Py, z1, and z2 to the accumulator computed by the translat...
bb::RelationParameters< FF > relation_parameters
Class responsible for computation of the batched multilinear polynomials required by the Gemini proto...
Definition gemini.hpp:123
void mask()
Add random values to the coefficients of a polynomial. In practice, this is used for ensuring the com...
Polynomial p and an opening pair (r,v) such that p(r) = v.
Definition claim.hpp:34
A template class for a reference array. Behaves as if std::array<T&, N> was possible.
Definition ref_array.hpp:22
Shplonk Prover.
Definition shplonk.hpp:36
A Curve-agnostic ZK protocol to prove inner products of small vectors.
std::array< bb::Polynomial< FF >, NUM_SMALL_IPA_EVALUATIONS > get_witness_polynomials() const
void prove()
Compute the derived witnesses and and commit to them.
The implementation of the sumcheck Prover for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:123
A class designed to accept the ECCVM Transcript Polynomials, concatenate their masking terms in Lagra...
void vinfo(Args... args)
Definition log.hpp:76
AluTraceBuilder builder
Definition alu.test.cpp:123
UltraKeccakFlavor::VerificationKey VerificationKey
Entry point for Barretenberg command-line interface.
void compute_logderivative_inverse(Polynomials &polynomials, auto &relation_parameters, const size_t circuit_size)
Compute the inverse polynomial I(X) required for logderivative lookupsdetails Inverse may be defined ...
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
#define PROFILE_THIS_NAME(name)
Definition op_count.hpp:16
RefArray< BF, NUM_TRANSLATION_EVALUATIONS > get_all()
std::array< std::string, NUM_TRANSLATION_EVALUATIONS > labels