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 // For ZK flavors: create and commit to Gemini masking polynomial
29 commit_to_masking_poly();
30 // Compute first three wire commitments
31 execute_wire_commitments_round();
32 // Compute sorted list accumulator and commitment
33 execute_sorted_list_accumulator_round();
34 // Fiat-Shamir: beta & gamma
35 execute_log_derivative_inverse_round();
36 // Compute grand product(s) and commitments.
37 execute_grand_product_computation_round();
38
39 // Generate relation separator alpha for sumcheck computation
40 prover_instance->alpha = generate_alpha_round();
41
42 // #ifndef __wasm__
43 // Free the commitment key
44 prover_instance->commitment_key = CommitmentKey();
45 // #endif
46
47 prover_instance->is_complete = true;
48}
49
54template <IsUltraOrMegaHonk Flavor> typename OinkProver<Flavor>::Proof OinkProver<Flavor>::export_proof()
55{
56 return transcript->export_proof();
57}
58
63template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_preamble_round()
64{
65 BB_BENCH_NAME("OinkProver::execute_preamble_round");
66 fr vk_hash = honk_vk->hash_with_origin_tagging(domain_separator, *transcript);
67 transcript->add_to_hash_buffer(domain_separator + "vk_hash", vk_hash);
68 vinfo("vk hash in Oink prover: ", vk_hash);
69
70 for (size_t i = 0; i < prover_instance->num_public_inputs(); ++i) {
71 auto public_input_i = prover_instance->public_inputs[i];
72 transcript->send_to_verifier(domain_separator + "public_input_" + std::to_string(i), public_input_i);
73 }
74}
75
81template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_wire_commitments_round()
82{
83 BB_BENCH_NAME("OinkProver::execute_wire_commitments_round");
84 // Commit to the first three wire polynomials
85 // We only commit to the fourth wire polynomial after adding memory recordss
86 auto batch = prover_instance->commitment_key.start_batch();
87 // Commit to the first three wire polynomials
88 // We only commit to the fourth wire polynomial after adding memory records
89
90 batch.add_to_batch(prover_instance->polynomials.w_l, commitment_labels.w_l, /*mask?*/ Flavor::HasZK);
91 batch.add_to_batch(prover_instance->polynomials.w_r, commitment_labels.w_r, /*mask?*/ Flavor::HasZK);
92 batch.add_to_batch(prover_instance->polynomials.w_o, commitment_labels.w_o, /*mask?*/ Flavor::HasZK);
93
94 if constexpr (IsMegaFlavor<Flavor>) {
95
96 // Commit to Goblin ECC op wires.
97 // Note even with zk, we do not mask here. The masking for these is done differently.
98 // It is necessary that "random" ops are added to the op_queue, which is then used to populate these ecc op
99 // wires. This is more holistic and obviates the need to extend with random values.
100 bool mask_ecc_op_polys = false; // Flavor::HasZK
101
102 for (auto [polynomial, label] :
103 zip_view(prover_instance->polynomials.get_ecc_op_wires(), commitment_labels.get_ecc_op_wires())) {
104 {
105 BB_BENCH_NAME("COMMIT::ecc_op_wires");
106 batch.add_to_batch(polynomial, domain_separator + label, mask_ecc_op_polys);
107 };
108 }
109
110 // Commit to DataBus related polynomials
111 for (auto [polynomial, label] :
112 zip_view(prover_instance->polynomials.get_databus_entities(), commitment_labels.get_databus_entities())) {
113 {
114 BB_BENCH_NAME("COMMIT::databus");
115 bool is_unmasked_databus_commitment = label == "CALLDATA";
116 batch.add_to_batch(polynomial, label, /*mask?*/ Flavor::HasZK && !is_unmasked_databus_commitment);
117 }
118 }
119 }
120
121 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
122 prover_instance->commitments.w_l = computed_commitments[0];
123 prover_instance->commitments.w_r = computed_commitments[1];
124 prover_instance->commitments.w_o = computed_commitments[2];
125
126 if constexpr (IsMegaFlavor<Flavor>) {
127 size_t commitment_idx = 3;
128 for (auto& commitment : prover_instance->commitments.get_ecc_op_wires()) {
129 commitment = computed_commitments[commitment_idx];
130 commitment_idx++;
131 }
132
133 for (auto& commitment : prover_instance->commitments.get_databus_entities()) {
134 commitment = computed_commitments[commitment_idx];
135 commitment_idx++;
136 }
137 }
138}
139
144template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_sorted_list_accumulator_round()
145{
146 BB_BENCH_NAME("OinkProver::execute_sorted_list_accumulator_round");
147 // Get eta challenges
148 auto [eta, eta_two, eta_three] = transcript->template get_challenges<FF>(std::array<std::string, 3>{
149 domain_separator + "eta", domain_separator + "eta_two", domain_separator + "eta_three" });
150 prover_instance->relation_parameters.eta = eta;
151 prover_instance->relation_parameters.eta_two = eta_two;
152 prover_instance->relation_parameters.eta_three = eta_three;
153
155 prover_instance->memory_read_records,
156 prover_instance->memory_write_records,
157 eta,
158 eta_two,
159 eta_three);
160
161 // Commit to lookup argument polynomials and the finalized (i.e. with memory records) fourth wire polynomial
162 auto batch = prover_instance->commitment_key.start_batch();
163 batch.add_to_batch(prover_instance->polynomials.lookup_read_counts,
164 commitment_labels.lookup_read_counts,
165 /*mask?*/ Flavor::HasZK);
166 batch.add_to_batch(
167 prover_instance->polynomials.lookup_read_tags, commitment_labels.lookup_read_tags, /*mask?*/ Flavor::HasZK);
168 batch.add_to_batch(
169 prover_instance->polynomials.w_4, domain_separator + commitment_labels.w_4, /*mask?*/ Flavor::HasZK);
170 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
171
172 prover_instance->commitments.lookup_read_counts = computed_commitments[0];
173 prover_instance->commitments.lookup_read_tags = computed_commitments[1];
174 prover_instance->commitments.w_4 = computed_commitments[2];
175}
176
181template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_log_derivative_inverse_round()
182{
183 BB_BENCH_NAME("OinkProver::execute_log_derivative_inverse_round");
184 auto [beta, gamma] = transcript->template get_challenges<FF>(
185 std::array<std::string, 2>{ domain_separator + "beta", domain_separator + "gamma" });
186 prover_instance->relation_parameters.beta = beta;
187 prover_instance->relation_parameters.gamma = gamma;
188
189 // Compute the inverses used in log-derivative lookup relations
191 prover_instance->polynomials, prover_instance->dyadic_size(), prover_instance->relation_parameters);
192
193 auto batch = prover_instance->commitment_key.start_batch();
194 batch.add_to_batch(prover_instance->polynomials.lookup_inverses,
195 commitment_labels.lookup_inverses,
196 /*mask?*/ Flavor::HasZK);
197
198 // If Mega, commit to the databus inverse polynomials and send
199 if constexpr (IsMegaFlavor<Flavor>) {
200 for (auto [polynomial, label] :
201 zip_view(prover_instance->polynomials.get_databus_inverses(), commitment_labels.get_databus_inverses())) {
202 batch.add_to_batch(polynomial, label, /*mask?*/ Flavor::HasZK);
203 };
204 }
205 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
206
207 prover_instance->commitments.lookup_inverses = computed_commitments[0];
208 if constexpr (IsMegaFlavor<Flavor>) {
209 size_t commitment_idx = 1;
210 for (auto& commitment : prover_instance->commitments.get_databus_inverses()) {
211 commitment = computed_commitments[commitment_idx];
212 commitment_idx++;
213 };
214 }
215}
216
221template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::execute_grand_product_computation_round()
222{
223 BB_BENCH_NAME("OinkProver::execute_grand_product_computation_round");
224 // Compute the permutation grand product polynomial
225
227 prover_instance->public_inputs,
228 prover_instance->pub_inputs_offset(),
229 prover_instance->relation_parameters,
230 prover_instance->get_final_active_wire_idx() + 1);
231
232 {
233 BB_BENCH_NAME("COMMIT::z_perm");
234 prover_instance->commitments.z_perm =
235 commit_to_witness_polynomial(prover_instance->polynomials.z_perm, commitment_labels.z_perm);
236 }
237}
238
239template <IsUltraOrMegaHonk Flavor> typename Flavor::SubrelationSeparator OinkProver<Flavor>::generate_alpha_round()
240{
241 BB_BENCH_NAME("OinkProver::generate_alpha_round");
242
243 // Get the single alpha challenge for sumcheck computation
244 // Powers of this challenge will be used to batch subrelations
245 return transcript->template get_challenge<FF>(domain_separator + "alpha");
246}
247
255template <IsUltraOrMegaHonk Flavor>
257 const std::string& label)
258{
259 BB_BENCH_NAME("OinkProver::commit_to_witness_polynomial");
260 // Mask the polynomial when proving in zero-knowledge
261 if constexpr (Flavor::HasZK) {
262 polynomial.mask();
263 };
264
265 typename Flavor::Commitment commitment;
266
267 commitment = prover_instance->commitment_key.commit(polynomial);
268 // Send the commitment to the verifier
269 transcript->send_to_verifier(domain_separator + label, commitment);
270
271 return commitment;
272}
273
274template <IsUltraOrMegaHonk Flavor> void OinkProver<Flavor>::commit_to_masking_poly()
275{
276 if constexpr (Flavor::HasZK) {
277 // Create a random masking polynomial for Gemini
278 const size_t polynomial_size = prover_instance->dyadic_size();
279 prover_instance->polynomials.gemini_masking_poly = Polynomial<FF>::random(polynomial_size);
280
281 // Commit to the masking polynomial and send to transcript
282 auto masking_commitment =
283 prover_instance->commitment_key.commit(prover_instance->polynomials.gemini_masking_poly);
284 transcript->send_to_verifier("Gemini:masking_poly_comm", masking_commitment);
285 }
286};
287
288template class OinkProver<UltraFlavor>;
289template class OinkProver<UltraZKFlavor>;
290template class OinkProver<UltraKeccakFlavor>;
291#ifdef STARKNET_GARAGA_FLAVORS
294#endif
296template class OinkProver<UltraRollupFlavor>;
297template class OinkProver<MegaFlavor>;
298template class OinkProver<MegaZKFlavor>;
299
300} // namespace bb
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:219
static constexpr bool HasZK
typename G1::affine_element Commitment
Class for all the oink rounds, which are shared between the folding prover and ultra prover.
Proof export_proof()
Export the Oink proof.
Flavor::Commitment commit_to_witness_polynomial(Polynomial< FF > &polynomial, const std::string &label)
A uniform method to mask, commit, and send the corresponding commitment to the verifier.
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.
void prove()
Oink Prover function that runs all the rounds of the verifier.
SubrelationSeparator generate_alpha_round()
void execute_preamble_round()
Add circuit size, public input size, and public inputs to transcript.
typename Flavor::CommitmentKey CommitmentKey
void execute_sorted_list_accumulator_round()
Compute sorted witness-table accumulator and commit to the resulting polynomials.
void commit_to_masking_poly()
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 .....
static Polynomial random(size_t size, size_t start_index=0)
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 compute_grand_product_polynomial(Flavor::ProverPolynomials &polynomials, std::vector< FF > &public_inputs, const size_t pub_inputs_offset, RelationParameters< FF > &relation_parameters, size_t size_override=0)
Computes public_input_delta and the permutation grand product polynomial.
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.
#define vinfo(...)
Definition log.hpp:80
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)