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: Planned, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#include "eccvm_prover.hpp"
19
20namespace bb {
21
22ECCVMProver::ECCVMProver(CircuitBuilder& builder, const std::shared_ptr<Transcript>& transcript)
23 : transcript(transcript)
24{
25 BB_BENCH_NAME("ECCVMProver(CircuitBuilder&)");
26
27 // TODO(https://github.com/AztecProtocol/barretenberg/issues/939): Remove redundancy between
28 // ProvingKey/ProverPolynomials and update the model to reflect what's done in all other proving systems.
29
30 // Construct the proving key; populates all polynomials except for witness polys
32
33 key->commitment_key = CommitmentKey(key->circuit_size);
34}
35
41{
43
44 // Fiat-Shamir the vk hash
46 typename Flavor::BF vk_hash = vk.get_hash();
47 transcript->add_to_hash_buffer("vk_hash", vk_hash);
48 vinfo("ECCVM vk hash in prover: ", vk_hash);
49}
50
56{
57 BB_BENCH_NAME("ECCVMProver::execute_wire_commitments_round");
58
59 const size_t circuit_size = key->circuit_size;
60
61 // Create and commit to Gemini masking polynomial (for ZK-PCS)
62 key->polynomials.gemini_masking_poly = Polynomial::random(circuit_size);
63 auto masking_commitment = key->commitment_key.commit(key->polynomials.gemini_masking_poly);
64 transcript->send_to_verifier("Gemini:masking_poly_comm", masking_commitment);
65
66 auto batch = key->commitment_key.start_batch();
67 for (const auto& [wire, label] : zip_view(key->polynomials.get_wires(), commitment_labels.get_wires())) {
68 batch.add_to_batch(wire, label, Flavor::CommitmentLabels::wire_has_high_duplicate_density(label));
69 }
70 batch.commit_and_send_to_verifier(transcript);
71}
72
78{
79 BB_BENCH_NAME("ECCVMProver::execute_log_derivative_commitments_round");
80
81 // Compute and add beta to relation parameters
82 auto [beta, gamma] = transcript->template get_challenges<FF>(std::array<std::string, 2>{ "beta", "gamma" });
83
84 // TODO(#583)(@zac-williamson): fix Transcript to be able to generate more than 2 challenges per round! oof.
85 auto beta_sqr = beta * beta;
86 auto beta_quartic = beta_sqr * beta_sqr;
90 relation_parameters.beta_cube = beta_sqr * beta;
91 relation_parameters.beta_quartic = beta_quartic;
92 // `eccvm_set_permutation_delta` is used in the set membership gadget in eccvm/ecc_set_relation.hpp, specifically to
93 // constrain (pc, round, wnaf_slice) to match between the MSM table and the Precomputed table. The number of rows we
94 // add per short scalar `mul` is slightly less in the Precomputed table as in the MSM table, so to get the
95 // permutation argument to work out, when `precompute_select == 0`, we must implicitly _remove_ (0, 0, 0) as a tuple
96 // on the wNAF side. This corresponds to dividing by
97 // (γ+t·β⁴)·(γ+β²+t·β⁴)·(γ+2β²+t·β⁴)·(γ+3β²+t·β⁴), where t = FIRST_TERM_TAG.
98 auto first_term_tag = beta_quartic; // FIRST_TERM_TAG (= 1) * beta_quartic
99 relation_parameters.eccvm_set_permutation_delta = (gamma + first_term_tag) * (gamma + beta_sqr + first_term_tag) *
100 (gamma + beta_sqr + beta_sqr + first_term_tag) *
101 (gamma + beta_sqr + beta_sqr + beta_sqr + first_term_tag);
103 // Compute inverse polynomial for our logarithmic-derivative lookup method
104 // Skip the disabled head region to preserve masking values
106 typename Flavor::LookupRelation,
108 true>(key->polynomials, relation_parameters, Flavor::TRACE_OFFSET);
109 auto& li = key->polynomials.lookup_inverses;
110 transcript->send_to_verifier(commitment_labels.lookup_inverses, key->commitment_key.commit(li));
111}
112
118{
119 BB_BENCH_NAME("ECCVMProver::execute_grand_product_computation_round");
120 // Compute permutation grand product (starts after disabled head region via gp_start)
121 compute_grand_products<Flavor>(key->polynomials, relation_parameters);
122 auto& zp = key->polynomials.z_perm;
123 // set has_duplicates_hint for Z_PERM (empty row = duplicate Z value)
124 transcript->send_to_verifier(commitment_labels.z_perm,
125 key->commitment_key.commit(zp, /*has_duplicates_hint=*/true));
126}
127
133{
134 BB_BENCH_NAME("ECCVMProver::execute_relation_check_rounds");
135 using Sumcheck = SumcheckProver<Flavor>;
136
137 // Each linearly independent subrelation contribution is multiplied by `alpha^i`, where
138 // i = 0, ..., NUM_SUBRELATIONS- 1.
139 FF alpha = transcript->template get_challenge<FF>("Sumcheck:alpha");
140
141 std::vector<FF> gate_challenges =
142 transcript->template get_dyadic_powers_of_challenge<FF>("Sumcheck:gate_challenge", CONST_ECCVM_LOG_N);
143
144 Sumcheck sumcheck(key->circuit_size,
145 key->polynomials,
147 alpha,
148 gate_challenges,
150 CONST_ECCVM_LOG_N);
151
152 zk_sumcheck_data = ZKData(key->log_circuit_size, transcript, key->commitment_key);
153
154 sumcheck_output = sumcheck.prove(zk_sumcheck_data);
155}
156
164{
165 BB_BENCH_NAME("ECCVMProver::execute_pcs_rounds");
166 using Curve = typename Flavor::Curve;
167 using Shplemini = ShpleminiProver_<Curve>;
168 using Shplonk = ShplonkProver_<Curve>;
170 using PolynomialBatcher = GeminiProver_<Curve>::PolynomialBatcher;
171
172 SmallSubgroupIPA small_subgroup_ipa_prover(zk_sumcheck_data,
173 sumcheck_output.challenge,
174 sumcheck_output.claimed_libra_evaluation,
176 key->commitment_key);
177 small_subgroup_ipa_prover.prove();
178
179 // Execute the Shplemini (Gemini + Shplonk) protocol to produce a univariate opening claim for the multilinear
180 // evaluations produced by Sumcheck
181 PolynomialBatcher polynomial_batcher(key->circuit_size);
182 polynomial_batcher.set_unshifted(key->polynomials.get_unshifted());
183 polynomial_batcher.set_to_be_shifted_by_one(key->polynomials.get_to_be_shifted());
184
185 OpeningClaim multivariate_to_univariate_opening_claim =
186 Shplemini::prove(key->circuit_size,
187 polynomial_batcher,
188 sumcheck_output.challenge,
189 key->commitment_key,
191 small_subgroup_ipa_prover.get_witness_polynomials(),
192 sumcheck_output.round_univariates,
193 sumcheck_output.round_univariate_evaluations);
194
196
197 opening_claims.back() = std::move(multivariate_to_univariate_opening_claim);
198
199 // Reduce the opening claims to a single opening claim via Shplonk
200 // IPA proving is performed externally
201 batch_opening_claim = Shplonk::prove(key->commitment_key, opening_claims, transcript);
202}
203
205{
206 return { transcript->export_proof() };
207}
208
222
253{
254 // Used to capture the batched evaluation of unmasked `translation_polynomials` while preserving ZK
255 using SmallIPA = SmallSubgroupIPAProver<Flavor>;
256
257 // Initialize SmallSubgroupIPA structures
260
261 RefArray translation_polynomials{ key->polynomials.transcript_op,
262 key->polynomials.transcript_Px,
263 key->polynomials.transcript_Py,
264 key->polynomials.transcript_z1,
265 key->polynomials.transcript_z2 };
266
267 // Extract the masking terms of `translation_polynomials`, concatenate them in the Lagrange basis over SmallSubgroup
268 // H, mask the resulting polynomial, and commit to it
269 TranslationData<Transcript> translation_data(translation_polynomials, transcript, key->commitment_key);
270
271 // Get a challenge to evaluate the `translation_polynomials` as univariates
272 evaluation_challenge_x = transcript->template get_challenge<FF>("Translation:evaluation_challenge_x");
273
274 // Evaluate `translation_polynomial` as univariates and add their evaluations at x to the transcript
275 for (auto [eval, poly, label] :
277 eval = poly.evaluate(evaluation_challenge_x);
278 transcript->send_to_verifier(label, eval);
279 }
280
281 // Get another challenge to batch the evaluations of the transcript polynomials
282 batching_challenge_v = transcript->template get_challenge<FF>("Translation:batching_challenge_v");
283
284 SmallIPA translation_masking_term_prover(
285 translation_data, evaluation_challenge_x, batching_challenge_v, transcript, key->commitment_key);
286 translation_masking_term_prover.prove();
287
288 // Get the challenge to check evaluations of the SmallSubgroupIPA witness polynomials
289 FF small_ipa_evaluation_challenge =
290 transcript->template get_challenge<FF>("Translation:small_ipa_evaluation_challenge");
291
292 // Populate SmallSubgroupIPA opening claims:
293 // 1. Get the evaluation points and labels
294 evaluation_points = translation_masking_term_prover.evaluation_points(small_ipa_evaluation_challenge);
295 evaluation_labels = translation_masking_term_prover.evaluation_labels();
296 // 2. Compute the evaluations of witness polynomials at corresponding points, send them to the verifier, and create
297 // the opening claims
298 for (size_t idx = 0; idx < NUM_SMALL_IPA_EVALUATIONS; idx++) {
299 auto witness_poly = translation_masking_term_prover.get_witness_polynomials()[idx];
300 const FF evaluation = witness_poly.evaluate(evaluation_points[idx]);
301 transcript->send_to_verifier(evaluation_labels[idx], evaluation);
302 opening_claims[idx] = { .polynomial = witness_poly, .opening_pair = { evaluation_points[idx], evaluation } };
303 }
304
305 // Compute the opening claim for the masked evaluations of `op`, `Px`, `Py`, `z1`, and `z2` at
306 // `evaluation_challenge_x` batched by the powers of `batching_challenge_v`.
307 Polynomial batched_translation_univariate{ key->circuit_size };
308 FF batched_translation_evaluation{ 0 };
309 FF batching_scalar = FF(1);
310 for (auto [polynomial, eval] : zip_view(translation_polynomials, translation_evaluations.get_all())) {
311 batched_translation_univariate.add_scaled(polynomial, batching_scalar);
312 batched_translation_evaluation += eval * batching_scalar;
313 batching_scalar *= batching_challenge_v;
314 }
315
316 // Add the batched claim to the array of SmallSubgroupIPA opening claims.
317 opening_claims[NUM_SMALL_IPA_EVALUATIONS] = { batched_translation_univariate,
318 { evaluation_challenge_x, batched_translation_evaluation } };
319}
320
327} // namespace bb
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:264
A container for the prover polynomials.
typename Curve::BaseField BF
FixedVKAndHash_< PrecomputedEntities< Commitment >, BF, ECCVMHardcodedVKAndHash > VerificationKey
The verification key stores commitments to the precomputed polynomials used by the verifier.
static constexpr size_t TRACE_OFFSET
OpeningClaim batch_opening_claim
SumcheckOutput< Flavor > sumcheck_output
BB_PROFILE void execute_log_derivative_commitments_round()
Compute sorted witness-table accumulator.
ECCVMProver(CircuitBuilder &builder, const std::shared_ptr< Transcript > &transcript)
ZKSumcheckData< Flavor > ZKData
std::shared_ptr< Transcript > transcript
std::pair< Proof, OpeningClaim > construct_proof()
CommitmentLabels commitment_labels
TranslationEvaluations translation_evaluations
std::shared_ptr< ProvingKey > key
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
ECCVMLookupShortRelation< FF > LookupRelation
Class responsible for computation of the batched multilinear polynomials required by the Gemini proto...
Definition gemini.hpp:128
Base Native verification key class.
Definition flavor.hpp:137
static Polynomial random(size_t size, size_t start_index=0)
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:37
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:294
A class designed to accept the ECCVM Transcript Polynomials, concatenate their masking terms in Lagra...
#define vinfo(...)
Definition log.hpp:94
AluTraceBuilder builder
Definition alu.test.cpp:124
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
void compute_logderivative_inverse(Polynomials &polynomials, auto &relation_parameters, const size_t start_index=0)
Compute the inverse polynomial I(X) required for logderivative lookups.
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
RefArray< BF, NUM_TRANSLATION_EVALUATIONS > get_all()
std::array< std::string, NUM_TRANSLATION_EVALUATIONS > labels
constexpr field invert() const noexcept