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