Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
proof_structures.hpp
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
7#pragma once
8
19
20namespace bb {
21
29template <typename Flavor> struct StructuredProof;
30
31// ============================================================================
32// Common base with type definitions and helper methods
33// ============================================================================
34template <typename Flavor> struct StructuredProofHelper {
35 using FF = typename Flavor::FF;
38 using Codec = typename Transcript::Codec;
39 using ProofData = typename Transcript::Proof;
41 static constexpr size_t NUM_ALL_ENTITIES = Flavor::NUM_ALL_ENTITIES;
42
43 protected:
44 template <typename T> static T deserialize_from_buffer(const ProofData& proof_data, size_t& offset)
45 {
46 constexpr size_t element_size = Codec::template calc_num_fields<T>();
47 BB_ASSERT_LTE(offset + element_size, proof_data.size());
48 auto element_span = std::span{ proof_data }.subspan(offset, element_size);
49 offset += element_size;
50 return Codec::template deserialize_from_fields<T>(element_span);
51 }
52
53 template <typename T> static void serialize_to_buffer(const T& element, ProofData& proof_data)
54 {
55 auto element_fields = Codec::serialize_to_fields(element);
56 proof_data.insert(proof_data.end(), element_fields.begin(), element_fields.end());
57 }
58};
59
60// ============================================================================
61// Ultra proof structure base with common fields and helper methods
62// ============================================================================
63template <typename Flavor> struct UltraStructuredProofBase : StructuredProofHelper<Flavor> {
67 using typename Base::Commitment;
68 using typename Base::FF;
69 using typename Base::ProofData;
70
71 // Common fields shared between ZK and non-ZK
72 std::vector<FF> public_inputs;
82 std::array<FF, NUM_ALL_ENTITIES> sumcheck_evaluations;
83 std::vector<Commitment> gemini_fold_comms;
84 std::vector<FF> gemini_fold_evals;
87
88 protected:
90 {
91 public_inputs.clear();
93 gemini_fold_comms.clear();
94 gemini_fold_evals.clear();
95 }
96
97 // Helper: deserialize Ultra witness commitments
98 void deserialize_ultra_witness_comms(const ProofData& proof_data, size_t& offset)
99 {
100 w_l_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
101 w_r_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
102 w_o_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
103 lookup_read_counts_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
104 lookup_read_tags_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
105 w_4_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
106 lookup_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
107 z_perm_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
108 }
109
110 // Helper: serialize Ultra witness commitments
122
123 // Helper: deserialize sumcheck data
124 void deserialize_sumcheck(const ProofData& proof_data, size_t& offset, size_t log_n)
125 {
126 for (size_t i = 0; i < log_n; ++i) {
127 sumcheck_univariates.push_back(
129 offset));
130 }
132 this->template deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(proof_data, offset);
133 }
134
135 // Helper: serialize sumcheck data
136 void serialize_sumcheck(ProofData& proof_data, size_t log_n) const
137 {
138 for (size_t i = 0; i < log_n; ++i) {
140 }
142 }
143
144 // Helper: deserialize Gemini/Shplonk/KZG data
145 void deserialize_pcs(const ProofData& proof_data, size_t& offset, size_t log_n)
146 {
147 for (size_t i = 0; i < log_n - 1; ++i) {
148 gemini_fold_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
149 }
150 for (size_t i = 0; i < log_n; ++i) {
151 gemini_fold_evals.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
152 }
153 shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
154 kzg_w_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
155 }
156
157 // Helper: serialize Gemini/Shplonk/KZG data
158 void serialize_pcs(ProofData& proof_data, size_t log_n) const
159 {
160 for (size_t i = 0; i < log_n - 1; ++i) {
162 }
163 for (size_t i = 0; i < log_n; ++i) {
165 }
168 }
169
170 public:
171 void deserialize(ProofData& proof_data, size_t num_public_inputs, size_t log_n)
172 {
173 size_t offset = 0;
175
176 for (size_t i = 0; i < num_public_inputs; ++i) {
177 public_inputs.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
178 }
180 deserialize_sumcheck(proof_data, offset, log_n);
181 deserialize_pcs(proof_data, offset, log_n);
182 }
183
184 void serialize(ProofData& proof_data, size_t log_n) const
185 {
186 size_t old_size = proof_data.size();
187 proof_data.clear();
188
189 for (const auto& pi : public_inputs) {
190 Base::serialize_to_buffer(pi, proof_data);
191 }
193 serialize_sumcheck(proof_data, log_n);
194 serialize_pcs(proof_data, log_n);
195
196 BB_ASSERT_EQ(proof_data.size(), old_size);
197 }
198};
199
200// ============================================================================
201// Ultra ZK proof structure - extends Ultra with ZK-specific fields
202// ============================================================================
205 using typename Base::Commitment;
206 using typename Base::FF;
207 using typename Base::ProofData;
208
209 // ZK-specific fields
220
221 void deserialize(ProofData& proof_data, size_t num_public_inputs, size_t log_n)
222 {
223 size_t offset = 0;
224 this->clear_vectors();
225
226 for (size_t i = 0; i < num_public_inputs; ++i) {
227 this->public_inputs.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
228 }
229 hiding_polynomial_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
230 this->deserialize_ultra_witness_comms(proof_data, offset);
231 libra_concatenation_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
232 libra_sum = this->template deserialize_from_buffer<FF>(proof_data, offset);
233
234 // Sumcheck univariates
235 for (size_t i = 0; i < log_n; ++i) {
236 this->sumcheck_univariates.push_back(
237 this->template deserialize_from_buffer<bb::Univariate<FF, Base::BATCHED_RELATION_PARTIAL_LENGTH>>(
238 proof_data, offset));
239 }
240 libra_claimed_evaluation = this->template deserialize_from_buffer<FF>(proof_data, offset);
241 this->sumcheck_evaluations =
242 this->template deserialize_from_buffer<std::array<FF, Base::NUM_ALL_ENTITIES>>(proof_data, offset);
243 libra_grand_sum_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
244 libra_quotient_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
245
246 // Gemini
247 for (size_t i = 0; i < log_n - 1; ++i) {
248 this->gemini_fold_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
249 }
250 for (size_t i = 0; i < log_n; ++i) {
251 this->gemini_fold_evals.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
252 }
253 libra_concatenation_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
254 libra_shifted_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
255 libra_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
256 libra_quotient_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
257 this->shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
258 this->kzg_w_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
259 }
260
261 void serialize(ProofData& proof_data, size_t log_n) const
262 {
263 size_t old_size = proof_data.size();
264 proof_data.clear();
265
266 for (const auto& pi : this->public_inputs) {
267 Base::serialize_to_buffer(pi, proof_data);
268 }
269 Base::serialize_to_buffer(hiding_polynomial_commitment, proof_data);
270 this->serialize_ultra_witness_comms(proof_data);
271 Base::serialize_to_buffer(libra_concatenation_commitment, proof_data);
272 Base::serialize_to_buffer(libra_sum, proof_data);
273
274 // Sumcheck univariates
275 for (size_t i = 0; i < log_n; ++i) {
276 Base::serialize_to_buffer(this->sumcheck_univariates[i], proof_data);
277 }
278 Base::serialize_to_buffer(libra_claimed_evaluation, proof_data);
279 Base::serialize_to_buffer(this->sumcheck_evaluations, proof_data);
280 Base::serialize_to_buffer(libra_grand_sum_commitment, proof_data);
281 Base::serialize_to_buffer(libra_quotient_commitment, proof_data);
282
283 // Gemini
284 for (size_t i = 0; i < log_n - 1; ++i) {
285 Base::serialize_to_buffer(this->gemini_fold_comms[i], proof_data);
286 }
287 for (size_t i = 0; i < log_n; ++i) {
288 Base::serialize_to_buffer(this->gemini_fold_evals[i], proof_data);
289 }
290 Base::serialize_to_buffer(libra_concatenation_eval, proof_data);
291 Base::serialize_to_buffer(libra_shifted_grand_sum_eval, proof_data);
292 Base::serialize_to_buffer(libra_grand_sum_eval, proof_data);
293 Base::serialize_to_buffer(libra_quotient_eval, proof_data);
294 Base::serialize_to_buffer(this->shplonk_q_comm, proof_data);
295 Base::serialize_to_buffer(this->kzg_w_comm, proof_data);
296
297 BB_ASSERT_EQ(proof_data.size(), old_size);
298 }
299};
300
301// ============================================================================
302// Mega proof structure base with common fields and helper methods
303// ============================================================================
304template <typename Flavor> struct MegaStructuredProofBase : StructuredProofHelper<Flavor> {
306 using Base::BATCHED_RELATION_PARTIAL_LENGTH;
307 using Base::NUM_ALL_ENTITIES;
308 using typename Base::Commitment;
309 using typename Base::FF;
310 using typename Base::ProofData;
311
312 // Common fields shared between ZK and non-ZK
313 std::vector<FF> public_inputs;
321 // Per-bus commitments. MegaZK keeps only the kernel_calldata bus; MegaFlavor carries all five.
322 std::array<Commitment, Flavor::NUM_BUS_COLUMNS> bus_comms;
323 std::array<Commitment, Flavor::NUM_BUS_COLUMNS> bus_read_counts_comms;
324 std::array<Commitment, Flavor::NUM_BUS_COLUMNS> bus_inverses_comms;
331 std::array<FF, NUM_ALL_ENTITIES> sumcheck_evaluations;
332 std::vector<Commitment> gemini_fold_comms;
333 std::vector<FF> gemini_fold_evals;
336
337 protected:
339 {
340 public_inputs.clear();
341 sumcheck_univariates.clear();
342 gemini_fold_comms.clear();
343 gemini_fold_evals.clear();
344 }
345
346 // Helper: deserialize Mega witness commitments
347 void deserialize_mega_witness_comms(const ProofData& proof_data, size_t& offset)
348 {
349 w_l_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
350 w_r_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
351 w_o_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
352 ecc_op_wire_1_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
353 ecc_op_wire_2_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
354 ecc_op_wire_3_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
355 ecc_op_wire_4_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
356 for (size_t i = 0; i < Flavor::NUM_BUS_COLUMNS; ++i) {
357 bus_comms[i] = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
358 bus_read_counts_comms[i] = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
359 }
360 if constexpr (Flavor::HasLogDerivLookup) {
361 lookup_read_counts_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
362 lookup_read_tags_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
363 }
364 w_4_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
365 if constexpr (Flavor::HasLogDerivLookup) {
366 lookup_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
367 }
368 for (size_t i = 0; i < Flavor::NUM_BUS_COLUMNS; ++i) {
369 bus_inverses_comms[i] = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
370 }
371 z_perm_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
372 }
373
374 // Helper: serialize Mega witness commitments
376 {
377 Base::serialize_to_buffer(w_l_comm, proof_data);
378 Base::serialize_to_buffer(w_r_comm, proof_data);
379 Base::serialize_to_buffer(w_o_comm, proof_data);
380 Base::serialize_to_buffer(ecc_op_wire_1_comm, proof_data);
381 Base::serialize_to_buffer(ecc_op_wire_2_comm, proof_data);
382 Base::serialize_to_buffer(ecc_op_wire_3_comm, proof_data);
383 Base::serialize_to_buffer(ecc_op_wire_4_comm, proof_data);
384 for (size_t i = 0; i < Flavor::NUM_BUS_COLUMNS; ++i) {
385 Base::serialize_to_buffer(bus_comms[i], proof_data);
386 Base::serialize_to_buffer(bus_read_counts_comms[i], proof_data);
387 }
388 if constexpr (Flavor::HasLogDerivLookup) {
389 Base::serialize_to_buffer(lookup_read_counts_comm, proof_data);
390 Base::serialize_to_buffer(lookup_read_tags_comm, proof_data);
391 }
392 Base::serialize_to_buffer(w_4_comm, proof_data);
393 if constexpr (Flavor::HasLogDerivLookup) {
394 Base::serialize_to_buffer(lookup_inverses_comm, proof_data);
395 }
396 for (size_t i = 0; i < Flavor::NUM_BUS_COLUMNS; ++i) {
397 Base::serialize_to_buffer(bus_inverses_comms[i], proof_data);
398 }
399 Base::serialize_to_buffer(z_perm_comm, proof_data);
400 }
401
402 // Helper: deserialize sumcheck data
403 void deserialize_sumcheck(const ProofData& proof_data, size_t& offset, size_t log_n)
404 {
405 for (size_t i = 0; i < log_n; ++i) {
406 sumcheck_univariates.push_back(
407 this->template deserialize_from_buffer<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(proof_data,
408 offset));
409 }
410 sumcheck_evaluations =
411 this->template deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(proof_data, offset);
412 }
413
414 // Helper: serialize sumcheck data
415 void serialize_sumcheck(ProofData& proof_data, size_t log_n) const
416 {
417 for (size_t i = 0; i < log_n; ++i) {
418 Base::serialize_to_buffer(sumcheck_univariates[i], proof_data);
419 }
420 Base::serialize_to_buffer(sumcheck_evaluations, proof_data);
421 }
422
423 // Helper: deserialize Gemini/Shplonk/KZG data
424 void deserialize_pcs(const ProofData& proof_data, size_t& offset, size_t log_n)
425 {
426 for (size_t i = 0; i < log_n - 1; ++i) {
427 gemini_fold_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
428 }
429 for (size_t i = 0; i < log_n; ++i) {
430 gemini_fold_evals.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
431 }
432 shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
433 kzg_w_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
434 }
435
436 // Helper: serialize Gemini/Shplonk/KZG data
437 void serialize_pcs(ProofData& proof_data, size_t log_n) const
438 {
439 for (size_t i = 0; i < log_n - 1; ++i) {
440 Base::serialize_to_buffer(gemini_fold_comms[i], proof_data);
441 }
442 for (size_t i = 0; i < log_n; ++i) {
443 Base::serialize_to_buffer(gemini_fold_evals[i], proof_data);
444 }
445 Base::serialize_to_buffer(shplonk_q_comm, proof_data);
446 Base::serialize_to_buffer(kzg_w_comm, proof_data);
447 }
448
449 public:
450 void deserialize(ProofData& proof_data, size_t num_public_inputs, size_t log_n)
451 {
452 size_t offset = 0;
453 clear_vectors();
454
455 for (size_t i = 0; i < num_public_inputs; ++i) {
456 public_inputs.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
457 }
458 deserialize_mega_witness_comms(proof_data, offset);
459 deserialize_sumcheck(proof_data, offset, log_n);
460 deserialize_pcs(proof_data, offset, log_n);
461 }
462
463 void serialize(ProofData& proof_data, size_t log_n) const
464 {
465 size_t old_size = proof_data.size();
466 proof_data.clear();
467
468 for (const auto& pi : public_inputs) {
469 Base::serialize_to_buffer(pi, proof_data);
470 }
471 serialize_mega_witness_comms(proof_data);
472 serialize_sumcheck(proof_data, log_n);
473 serialize_pcs(proof_data, log_n);
474
475 BB_ASSERT_EQ(proof_data.size(), old_size);
476 }
477};
478
479// ============================================================================
480// Mega ZK proof structure - extends Mega with ZK-specific fields
481// ============================================================================
484 using typename Base::Commitment;
485 using typename Base::FF;
486 using typename Base::ProofData;
487
488 // ZK-specific fields
499
500 void deserialize(ProofData& proof_data, size_t num_public_inputs, size_t log_n)
501 {
502 size_t offset = 0;
503 this->clear_vectors();
504
505 for (size_t i = 0; i < num_public_inputs; ++i) {
506 this->public_inputs.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
507 }
508 if constexpr (flavor_has_gemini_masking<Flavor>()) {
509 hiding_polynomial_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
510 }
511 this->deserialize_mega_witness_comms(proof_data, offset);
512 libra_concatenation_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
513 libra_sum = this->template deserialize_from_buffer<FF>(proof_data, offset);
514
515 // Sumcheck univariates
516 for (size_t i = 0; i < log_n; ++i) {
517 this->sumcheck_univariates.push_back(
518 this->template deserialize_from_buffer<bb::Univariate<FF, Base::BATCHED_RELATION_PARTIAL_LENGTH>>(
519 proof_data, offset));
520 }
521 libra_claimed_evaluation = this->template deserialize_from_buffer<FF>(proof_data, offset);
522 this->sumcheck_evaluations =
523 this->template deserialize_from_buffer<std::array<FF, Base::NUM_ALL_ENTITIES>>(proof_data, offset);
524 libra_grand_sum_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
525 libra_quotient_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
526
527 // Gemini
528 for (size_t i = 0; i < log_n - 1; ++i) {
529 this->gemini_fold_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
530 }
531 for (size_t i = 0; i < log_n; ++i) {
532 this->gemini_fold_evals.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
533 }
534 libra_concatenation_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
535 libra_shifted_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
536 libra_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
537 libra_quotient_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
538 this->shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
539 this->kzg_w_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
540 }
541
542 void serialize(ProofData& proof_data, size_t log_n) const
543 {
544 size_t old_size = proof_data.size();
545 proof_data.clear();
546
547 for (const auto& pi : this->public_inputs) {
548 Base::serialize_to_buffer(pi, proof_data);
549 }
550 if constexpr (flavor_has_gemini_masking<Flavor>()) {
551 Base::serialize_to_buffer(hiding_polynomial_commitment, proof_data);
552 }
553 this->serialize_mega_witness_comms(proof_data);
554 Base::serialize_to_buffer(libra_concatenation_commitment, proof_data);
555 Base::serialize_to_buffer(libra_sum, proof_data);
556
557 // Sumcheck univariates
558 for (size_t i = 0; i < log_n; ++i) {
559 Base::serialize_to_buffer(this->sumcheck_univariates[i], proof_data);
560 }
561 Base::serialize_to_buffer(libra_claimed_evaluation, proof_data);
562 Base::serialize_to_buffer(this->sumcheck_evaluations, proof_data);
563 Base::serialize_to_buffer(libra_grand_sum_commitment, proof_data);
564 Base::serialize_to_buffer(libra_quotient_commitment, proof_data);
565
566 // Gemini
567 for (size_t i = 0; i < log_n - 1; ++i) {
568 Base::serialize_to_buffer(this->gemini_fold_comms[i], proof_data);
569 }
570 for (size_t i = 0; i < log_n; ++i) {
571 Base::serialize_to_buffer(this->gemini_fold_evals[i], proof_data);
572 }
573 Base::serialize_to_buffer(libra_concatenation_eval, proof_data);
574 Base::serialize_to_buffer(libra_shifted_grand_sum_eval, proof_data);
575 Base::serialize_to_buffer(libra_grand_sum_eval, proof_data);
576 Base::serialize_to_buffer(libra_quotient_eval, proof_data);
577 Base::serialize_to_buffer(this->shplonk_q_comm, proof_data);
578 Base::serialize_to_buffer(this->kzg_w_comm, proof_data);
579
580 BB_ASSERT_EQ(proof_data.size(), old_size);
581 }
582};
583
584// ============================================================================
585// Translator proof structure (always ZK, with interleaved claims)
586// ============================================================================
589 using Base::BATCHED_RELATION_PARTIAL_LENGTH;
590 using Base::NUM_ALL_ENTITIES;
591 using typename Base::Commitment;
592 using typename Base::FF;
593 using typename Base::ProofData;
594
595 // Number of wire commitments sent in proof (concatenated + ordered range constraints)
596 static constexpr size_t NUM_BATCH_WITNESS_COMMS = Flavor::NUM_COMMITMENTS_IN_PROOF;
597 // Minicircuit evaluations are sent mid-sumcheck after LOG_MINI_CIRCUIT_SIZE rounds
598 static constexpr size_t LOG_MINI_CIRCUIT_SIZE = Flavor::LOG_MINI_CIRCUIT_SIZE;
599 static constexpr size_t NUM_MINICIRCUIT_EVALUATIONS = Flavor::NUM_MINICIRCUIT_EVALUATIONS;
600 static constexpr size_t NUM_FULL_CIRCUIT_EVALUATIONS = Flavor::NUM_FULL_CIRCUIT_EVALUATIONS;
601
602 // Witness commitments
604 std::vector<Commitment> witness_comms; // non-opqueue wires + ordered range constraints
606
607 // Libra (ZK - Translator is always ZK)
610
611 // Sumcheck: univariates are split around interleaved minicircuit evaluations
613 // Minicircuit wire evaluations (sent mid-sumcheck after LOG_MINI_CIRCUIT_SIZE rounds)
615 // Full-circuit evaluations (sent after all sumcheck rounds)
618
619 // Post-sumcheck Libra commitments
622
623 // Gemini/Shplemini
624 std::vector<Commitment> gemini_fold_comms;
625 std::vector<FF> gemini_fold_evals;
626
627 // Libra evaluations
632
633 // Final PCS
636
637 void deserialize(ProofData& proof_data, size_t /*num_public_inputs*/, size_t log_n)
638 {
639 size_t offset = 0;
640 witness_comms.clear();
641 sumcheck_univariates.clear();
642 gemini_fold_comms.clear();
643 gemini_fold_evals.clear();
644
645 // Witness commitments
646 gemini_masking_poly_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
647 for (size_t i = 0; i < NUM_BATCH_WITNESS_COMMS; ++i) {
648 witness_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
649 }
650 z_perm_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
651
652 // Libra pre-sumcheck
653 libra_concatenation_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
654 libra_sum = this->template deserialize_from_buffer<FF>(proof_data, offset);
655
656 // Sumcheck univariates (first LOG_MINI_CIRCUIT_SIZE rounds)
657 for (size_t i = 0; i < LOG_MINI_CIRCUIT_SIZE; ++i) {
658 sumcheck_univariates.push_back(
659 this->template deserialize_from_buffer<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(proof_data,
660 offset));
661 }
662 // Minicircuit evaluations (interleaved mid-sumcheck)
663 minicircuit_evaluations =
664 this->template deserialize_from_buffer<std::array<FF, NUM_MINICIRCUIT_EVALUATIONS>>(proof_data, offset);
665 // Sumcheck univariates (remaining rounds)
666 for (size_t i = LOG_MINI_CIRCUIT_SIZE; i < log_n; ++i) {
667 sumcheck_univariates.push_back(
668 this->template deserialize_from_buffer<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(proof_data,
669 offset));
670 }
671 // Full-circuit evaluations (excludes computable precomputed + concatenated + minicircuit)
672 full_circuit_evaluations =
673 this->template deserialize_from_buffer<std::array<FF, NUM_FULL_CIRCUIT_EVALUATIONS>>(proof_data, offset);
674 libra_claimed_evaluation = this->template deserialize_from_buffer<FF>(proof_data, offset);
675
676 // Libra post-sumcheck commitments
677 libra_grand_sum_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
678 libra_quotient_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
679
680 // Gemini fold commitments and evaluations
681 for (size_t i = 0; i < log_n - 1; ++i) {
682 gemini_fold_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
683 }
684 for (size_t i = 0; i < log_n; ++i) {
685 gemini_fold_evals.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
686 }
687
688 // Libra evaluations
689 libra_concatenation_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
690 libra_shifted_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
691 libra_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
692 libra_quotient_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
693
694 // Final PCS
695 shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
696 kzg_w_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
697 }
698
699 void serialize(ProofData& proof_data, size_t log_n) const
700 {
701 size_t old_size = proof_data.size();
702 proof_data.clear();
703
704 // Witness commitments
705 Base::serialize_to_buffer(gemini_masking_poly_comm, proof_data);
706 for (const auto& comm : witness_comms) {
707 Base::serialize_to_buffer(comm, proof_data);
708 }
709 Base::serialize_to_buffer(z_perm_comm, proof_data);
710
711 // Libra pre-sumcheck
712 Base::serialize_to_buffer(libra_concatenation_commitment, proof_data);
713 Base::serialize_to_buffer(libra_sum, proof_data);
714
715 // Sumcheck univariates (first LOG_MINI_CIRCUIT_SIZE rounds)
716 for (size_t i = 0; i < LOG_MINI_CIRCUIT_SIZE; ++i) {
717 Base::serialize_to_buffer(sumcheck_univariates[i], proof_data);
718 }
719 // Minicircuit evaluations (interleaved mid-sumcheck)
720 Base::serialize_to_buffer(minicircuit_evaluations, proof_data);
721 // Sumcheck univariates (remaining rounds)
722 for (size_t i = LOG_MINI_CIRCUIT_SIZE; i < log_n; ++i) {
723 Base::serialize_to_buffer(sumcheck_univariates[i], proof_data);
724 }
725 // Full-circuit evaluations
726 Base::serialize_to_buffer(full_circuit_evaluations, proof_data);
727 Base::serialize_to_buffer(libra_claimed_evaluation, proof_data);
728
729 // Libra post-sumcheck commitments
730 Base::serialize_to_buffer(libra_grand_sum_commitment, proof_data);
731 Base::serialize_to_buffer(libra_quotient_commitment, proof_data);
732
733 // Gemini fold commitments and evaluations
734 for (size_t i = 0; i < log_n - 1; ++i) {
735 Base::serialize_to_buffer(gemini_fold_comms[i], proof_data);
736 }
737 for (size_t i = 0; i < log_n; ++i) {
738 Base::serialize_to_buffer(gemini_fold_evals[i], proof_data);
739 }
740
741 // Libra evaluations
742 Base::serialize_to_buffer(libra_concatenation_eval, proof_data);
743 Base::serialize_to_buffer(libra_shifted_grand_sum_eval, proof_data);
744 Base::serialize_to_buffer(libra_grand_sum_eval, proof_data);
745 Base::serialize_to_buffer(libra_quotient_eval, proof_data);
746
747 // Final PCS
748 Base::serialize_to_buffer(shplonk_q_comm, proof_data);
749 Base::serialize_to_buffer(kzg_w_comm, proof_data);
750
751 BB_ASSERT_EQ(proof_data.size(), old_size);
752 }
753};
754
755// ============================================================================
756// ECCVM proof structure (always ZK, committed sumcheck, translation sub-protocol)
757// ============================================================================
758template <typename Flavor> struct ECCVMStructuredProofBase : StructuredProofHelper<Flavor> {
760 using Base::NUM_ALL_ENTITIES;
761 using typename Base::Commitment;
762 using typename Base::FF;
763 using typename Base::ProofData;
764
765 // Witness commitments (masking_poly + NUM_WIRES wires + lookup_inverses + z_perm)
767 std::vector<Commitment> wire_comms;
770
771 // Libra pre-sumcheck
774
775 // Committed sumcheck rounds (each round: commitment + eval_0 + eval_1, interleaved in proof)
776 std::vector<Commitment> sumcheck_round_comms;
777 std::vector<FF> sumcheck_round_eval_0s;
778 std::vector<FF> sumcheck_round_eval_1s;
779
780 // Sumcheck evaluations
781 std::array<FF, NUM_ALL_ENTITIES> sumcheck_evaluations;
782
783 // Libra post-sumcheck
787
788 // Gemini/Shplemini
789 std::vector<Commitment> gemini_fold_comms;
790 std::vector<FF> gemini_fold_evals;
791
792 // Libra SmallSubgroupIPA evaluations
797
798 // First Shplonk Q (from Shplemini)
800
801 // Translation data
815
816 // TripleIPA pow-tensor masking claim
819
820 // Final Shplonk Q
822
823 void deserialize(ProofData& proof_data, size_t /*num_public_inputs*/, size_t log_n)
824 {
825 size_t offset = 0;
826 wire_comms.clear();
827 sumcheck_round_comms.clear();
828 sumcheck_round_eval_0s.clear();
829 sumcheck_round_eval_1s.clear();
830 gemini_fold_comms.clear();
831 gemini_fold_evals.clear();
832
833 // Witness commitments
834 gemini_masking_poly_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
835 for (size_t i = 0; i < Flavor::NUM_WIRES; ++i) {
836 wire_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
837 }
838 lookup_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
839 z_perm_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
840
841 // Libra pre-sumcheck
842 libra_concatenation_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
843 libra_sum = this->template deserialize_from_buffer<FF>(proof_data, offset);
844
845 // Committed sumcheck rounds (interleaved: comm, eval_0, eval_1 per round)
846 for (size_t i = 0; i < log_n; ++i) {
847 sumcheck_round_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
848 sumcheck_round_eval_0s.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
849 sumcheck_round_eval_1s.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
850 }
851
852 // Sumcheck evaluations
853 sumcheck_evaluations =
854 this->template deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(proof_data, offset);
855
856 // Libra post-sumcheck
857 libra_claimed_evaluation = this->template deserialize_from_buffer<FF>(proof_data, offset);
858 libra_grand_sum_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
859 libra_quotient_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
860
861 // Libra SmallSubgroupIPA evaluations
862 libra_concatenation_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
863 libra_shifted_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
864 libra_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
865 libra_quotient_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
866
867 // Translation data
868 translation_masking_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
869 translation_op_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
870 translation_Px_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
871 translation_Py_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
872 translation_z1_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
873 translation_z2_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
874 translation_masking_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
875 translation_grand_sum_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
876 translation_quotient_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
877 translation_concatenation_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
878 translation_shifted_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
879 translation_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
880 translation_quotient_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
881
882 // TripleIPA pow-tensor masking claim
883 pow_mask_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
884 pow_mask_evaluation = this->template deserialize_from_buffer<FF>(proof_data, offset);
885
886 // Final Shplonk Q
887 final_shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
888 }
889
890 void serialize(ProofData& proof_data, size_t log_n) const
891 {
892 size_t old_size = proof_data.size();
893 proof_data.clear();
894
895 // Witness commitments
896 Base::serialize_to_buffer(gemini_masking_poly_comm, proof_data);
897 for (const auto& comm : wire_comms) {
898 Base::serialize_to_buffer(comm, proof_data);
899 }
900 Base::serialize_to_buffer(lookup_inverses_comm, proof_data);
901 Base::serialize_to_buffer(z_perm_comm, proof_data);
902
903 // Libra pre-sumcheck
904 Base::serialize_to_buffer(libra_concatenation_commitment, proof_data);
905 Base::serialize_to_buffer(libra_sum, proof_data);
906
907 // Committed sumcheck rounds
908 for (size_t i = 0; i < log_n; ++i) {
909 Base::serialize_to_buffer(sumcheck_round_comms[i], proof_data);
910 Base::serialize_to_buffer(sumcheck_round_eval_0s[i], proof_data);
911 Base::serialize_to_buffer(sumcheck_round_eval_1s[i], proof_data);
912 }
913
914 // Sumcheck evaluations
915 Base::serialize_to_buffer(sumcheck_evaluations, proof_data);
916
917 // Libra post-sumcheck
918 Base::serialize_to_buffer(libra_claimed_evaluation, proof_data);
919 Base::serialize_to_buffer(libra_grand_sum_commitment, proof_data);
920 Base::serialize_to_buffer(libra_quotient_commitment, proof_data);
921
922 // Libra SmallSubgroupIPA evaluations
923 Base::serialize_to_buffer(libra_concatenation_eval, proof_data);
924 Base::serialize_to_buffer(libra_shifted_grand_sum_eval, proof_data);
925 Base::serialize_to_buffer(libra_grand_sum_eval, proof_data);
926 Base::serialize_to_buffer(libra_quotient_eval, proof_data);
927
928 // Translation data
929 Base::serialize_to_buffer(translation_masking_comm, proof_data);
930 Base::serialize_to_buffer(translation_op_eval, proof_data);
931 Base::serialize_to_buffer(translation_Px_eval, proof_data);
932 Base::serialize_to_buffer(translation_Py_eval, proof_data);
933 Base::serialize_to_buffer(translation_z1_eval, proof_data);
934 Base::serialize_to_buffer(translation_z2_eval, proof_data);
935 Base::serialize_to_buffer(translation_masking_eval, proof_data);
936 Base::serialize_to_buffer(translation_grand_sum_commitment, proof_data);
937 Base::serialize_to_buffer(translation_quotient_commitment, proof_data);
938 Base::serialize_to_buffer(translation_concatenation_eval, proof_data);
939 Base::serialize_to_buffer(translation_shifted_grand_sum_eval, proof_data);
940 Base::serialize_to_buffer(translation_grand_sum_eval, proof_data);
941 Base::serialize_to_buffer(translation_quotient_eval, proof_data);
942
943 // TripleIPA pow-tensor masking claim
944 Base::serialize_to_buffer(pow_mask_commitment, proof_data);
945 Base::serialize_to_buffer(pow_mask_evaluation, proof_data);
946
947 // Final Shplonk Q
948 Base::serialize_to_buffer(final_shplonk_q_comm, proof_data);
949
950 BB_ASSERT_EQ(proof_data.size(), old_size);
951 }
952};
953
954// ============================================================================
955// Flavor Specializations
956// ============================================================================
957
958// Ultra flavors (non-ZK)
961
962// Ultra ZK flavors
965
966// Mega flavors
969
970// Translator flavor
972
973// ECCVM flavor
975
976} // namespace bb
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
#define BB_ASSERT_LTE(left, right,...)
Definition assert.hpp:158
std::vector< DataType > Proof
typename Curve::ScalarField FF
static constexpr size_t NUM_ALL_ENTITIES
typename G1::affine_element Commitment
static constexpr size_t NUM_WIRES
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
BaseTranscript< Codec, HashFunction > Transcript
A univariate polynomial represented by its values on {0, 1,..., domain_end - 1}.
ssize_t offset
Definition engine.cpp:62
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::vector< Commitment > gemini_fold_comms
typename Flavor::Commitment Commitment
std::vector< Commitment > wire_comms
void deserialize(ProofData &proof_data, size_t, size_t log_n)
std::vector< FF > sumcheck_round_eval_1s
std::vector< Commitment > sumcheck_round_comms
std::array< FF, NUM_ALL_ENTITIES > sumcheck_evaluations
typename Transcript::Proof ProofData
void serialize(ProofData &proof_data, size_t log_n) const
std::vector< FF > sumcheck_round_eval_0s
std::array< Commitment, Flavor::NUM_BUS_COLUMNS > bus_inverses_comms
std::array< Commitment, Flavor::NUM_BUS_COLUMNS > bus_comms
void deserialize_mega_witness_comms(const ProofData &proof_data, size_t &offset)
typename Flavor::Commitment Commitment
void deserialize_pcs(const ProofData &proof_data, size_t &offset, size_t log_n)
std::vector< Commitment > gemini_fold_comms
std::array< Commitment, Flavor::NUM_BUS_COLUMNS > bus_read_counts_comms
void serialize(ProofData &proof_data, size_t log_n) const
void serialize_mega_witness_comms(ProofData &proof_data) const
void serialize_sumcheck(ProofData &proof_data, size_t log_n) const
void serialize_pcs(ProofData &proof_data, size_t log_n) const
std::array< FF, NUM_ALL_ENTITIES > sumcheck_evaluations
void deserialize(ProofData &proof_data, size_t num_public_inputs, size_t log_n)
void deserialize_sumcheck(const ProofData &proof_data, size_t &offset, size_t log_n)
std::vector< bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > > sumcheck_univariates
typename Transcript::Proof ProofData
void deserialize(ProofData &proof_data, size_t num_public_inputs, size_t log_n)
typename Flavor::Commitment Commitment
typename Transcript::Proof ProofData
void serialize(ProofData &proof_data, size_t log_n) const
static void serialize_to_buffer(const T &element, ProofData &proof_data)
static constexpr size_t NUM_ALL_ENTITIES
static T deserialize_from_buffer(const ProofData &proof_data, size_t &offset)
typename Flavor::Commitment Commitment
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
typename Transcript::Codec Codec
typename Transcript::Proof ProofData
typename Flavor::Transcript Transcript
Test utility for deserializing/serializing proof data into typed structures.
void deserialize(ProofData &proof_data, size_t, size_t log_n)
void serialize(ProofData &proof_data, size_t log_n) const
typename Flavor::Commitment Commitment
std::array< FF, NUM_FULL_CIRCUIT_EVALUATIONS > full_circuit_evaluations
std::array< FF, NUM_MINICIRCUIT_EVALUATIONS > minicircuit_evaluations
std::vector< Commitment > gemini_fold_comms
std::vector< Commitment > witness_comms
typename Transcript::Proof ProofData
std::vector< bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > > sumcheck_univariates
void serialize(ProofData &proof_data, size_t log_n) const
std::vector< Commitment > gemini_fold_comms
void deserialize_ultra_witness_comms(const ProofData &proof_data, size_t &offset)
std::array< FF, NUM_ALL_ENTITIES > sumcheck_evaluations
typename Flavor::Commitment Commitment
void deserialize_sumcheck(const ProofData &proof_data, size_t &offset, size_t log_n)
void serialize_ultra_witness_comms(ProofData &proof_data) const
void deserialize(ProofData &proof_data, size_t num_public_inputs, size_t log_n)
std::vector< bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > > sumcheck_univariates
void serialize_pcs(ProofData &proof_data, size_t log_n) const
void deserialize_pcs(const ProofData &proof_data, size_t &offset, size_t log_n)
void serialize_sumcheck(ProofData &proof_data, size_t log_n) const
typename Transcript::Proof ProofData
void serialize(ProofData &proof_data, size_t log_n) const
typename Flavor::Commitment Commitment
void deserialize(ProofData &proof_data, size_t num_public_inputs, size_t log_n)
typename Transcript::Proof ProofData