Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
oink_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
12
13namespace bb {
14
20template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::prove()
21{
22 BB_BENCH_NAME("OinkProver::prove");
23 if (!prover_instance->commitment_key.initialized()) {
24 prover_instance->commitment_key = CommitmentKey(prover_instance->dyadic_size());
25 }
26 // Add circuit size public input size and public inputs to transcript->
27 execute_preamble_round();
28 // Compute first three wire commitments
29 execute_wire_commitments_round();
30 // Compute sorted list accumulator and commitment
31 execute_sorted_list_accumulator_round();
32 // Fiat-Shamir: beta & gamma
33 execute_log_derivative_inverse_round();
34 // Compute grand product(s) and commitments.
35 execute_grand_product_computation_round();
36
37 // Generate relation separators alphas for sumcheck/combiner computation
38 prover_instance->alphas = generate_alphas_round();
39
40 // #ifndef __wasm__
41 // Free the commitment key
42 prover_instance->commitment_key = CommitmentKey();
43 // #endif
44
45 prover_instance->is_complete = true;
46}
47
52template <IsUltraOrMegaHonk Flavor> typename OinkProver<Flavor>::Proof OinkProver<Flavor>::export_proof()
53{
54 return transcript->export_proof();
55}
56
61template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_preamble_round()
62{
63 BB_BENCH_NAME("OinkProver::execute_preamble_round");
64 fr vk_hash = honk_vk->hash_through_transcript(domain_separator, *transcript);
65 transcript->add_to_hash_buffer(domain_separator + "vk_hash", vk_hash);
66 vinfo("vk hash in Oink prover: ", vk_hash);
67
68 for (size_t i = 0; i < prover_instance->num_public_inputs(); ++i) {
69 auto public_input_i = prover_instance->public_inputs[i];
70 transcript->send_to_verifier(domain_separator + "public_input_" + std::to_string(i), public_input_i);
71 }
72}
73
79template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_wire_commitments_round()
80{
81 BB_BENCH_NAME("OinkProver::execute_wire_commitments_round");
82 // Commit to the first three wire polynomials
83 // We only commit to the fourth wire polynomial after adding memory recordss
84 auto batch = prover_instance->commitment_key.start_batch();
85 // Commit to the first three wire polynomials
86 // We only commit to the fourth wire polynomial after adding memory records
87
88 batch.add_to_batch(prover_instance->polynomials.w_l, commitment_labels.w_l, /*mask?*/ Flavor::HasZK);
89 batch.add_to_batch(prover_instance->polynomials.w_r, commitment_labels.w_r, /*mask?*/ Flavor::HasZK);
90 batch.add_to_batch(prover_instance->polynomials.w_o, commitment_labels.w_o, /*mask?*/ Flavor::HasZK);
91
92 if constexpr (IsMegaFlavor<Flavor>) {
93
94 // Commit to Goblin ECC op wires.
95 // Note even with zk, we do not mask here. The masking for these is done differently.
96 // It is necessary that "random" ops are added to the op_queue, which is then used to populate these ecc op
97 // wires. This is more holistic and obviates the need to extend with random values.
98 bool mask_ecc_op_polys = false; // Flavor::HasZK
99
100 for (auto [polynomial, label] :
101 zip_view(prover_instance->polynomials.get_ecc_op_wires(), commitment_labels.get_ecc_op_wires())) {
102 {
103 BB_BENCH_NAME("COMMIT::ecc_op_wires");
104 batch.add_to_batch(polynomial, domain_separator + label, mask_ecc_op_polys);
105 };
106 }
107
108 // Commit to DataBus related polynomials
109 for (auto [polynomial, label] :
110 zip_view(prover_instance->polynomials.get_databus_entities(), commitment_labels.get_databus_entities())) {
111 {
112 BB_BENCH_NAME("COMMIT::databus");
113 batch.add_to_batch(polynomial, label, /*mask?*/ Flavor::HasZK);
114 }
115 }
116 }
117
118 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
119 prover_instance->commitments.w_l = computed_commitments[0];
120 prover_instance->commitments.w_r = computed_commitments[1];
121 prover_instance->commitments.w_o = computed_commitments[2];
122
123 if constexpr (IsMegaFlavor<Flavor>) {
124 size_t commitment_idx = 3;
125 for (auto& commitment : prover_instance->commitments.get_ecc_op_wires()) {
126 commitment = computed_commitments[commitment_idx];
127 commitment_idx++;
128 }
129
130 for (auto& commitment : prover_instance->commitments.get_databus_entities()) {
131 commitment = computed_commitments[commitment_idx];
132 commitment_idx++;
133 }
134 }
135}
136
141template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_sorted_list_accumulator_round()
142{
143 BB_BENCH_NAME("OinkProver::execute_sorted_list_accumulator_round");
144 // Get eta challenges
145 auto [eta, eta_two, eta_three] = transcript->template get_challenges<FF>(
146 domain_separator + "eta", domain_separator + "eta_two", domain_separator + "eta_three");
147 prover_instance->relation_parameters.eta = eta;
148 prover_instance->relation_parameters.eta_two = eta_two;
149 prover_instance->relation_parameters.eta_three = eta_three;
150
152 prover_instance->memory_read_records,
153 prover_instance->memory_write_records,
154 eta,
155 eta_two,
156 eta_three);
157
158 // Commit to lookup argument polynomials and the finalized (i.e. with memory records) fourth wire polynomial
159 auto batch = prover_instance->commitment_key.start_batch();
160 batch.add_to_batch(prover_instance->polynomials.lookup_read_counts,
161 commitment_labels.lookup_read_counts,
162 /*mask?*/ Flavor::HasZK);
163 batch.add_to_batch(
164 prover_instance->polynomials.lookup_read_tags, commitment_labels.lookup_read_tags, /*mask?*/ Flavor::HasZK);
165 batch.add_to_batch(
166 prover_instance->polynomials.w_4, domain_separator + commitment_labels.w_4, /*mask?*/ Flavor::HasZK);
167 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
168
169 prover_instance->commitments.lookup_read_counts = computed_commitments[0];
170 prover_instance->commitments.lookup_read_tags = computed_commitments[1];
171 prover_instance->commitments.w_4 = computed_commitments[2];
172}
173
178template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_log_derivative_inverse_round()
179{
180 BB_BENCH_NAME("OinkProver::execute_log_derivative_inverse_round");
181 auto [beta, gamma] = transcript->template get_challenges<FF>(domain_separator + "beta", domain_separator + "gamma");
182 prover_instance->relation_parameters.beta = beta;
183 prover_instance->relation_parameters.gamma = gamma;
184
185 // Compute the inverses used in log-derivative lookup relations
187 prover_instance->polynomials, prover_instance->dyadic_size(), prover_instance->relation_parameters);
188
189 auto batch = prover_instance->commitment_key.start_batch();
190 batch.add_to_batch(prover_instance->polynomials.lookup_inverses,
191 commitment_labels.lookup_inverses,
192 /*mask?*/ Flavor::HasZK);
193
194 // If Mega, commit to the databus inverse polynomials and send
195 if constexpr (IsMegaFlavor<Flavor>) {
196 for (auto [polynomial, label] :
197 zip_view(prover_instance->polynomials.get_databus_inverses(), commitment_labels.get_databus_inverses())) {
198 batch.add_to_batch(polynomial, label, /*mask?*/ Flavor::HasZK);
199 };
200 }
201 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
202
203 prover_instance->commitments.lookup_inverses = computed_commitments[0];
204 if constexpr (IsMegaFlavor<Flavor>) {
205 size_t commitment_idx = 1;
206 for (auto& commitment : prover_instance->commitments.get_databus_inverses()) {
207 commitment = computed_commitments[commitment_idx];
208 commitment_idx++;
209 };
210 }
211}
212
217template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_grand_product_computation_round()
218{
219 BB_BENCH_NAME("OinkProver::execute_grand_product_computation_round");
220 // Compute the permutation grand product polynomial
221
223 prover_instance->public_inputs,
224 prover_instance->pub_inputs_offset(),
225 prover_instance->active_region_data,
226 prover_instance->relation_parameters,
227 prover_instance->get_final_active_wire_idx() + 1);
228
229 {
230 BB_BENCH_NAME("COMMIT::z_perm");
231 auto commit_type = (prover_instance->get_is_structured())
234 prover_instance->commitments.z_perm =
235 commit_to_witness_polynomial(prover_instance->polynomials.z_perm, commitment_labels.z_perm, commit_type);
236 }
237}
238
240{
241 BB_BENCH_NAME("OinkProver::generate_alphas_round");
242
243 // Get the relation separation challenges for sumcheck/combiner computation
244 std::array<std::string, Flavor::NUM_SUBRELATIONS - 1> challenge_labels;
245
246 for (size_t idx = 0; idx < Flavor::NUM_SUBRELATIONS - 1; ++idx) {
247 challenge_labels[idx] = domain_separator + "alpha_" + std::to_string(idx);
248 }
249 // It is more efficient to generate an array of challenges than to generate them individually.
250 SubrelationSeparators alphas = transcript->template get_challenges<FF>(challenge_labels);
251
252 return alphas;
253}
254
262template <IsUltraOrMegaHonk Flavor>
264 const std::string& label,
265 const CommitmentKey::CommitType type)
266{
267 BB_BENCH_NAME("OinkProver::commit_to_witness_polynomial");
268 // Mask the polynomial when proving in zero-knowledge
269 if constexpr (Flavor::HasZK) {
270 polynomial.mask();
271 };
272
273 typename Flavor::Commitment commitment;
274
275 commitment = prover_instance->commitment_key.commit_with_type(
276 polynomial, type, prover_instance->active_region_data.get_ranges());
277 // Send the commitment to the verifier
278 transcript->send_to_verifier(domain_separator + label, commitment);
279
280 return commitment;
281}
282
283template class OinkProver<UltraFlavor>;
284template class OinkProver<UltraZKFlavor>;
285template class OinkProver<UltraKeccakFlavor>;
286#ifdef STARKNET_GARAGA_FLAVORS
289#endif
291template class OinkProver<UltraRollupFlavor>;
292template class OinkProver<MegaFlavor>;
293template class OinkProver<MegaZKFlavor>;
294
295} // namespace bb
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:218
std::array< FF, NUM_SUBRELATIONS - 1 > SubrelationSeparators
static constexpr size_t NUM_SUBRELATIONS
static constexpr bool HasZK
Curve::AffineElement Commitment
Class for all the oink rounds, which are shared between the folding prover and ultra prover.
Proof export_proof()
Export the Oink proof.
void execute_log_derivative_inverse_round()
Compute log derivative inverse polynomial and its commitment, if required.
void execute_grand_product_computation_round()
Compute permutation and lookup grand product polynomials and their commitments.
Flavor::Commitment commit_to_witness_polynomial(Polynomial< FF > &polynomial, const std::string &label, const CommitmentKey::CommitType type=CommitmentKey::CommitType::Default)
A uniform method to mask, commit, and send the corresponding commitment to the verifier.
void prove()
Oink Prover function that runs all the rounds of the verifier.
void execute_preamble_round()
Add circuit size, public input size, and public inputs to transcript.
typename Flavor::CommitmentKey CommitmentKey
SubrelationSeparators generate_alphas_round()
void execute_sorted_list_accumulator_round()
Compute sorted witness-table accumulator and commit to the resulting polynomials.
typename Flavor::SubrelationSeparators SubrelationSeparators
void execute_wire_commitments_round()
Commit to the wire polynomials (part of the witness), with the exception of the fourth wire,...
typename Transcript::Proof Proof
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
void mask()
Add random values to the coefficients of a polynomial. In practice, this is used for ensuring the com...
static void compute_logderivative_inverses(Flavor::ProverPolynomials &polynomials, const size_t circuit_size, RelationParameters< FF > &relation_parameters)
Compute the inverse polynomials used in the log derivative lookup relations.
static void add_ram_rom_memory_records_to_wire_4(typename Flavor::ProverPolynomials &polynomials, const std::vector< uint32_t > &memory_read_records, const std::vector< uint32_t > &memory_write_records, const FF &eta, const FF &eta_two, const FF &eta_three)
Add RAM/ROM memory records to the fourth wire polynomial.
static void compute_grand_product_polynomial(Flavor::ProverPolynomials &polynomials, std::vector< FF > &public_inputs, const size_t pub_inputs_offset, ActiveRegionData &active_region_data, RelationParameters< FF > &relation_parameters, size_t size_override=0)
Computes public_input_delta and the permutation grand product polynomial.
#define vinfo(...)
Definition log.hpp:79
Entry point for Barretenberg command-line interface.
std::string to_string(bb::avm2::ValueTag tag)