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 const size_t ck_size = prover_instance->polynomials.max_end_index();
26 commitment_key = CommitmentKey(ck_size);
27
28 send_vk_hash_and_public_inputs();
29 commit_to_masking_poly();
30
31 // All masked witness polynomials already have random masking values from allocation.
32 commit_to_wires();
33 commit_to_lookup_counts_and_w4();
34 commit_to_logderiv_inverses();
35 commit_to_z_perm();
36 if (emit_alpha) {
37 prover_instance->alpha = transcript->template get_challenge<FF>("alpha");
38 }
39}
40
46{
47 return transcript->export_proof();
48}
49
54{
55 BB_BENCH_NAME("OinkProver::send_vk_hash_and_public_inputs");
56 fr vk_hash = honk_vk->hash_with_origin_tagging(*transcript);
57 transcript->add_to_hash_buffer("vk_hash", vk_hash);
58 vinfo("vk hash in Oink prover: ", vk_hash);
59
60 for (size_t i = 0; i < prover_instance->num_public_inputs(); ++i) {
61 auto public_input_i = prover_instance->public_inputs[i];
62 transcript->send_to_verifier("public_input_" + std::to_string(i), public_input_i);
63 }
64}
65
70template <typename Flavor> void OinkProver<Flavor>::commit_to_wires()
71{
72 BB_BENCH_NAME("OinkProver::commit_to_wires");
73 auto batch = commitment_key.start_batch();
74
75 // Commit to the first three wire polynomials; w_4 is deferred until after memory records are added
76 // Masking values are already in the polynomials
77 batch.add_to_batch(prover_instance->polynomials.w_l, commitment_labels.w_l);
78 batch.add_to_batch(prover_instance->polynomials.w_r, commitment_labels.w_r);
79 batch.add_to_batch(prover_instance->polynomials.w_o, commitment_labels.w_o);
80
81 if constexpr (IsMegaFlavor<Flavor>) {
82 for (auto [polynomial, label] :
83 zip_view(prover_instance->polynomials.get_ecc_op_wires(), commitment_labels.get_ecc_op_wires())) {
84 batch.add_to_batch(polynomial, label);
85 }
86 for (auto [polynomial, label] :
87 zip_view(prover_instance->polynomials.get_databus_entities(), commitment_labels.get_databus_entities())) {
88 batch.add_to_batch(polynomial, label);
89 }
90 }
91
92 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
93 prover_instance->commitments.w_l = computed_commitments[0];
94 prover_instance->commitments.w_r = computed_commitments[1];
95 prover_instance->commitments.w_o = computed_commitments[2];
96
97 if constexpr (IsMegaFlavor<Flavor>) {
98 size_t commitment_idx = 3;
99 for (auto& commitment : prover_instance->commitments.get_ecc_op_wires()) {
100 commitment = computed_commitments[commitment_idx++];
101 }
102 for (auto& commitment : prover_instance->commitments.get_databus_entities()) {
103 commitment = computed_commitments[commitment_idx++];
104 }
105 }
106}
107
113{
114 BB_BENCH_NAME("OinkProver::commit_to_lookup_counts_and_w4");
115 // Get eta challenge and compute powers (eta, eta², eta³)
116 prover_instance->relation_parameters.compute_eta_powers(transcript->template get_challenge<FF>("eta"));
117
118 // Memory record indices are in the active trace region (after disabled rows), so masking is preserved
119 add_ram_rom_memory_records_to_wire_4(*prover_instance);
120
121 auto batch = commitment_key.start_batch();
122 batch.add_to_batch(prover_instance->polynomials.lookup_read_counts, commitment_labels.lookup_read_counts);
123 batch.add_to_batch(prover_instance->polynomials.lookup_read_tags, commitment_labels.lookup_read_tags);
124 batch.add_to_batch(prover_instance->polynomials.w_4, commitment_labels.w_4);
125 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
126
127 prover_instance->commitments.lookup_read_counts = computed_commitments[0];
128 prover_instance->commitments.lookup_read_tags = computed_commitments[1];
129 prover_instance->commitments.w_4 = computed_commitments[2];
130}
131
136template <typename Flavor> void OinkProver<Flavor>::commit_to_logderiv_inverses()
137{
138 BB_BENCH_NAME("OinkProver::commit_to_logderiv_inverses");
139 auto [beta, gamma] = transcript->template get_challenges<FF>(std::array<std::string, 2>{ "beta", "gamma" });
140 prover_instance->relation_parameters.compute_beta_powers(beta);
141 prover_instance->relation_parameters.gamma = gamma;
142
143 // Compute the inverses used in log-derivative lookup relations
144 // For ZK, computation starts after the disabled head region to preserve masking values
145 compute_logderivative_inverses(*prover_instance);
146
147 auto batch = commitment_key.start_batch();
148 batch.add_to_batch(prover_instance->polynomials.lookup_inverses, commitment_labels.lookup_inverses);
149
150 // If Mega, commit to the databus inverse polynomials and send
151 if constexpr (IsMegaFlavor<Flavor>) {
152 for (auto [polynomial, label] :
153 zip_view(prover_instance->polynomials.get_databus_inverses(), commitment_labels.get_databus_inverses())) {
154 batch.add_to_batch(polynomial, label);
155 };
156 }
157 auto computed_commitments = batch.commit_and_send_to_verifier(transcript);
158
159 prover_instance->commitments.lookup_inverses = computed_commitments[0];
160 if constexpr (IsMegaFlavor<Flavor>) {
161 size_t commitment_idx = 1;
162 for (auto& commitment : prover_instance->commitments.get_databus_inverses()) {
163 commitment = computed_commitments[commitment_idx];
164 commitment_idx++;
165 };
166 }
167}
168
172template <typename Flavor> void OinkProver<Flavor>::commit_to_z_perm()
173{
174 BB_BENCH_NAME("OinkProver::commit_to_z_perm");
175
176 // Grand product computation already starts after the disabled region (gp_start), preserving masking values
177 compute_grand_product_polynomial(*prover_instance);
178
179 auto& z_perm = prover_instance->polynomials.z_perm;
180 auto batch = commitment_key.start_batch();
181 batch.add_to_batch(z_perm, commitment_labels.z_perm);
182 auto commitments = batch.commit_and_send_to_verifier(transcript);
183 prover_instance->commitments.z_perm = commitments[0];
184}
185
186template <typename Flavor> void OinkProver<Flavor>::commit_to_masking_poly()
187{
188 if constexpr (flavor_has_gemini_masking<Flavor>()) {
189 // virtual_size = dyadic_size matches every other witness poly, so sumcheck's pairwise read
190 // past end_index lands in the virtual-zero region.
191 prover_instance->polynomials.gemini_masking_poly = Polynomial<FF>::random(
192 prover_instance->polynomials.max_end_index(), prover_instance->dyadic_size(), /*start_index=*/0);
193
194 // Commit to the masking polynomial and send to transcript
195 auto masking_commitment = commitment_key.commit(prover_instance->polynomials.gemini_masking_poly);
196 transcript->send_to_verifier("Gemini:masking_poly_comm", masking_commitment);
197 }
198};
199
210{
211 BB_BENCH_NAME("OinkProver::add_ram_rom_memory_records_to_wire_4");
212 // The memory record values are computed at the indicated indices as
213 // w4 = w3 * eta^3 + w2 * eta^2 + w1 * eta + read_write_flag;
214 // (See the Memory relation for details)
215 auto wires = instance.polynomials.get_wires();
216 const auto& eta = instance.relation_parameters.eta;
217 const auto& eta_two = instance.relation_parameters.eta_two;
218 const auto& eta_three = instance.relation_parameters.eta_three;
219
220 // Compute read record values
221 for (const auto& gate_idx : instance.memory_read_records) {
222 wires[3].at(gate_idx) = wires[2][gate_idx] * eta_three;
223 wires[3].at(gate_idx) += wires[1][gate_idx] * eta_two;
224 wires[3].at(gate_idx) += wires[0][gate_idx] * eta;
225 }
226
227 // Compute write record values
228 for (const auto& gate_idx : instance.memory_write_records) {
229 wires[3].at(gate_idx) = wires[2][gate_idx] * eta_three;
230 wires[3].at(gate_idx) += wires[1][gate_idx] * eta_two;
231 wires[3].at(gate_idx) += wires[0][gate_idx] * eta;
232 wires[3].at(gate_idx) += 1;
233 }
234}
235
243{
244 BB_BENCH_NAME("compute_logderivative_inverses");
245
246 auto& polynomials = instance.polynomials;
247 auto& relation_parameters = instance.relation_parameters;
248 const size_t circuit_size = instance.dyadic_size();
249
250 // Skip the disabled head region to preserve masking values
251 constexpr size_t start = ProverInstance::TRACE_OFFSET;
252
253 // Compute inverses for conventional lookups
254 LogDerivLookupRelation<FF>::compute_logderivative_inverse(polynomials, relation_parameters, circuit_size, start);
255
256 if constexpr (HasDataBus<Flavor>) {
257 // Compute inverses for each bus column's log-derivative lookup argument.
258 bb::constexpr_for<0, NUM_BUS_COLUMNS, 1>([&]<size_t bus_idx>() {
259 DatabusLookupRelation<FF>::template compute_logderivative_inverse<bus_idx>(
260 polynomials, relation_parameters, circuit_size, start);
261 });
262 }
263}
264
271{
272 BB_BENCH_NAME("OinkProver::compute_grand_product_polynomial");
273 auto& relation_parameters = instance.relation_parameters;
274 relation_parameters.public_input_delta = compute_public_input_delta<Flavor>(
275 instance.public_inputs, relation_parameters.beta, relation_parameters.gamma, instance.pub_inputs_offset());
276
277 // Compute permutation grand product polynomial
278 compute_grand_product<Flavor, UltraPermutationRelation<FF>>(
279 instance.polynomials, relation_parameters, instance.get_final_active_wire_idx() + 1);
280}
281
282template class OinkProver<UltraFlavor>;
283template class OinkProver<UltraZKFlavor>;
284template class OinkProver<UltraKeccakFlavor>;
285#ifdef STARKNET_GARAGA_FLAVORS
288#endif
290template class OinkProver<MegaFlavor>;
291template class OinkProver<MegaZKFlavor>;
292template class OinkProver<MegaAvmFlavor>;
293
294} // namespace bb
std::shared_ptr< Napi::ThreadSafeFunction > instance
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:264
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...
static constexpr size_t TRACE_OFFSET
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
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)