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: Completed, auditors: [Sergei], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
16
17namespace bb {
18
22template <typename Flavor> void OinkProver<Flavor>::prove(bool emit_alpha)
23{
24 BB_BENCH_NAME("OinkProver::prove");
25 commitment_key = CommitmentKey(prover_instance->polynomials.max_end_index());
26 send_vk_hash_and_public_inputs();
27 commit_to_masking_poly();
28 commit_to_wires();
29 commit_to_lookup_counts_and_w4();
30 commit_to_logderiv_inverses();
31 commit_to_z_perm();
32 if (emit_alpha) {
33 prover_instance->alpha = transcript->template get_challenge<FF>("alpha");
34 }
35}
36
42{
43 return transcript->export_proof();
44}
45
50{
51 BB_BENCH_NAME("OinkProver::send_vk_hash_and_public_inputs");
52 fr vk_hash = honk_vk->hash_with_origin_tagging(*transcript);
53 transcript->add_to_hash_buffer("vk_hash", vk_hash);
54 vinfo("vk hash in Oink prover: ", vk_hash);
55
56 for (size_t i = 0; i < prover_instance->num_public_inputs(); ++i) {
57 auto public_input_i = prover_instance->public_inputs[i];
58 transcript->send_to_verifier("public_input_" + std::to_string(i), public_input_i);
59 }
60}
61
66template <typename Flavor> void OinkProver<Flavor>::commit_to_wires()
67{
68 BB_BENCH_NAME("OinkProver::commit_to_wires");
69 auto batch = commitment_key.start_batch();
70
71 // Commit to the first three wire polynomials; w_4 is deferred until after memory records are added
72 batch.add_to_batch(prover_instance->polynomials.w_l, commitment_labels.w_l, /*mask?*/ Flavor::HasZK);
73 batch.add_to_batch(prover_instance->polynomials.w_r, commitment_labels.w_r, /*mask?*/ Flavor::HasZK);
74 batch.add_to_batch(prover_instance->polynomials.w_o, commitment_labels.w_o, /*mask?*/ Flavor::HasZK);
75
76 if constexpr (IsMegaFlavor<Flavor>) {
77 // ECC op wires are not masked here: masking is achieved by adding random ops to the op_queue instead.
78 for (auto [polynomial, label] :
79 zip_view(prover_instance->polynomials.get_ecc_op_wires(), commitment_labels.get_ecc_op_wires())) {
80 batch.add_to_batch(polynomial, label, /*mask?*/ false);
81 }
82
83 // DataBus polynomials: calldata is left unmasked, everything else is masked in ZK mode
84 for (auto [polynomial, label] :
85 zip_view(prover_instance->polynomials.get_databus_entities(), commitment_labels.get_databus_entities())) {
86 bool mask = Flavor::HasZK && (label != commitment_labels.calldata);
87 batch.add_to_batch(polynomial, label, mask);
88 }
89 }
90
91 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
92 prover_instance->commitments.w_l = computed_commitments[0];
93 prover_instance->commitments.w_r = computed_commitments[1];
94 prover_instance->commitments.w_o = computed_commitments[2];
95
96 if constexpr (IsMegaFlavor<Flavor>) {
97 size_t commitment_idx = 3;
98 for (auto& commitment : prover_instance->commitments.get_ecc_op_wires()) {
99 commitment = computed_commitments[commitment_idx++];
100 }
101 for (auto& commitment : prover_instance->commitments.get_databus_entities()) {
102 commitment = computed_commitments[commitment_idx++];
103 }
104 }
105}
106
112{
113 BB_BENCH_NAME("OinkProver::commit_to_lookup_counts_and_w4");
114 // Get eta challenge and compute powers (eta, eta², eta³)
115 prover_instance->relation_parameters.compute_eta_powers(transcript->template get_challenge<FF>("eta"));
116
117 add_ram_rom_memory_records_to_wire_4(*prover_instance);
118
119 // Commit to lookup argument polynomials and the finalized (i.e. with memory records) fourth wire polynomial
120 auto batch = commitment_key.start_batch();
121 batch.add_to_batch(prover_instance->polynomials.lookup_read_counts,
122 commitment_labels.lookup_read_counts,
123 /*mask?*/ Flavor::HasZK);
124 batch.add_to_batch(
125 prover_instance->polynomials.lookup_read_tags, commitment_labels.lookup_read_tags, /*mask?*/ Flavor::HasZK);
126 batch.add_to_batch(prover_instance->polynomials.w_4, commitment_labels.w_4, /*mask?*/ Flavor::HasZK);
127 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
128
129 prover_instance->commitments.lookup_read_counts = computed_commitments[0];
130 prover_instance->commitments.lookup_read_tags = computed_commitments[1];
131 prover_instance->commitments.w_4 = computed_commitments[2];
132}
133
138template <typename Flavor> void OinkProver<Flavor>::commit_to_logderiv_inverses()
139{
140 BB_BENCH_NAME("OinkProver::commit_to_logderiv_inverses");
141 auto [beta, gamma] = transcript->template get_challenges<FF>(std::array<std::string, 2>{ "beta", "gamma" });
142 prover_instance->relation_parameters.compute_beta_powers(beta);
143 prover_instance->relation_parameters.gamma = gamma;
144
145 // Compute the inverses used in log-derivative lookup relations
146 compute_logderivative_inverses(*prover_instance);
147
148 auto batch = commitment_key.start_batch();
149 batch.add_to_batch(prover_instance->polynomials.lookup_inverses,
150 commitment_labels.lookup_inverses,
151 /*mask?*/ Flavor::HasZK);
152
153 // If Mega, commit to the databus inverse polynomials and send
154 if constexpr (IsMegaFlavor<Flavor>) {
155 for (auto [polynomial, label] :
156 zip_view(prover_instance->polynomials.get_databus_inverses(), commitment_labels.get_databus_inverses())) {
157 batch.add_to_batch(polynomial, label, /*mask?*/ Flavor::HasZK);
158 };
159 }
160 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
161
162 prover_instance->commitments.lookup_inverses = computed_commitments[0];
163 if constexpr (IsMegaFlavor<Flavor>) {
164 size_t commitment_idx = 1;
165 for (auto& commitment : prover_instance->commitments.get_databus_inverses()) {
166 commitment = computed_commitments[commitment_idx];
167 commitment_idx++;
168 };
169 }
170}
171
175template <typename Flavor> void OinkProver<Flavor>::commit_to_z_perm()
176{
177 BB_BENCH_NAME("OinkProver::commit_to_z_perm");
178
179 compute_grand_product_polynomial(*prover_instance);
180
181 auto& z_perm = prover_instance->polynomials.z_perm;
182 if constexpr (Flavor::HasZK) {
183 z_perm.mask();
184 }
185 {
186 BB_BENCH_NAME("COMMIT::z_perm");
187 prover_instance->commitments.z_perm = commitment_key.commit(z_perm);
188 }
189 transcript->send_to_verifier(commitment_labels.z_perm, prover_instance->commitments.z_perm);
190}
191
192template <typename Flavor> void OinkProver<Flavor>::commit_to_masking_poly()
193{
194 if constexpr (Flavor::HasZK) {
195 // Create a random masking polynomial for Gemini
196 const size_t polynomial_size = prover_instance->dyadic_size();
197 prover_instance->polynomials.gemini_masking_poly = Polynomial<FF>::random(polynomial_size);
198
199 // Commit to the masking polynomial and send to transcript
200 auto masking_commitment = commitment_key.commit(prover_instance->polynomials.gemini_masking_poly);
201 transcript->send_to_verifier("Gemini:masking_poly_comm", masking_commitment);
202 }
203};
204
215{
216 // The memory record values are computed at the indicated indices as
217 // w4 = w3 * eta^3 + w2 * eta^2 + w1 * eta + read_write_flag;
218 // (See the Memory relation for details)
219 auto wires = instance.polynomials.get_wires();
220 const auto& eta = instance.relation_parameters.eta;
221 const auto& eta_two = instance.relation_parameters.eta_two;
222 const auto& eta_three = instance.relation_parameters.eta_three;
223
224 // Compute read record values
225 for (const auto& gate_idx : instance.memory_read_records) {
226 wires[3].at(gate_idx) = wires[2][gate_idx] * eta_three;
227 wires[3].at(gate_idx) += wires[1][gate_idx] * eta_two;
228 wires[3].at(gate_idx) += wires[0][gate_idx] * eta;
229 }
230
231 // Compute write record values
232 for (const auto& gate_idx : instance.memory_write_records) {
233 wires[3].at(gate_idx) = wires[2][gate_idx] * eta_three;
234 wires[3].at(gate_idx) += wires[1][gate_idx] * eta_two;
235 wires[3].at(gate_idx) += wires[0][gate_idx] * eta;
236 wires[3].at(gate_idx) += 1;
237 }
238}
239
247{
248 BB_BENCH_NAME("compute_logderivative_inverses");
249
250 auto& polynomials = instance.polynomials;
251 auto& relation_parameters = instance.relation_parameters;
252 const size_t circuit_size = instance.dyadic_size();
253
254 // Compute inverses for conventional lookups
255 LogDerivLookupRelation<FF>::compute_logderivative_inverse(polynomials, relation_parameters, circuit_size);
256
257 if constexpr (HasDataBus<Flavor>) {
258 // Compute inverses for calldata reads
260 polynomials, relation_parameters, circuit_size);
261
262 // Compute inverses for secondary_calldata reads
264 polynomials, relation_parameters, circuit_size);
265
266 // Compute inverses for return data reads
268 polynomials, relation_parameters, circuit_size);
269 }
270}
271
278{
279 auto& relation_parameters = instance.relation_parameters;
280 relation_parameters.public_input_delta = compute_public_input_delta<Flavor>(
281 instance.public_inputs, relation_parameters.beta, relation_parameters.gamma, instance.pub_inputs_offset());
282
283 // Compute permutation grand product polynomial
284 compute_grand_product<Flavor, UltraPermutationRelation<FF>>(
285 instance.polynomials, relation_parameters, instance.get_final_active_wire_idx() + 1);
286}
287
288template class OinkProver<UltraFlavor>;
289template class OinkProver<UltraZKFlavor>;
290template class OinkProver<UltraKeccakFlavor>;
291#ifdef STARKNET_GARAGA_FLAVORS
294#endif
296template class OinkProver<MegaFlavor>;
297template class OinkProver<MegaZKFlavor>;
298template class OinkProver<MegaAvmFlavor>;
299
300} // namespace bb
std::shared_ptr< Napi::ThreadSafeFunction > instance
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:225
static constexpr bool HasZK
Executes the "Oink" phase of the Honk proving protocol: the initial rounds that commit to witness dat...
void prove(bool emit_alpha=true)
Commit to witnesses, compute relation parameters, and prepare for Sumcheck.
Proof export_proof()
Export the Oink proof.
static void compute_logderivative_inverses(ProverInstance &instance)
Compute the inverse polynomials used in the log derivative lookup relations.
void commit_to_logderiv_inverses()
Compute log derivative inverse polynomial and its commitment, if required.
void send_vk_hash_and_public_inputs()
Hash the verification key and send public inputs to the transcript.
static void add_ram_rom_memory_records_to_wire_4(ProverInstance &instance)
Add RAM/ROM memory records to the fourth wire polynomial.
typename Flavor::CommitmentKey CommitmentKey
void commit_to_lookup_counts_and_w4()
Compute sorted witness-table accumulator and commit to the resulting polynomials.
void commit_to_z_perm()
Compute the permutation grand product polynomial and commit to it.
static void compute_grand_product_polynomial(ProverInstance &instance)
Computes public_input_delta and the permutation grand product polynomial.
void commit_to_masking_poly()
void commit_to_wires()
Commit to the wire polynomials (part of the witness), with the exception of the fourth wire,...
typename Transcript::Proof Proof
static Polynomial random(size_t size, size_t start_index=0)
Contains all the information required by a Honk prover to create a proof, constructed from a finalize...
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
#define vinfo(...)
Definition log.hpp:94
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
void compute_logderivative_inverse(Polynomials &polynomials, auto &relation_parameters, const size_t circuit_size)
Compute the inverse polynomial I(X) required for logderivative lookups.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)