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;
342 std::array<FF, NUM_ALL_ENTITIES> sumcheck_evaluations;
343 std::vector<Commitment> gemini_fold_comms;
344 std::vector<FF> gemini_fold_evals;
347
348 protected:
350 {
351 public_inputs.clear();
352 sumcheck_univariates.clear();
353 gemini_fold_comms.clear();
354 gemini_fold_evals.clear();
355 }
356
357 // Helper: deserialize Mega witness commitments
358 void deserialize_mega_witness_comms(const ProofData& proof_data, size_t& offset)
359 {
360 w_l_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
361 w_r_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
362 w_o_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
363 ecc_op_wire_1_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
364 ecc_op_wire_2_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
365 ecc_op_wire_3_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
366 ecc_op_wire_4_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
367 kernel_calldata_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
368 kernel_calldata_read_counts_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
369 first_app_calldata_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
370 first_app_calldata_read_counts_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
371 second_app_calldata_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
372 second_app_calldata_read_counts_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
373 third_app_calldata_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
374 third_app_calldata_read_counts_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
375 return_data_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
376 return_data_read_counts_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
377 lookup_read_counts_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
378 lookup_read_tags_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
379 w_4_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
380 lookup_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
381 kernel_calldata_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
382 first_app_calldata_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
383 second_app_calldata_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
384 third_app_calldata_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
385 return_data_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
386 z_perm_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
387 }
388
389 // Helper: serialize Mega witness commitments
391 {
392 Base::serialize_to_buffer(w_l_comm, proof_data);
393 Base::serialize_to_buffer(w_r_comm, proof_data);
394 Base::serialize_to_buffer(w_o_comm, proof_data);
395 Base::serialize_to_buffer(ecc_op_wire_1_comm, proof_data);
396 Base::serialize_to_buffer(ecc_op_wire_2_comm, proof_data);
397 Base::serialize_to_buffer(ecc_op_wire_3_comm, proof_data);
398 Base::serialize_to_buffer(ecc_op_wire_4_comm, proof_data);
399 Base::serialize_to_buffer(kernel_calldata_comm, proof_data);
400 Base::serialize_to_buffer(kernel_calldata_read_counts_comm, proof_data);
401 Base::serialize_to_buffer(first_app_calldata_comm, proof_data);
402 Base::serialize_to_buffer(first_app_calldata_read_counts_comm, proof_data);
403 Base::serialize_to_buffer(second_app_calldata_comm, proof_data);
404 Base::serialize_to_buffer(second_app_calldata_read_counts_comm, proof_data);
405 Base::serialize_to_buffer(third_app_calldata_comm, proof_data);
406 Base::serialize_to_buffer(third_app_calldata_read_counts_comm, proof_data);
407 Base::serialize_to_buffer(return_data_comm, proof_data);
408 Base::serialize_to_buffer(return_data_read_counts_comm, proof_data);
409 Base::serialize_to_buffer(lookup_read_counts_comm, proof_data);
410 Base::serialize_to_buffer(lookup_read_tags_comm, proof_data);
411 Base::serialize_to_buffer(w_4_comm, proof_data);
412 Base::serialize_to_buffer(lookup_inverses_comm, proof_data);
413 Base::serialize_to_buffer(kernel_calldata_inverses_comm, proof_data);
414 Base::serialize_to_buffer(first_app_calldata_inverses_comm, proof_data);
415 Base::serialize_to_buffer(second_app_calldata_inverses_comm, proof_data);
416 Base::serialize_to_buffer(third_app_calldata_inverses_comm, proof_data);
417 Base::serialize_to_buffer(return_data_inverses_comm, proof_data);
418 Base::serialize_to_buffer(z_perm_comm, proof_data);
419 }
420
421 // Helper: deserialize sumcheck data
422 void deserialize_sumcheck(const ProofData& proof_data, size_t& offset, size_t log_n)
423 {
424 for (size_t i = 0; i < log_n; ++i) {
425 sumcheck_univariates.push_back(
426 this->template deserialize_from_buffer<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(proof_data,
427 offset));
428 }
429 sumcheck_evaluations =
430 this->template deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(proof_data, offset);
431 }
432
433 // Helper: serialize sumcheck data
434 void serialize_sumcheck(ProofData& proof_data, size_t log_n) const
435 {
436 for (size_t i = 0; i < log_n; ++i) {
437 Base::serialize_to_buffer(sumcheck_univariates[i], proof_data);
438 }
439 Base::serialize_to_buffer(sumcheck_evaluations, proof_data);
440 }
441
442 // Helper: deserialize Gemini/Shplonk/KZG data
443 void deserialize_pcs(const ProofData& proof_data, size_t& offset, size_t log_n)
444 {
445 for (size_t i = 0; i < log_n - 1; ++i) {
446 gemini_fold_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
447 }
448 for (size_t i = 0; i < log_n; ++i) {
449 gemini_fold_evals.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
450 }
451 shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
452 kzg_w_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
453 }
454
455 // Helper: serialize Gemini/Shplonk/KZG data
456 void serialize_pcs(ProofData& proof_data, size_t log_n) const
457 {
458 for (size_t i = 0; i < log_n - 1; ++i) {
459 Base::serialize_to_buffer(gemini_fold_comms[i], proof_data);
460 }
461 for (size_t i = 0; i < log_n; ++i) {
462 Base::serialize_to_buffer(gemini_fold_evals[i], proof_data);
463 }
464 Base::serialize_to_buffer(shplonk_q_comm, proof_data);
465 Base::serialize_to_buffer(kzg_w_comm, proof_data);
466 }
467
468 public:
469 void deserialize(ProofData& proof_data, size_t num_public_inputs, size_t log_n)
470 {
471 size_t offset = 0;
472 clear_vectors();
473
474 for (size_t i = 0; i < num_public_inputs; ++i) {
475 public_inputs.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
476 }
477 deserialize_mega_witness_comms(proof_data, offset);
478 deserialize_sumcheck(proof_data, offset, log_n);
479 deserialize_pcs(proof_data, offset, log_n);
480 }
481
482 void serialize(ProofData& proof_data, size_t log_n) const
483 {
484 size_t old_size = proof_data.size();
485 proof_data.clear();
486
487 for (const auto& pi : public_inputs) {
488 Base::serialize_to_buffer(pi, proof_data);
489 }
490 serialize_mega_witness_comms(proof_data);
491 serialize_sumcheck(proof_data, log_n);
492 serialize_pcs(proof_data, log_n);
493
494 BB_ASSERT_EQ(proof_data.size(), old_size);
495 }
496};
497
498// ============================================================================
499// Mega ZK proof structure - extends Mega with ZK-specific fields
500// ============================================================================
503 using typename Base::Commitment;
504 using typename Base::FF;
505 using typename Base::ProofData;
506
507 // ZK-specific fields
518
519 void deserialize(ProofData& proof_data, size_t num_public_inputs, size_t log_n)
520 {
521 size_t offset = 0;
522 this->clear_vectors();
523
524 for (size_t i = 0; i < num_public_inputs; ++i) {
525 this->public_inputs.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
526 }
527 if constexpr (flavor_has_gemini_masking<Flavor>()) {
528 hiding_polynomial_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
529 }
530 this->deserialize_mega_witness_comms(proof_data, offset);
531 libra_concatenation_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
532 libra_sum = this->template deserialize_from_buffer<FF>(proof_data, offset);
533
534 // Sumcheck univariates
535 for (size_t i = 0; i < log_n; ++i) {
536 this->sumcheck_univariates.push_back(
537 this->template deserialize_from_buffer<bb::Univariate<FF, Base::BATCHED_RELATION_PARTIAL_LENGTH>>(
538 proof_data, offset));
539 }
540 libra_claimed_evaluation = this->template deserialize_from_buffer<FF>(proof_data, offset);
541 this->sumcheck_evaluations =
542 this->template deserialize_from_buffer<std::array<FF, Base::NUM_ALL_ENTITIES>>(proof_data, offset);
543 libra_grand_sum_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
544 libra_quotient_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
545
546 // Gemini
547 for (size_t i = 0; i < log_n - 1; ++i) {
548 this->gemini_fold_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
549 }
550 for (size_t i = 0; i < log_n; ++i) {
551 this->gemini_fold_evals.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
552 }
553 libra_concatenation_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
554 libra_shifted_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
555 libra_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
556 libra_quotient_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
557 this->shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
558 this->kzg_w_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
559 }
560
561 void serialize(ProofData& proof_data, size_t log_n) const
562 {
563 size_t old_size = proof_data.size();
564 proof_data.clear();
565
566 for (const auto& pi : this->public_inputs) {
567 Base::serialize_to_buffer(pi, proof_data);
568 }
569 if constexpr (flavor_has_gemini_masking<Flavor>()) {
570 Base::serialize_to_buffer(hiding_polynomial_commitment, proof_data);
571 }
572 this->serialize_mega_witness_comms(proof_data);
573 Base::serialize_to_buffer(libra_concatenation_commitment, proof_data);
574 Base::serialize_to_buffer(libra_sum, proof_data);
575
576 // Sumcheck univariates
577 for (size_t i = 0; i < log_n; ++i) {
578 Base::serialize_to_buffer(this->sumcheck_univariates[i], proof_data);
579 }
580 Base::serialize_to_buffer(libra_claimed_evaluation, proof_data);
581 Base::serialize_to_buffer(this->sumcheck_evaluations, proof_data);
582 Base::serialize_to_buffer(libra_grand_sum_commitment, proof_data);
583 Base::serialize_to_buffer(libra_quotient_commitment, proof_data);
584
585 // Gemini
586 for (size_t i = 0; i < log_n - 1; ++i) {
587 Base::serialize_to_buffer(this->gemini_fold_comms[i], proof_data);
588 }
589 for (size_t i = 0; i < log_n; ++i) {
590 Base::serialize_to_buffer(this->gemini_fold_evals[i], proof_data);
591 }
592 Base::serialize_to_buffer(libra_concatenation_eval, proof_data);
593 Base::serialize_to_buffer(libra_shifted_grand_sum_eval, proof_data);
594 Base::serialize_to_buffer(libra_grand_sum_eval, proof_data);
595 Base::serialize_to_buffer(libra_quotient_eval, proof_data);
596 Base::serialize_to_buffer(this->shplonk_q_comm, proof_data);
597 Base::serialize_to_buffer(this->kzg_w_comm, proof_data);
598
599 BB_ASSERT_EQ(proof_data.size(), old_size);
600 }
601};
602
603// ============================================================================
604// Translator proof structure (always ZK, with interleaved claims)
605// ============================================================================
608 using Base::BATCHED_RELATION_PARTIAL_LENGTH;
609 using Base::NUM_ALL_ENTITIES;
610 using typename Base::Commitment;
611 using typename Base::FF;
612 using typename Base::ProofData;
613
614 // Number of wire commitments sent in proof (concatenated + ordered range constraints)
615 static constexpr size_t NUM_BATCH_WITNESS_COMMS = Flavor::NUM_COMMITMENTS_IN_PROOF;
616 // Minicircuit evaluations are sent mid-sumcheck after LOG_MINI_CIRCUIT_SIZE rounds
617 static constexpr size_t LOG_MINI_CIRCUIT_SIZE = Flavor::LOG_MINI_CIRCUIT_SIZE;
618 static constexpr size_t NUM_MINICIRCUIT_EVALUATIONS = Flavor::NUM_MINICIRCUIT_EVALUATIONS;
619 static constexpr size_t NUM_FULL_CIRCUIT_EVALUATIONS = Flavor::NUM_FULL_CIRCUIT_EVALUATIONS;
620
621 // Witness commitments
623 std::vector<Commitment> witness_comms; // non-opqueue wires + ordered range constraints
625
626 // Libra (ZK - Translator is always ZK)
629
630 // Sumcheck: univariates are split around interleaved minicircuit evaluations
632 // Minicircuit wire evaluations (sent mid-sumcheck after LOG_MINI_CIRCUIT_SIZE rounds)
634 // Full-circuit evaluations (sent after all sumcheck rounds)
637
638 // Post-sumcheck Libra commitments
641
642 // Gemini/Shplemini
643 std::vector<Commitment> gemini_fold_comms;
644 std::vector<FF> gemini_fold_evals;
645
646 // Libra evaluations
651
652 // Final PCS
655
656 void deserialize(ProofData& proof_data, size_t /*num_public_inputs*/, size_t log_n)
657 {
658 size_t offset = 0;
659 witness_comms.clear();
660 sumcheck_univariates.clear();
661 gemini_fold_comms.clear();
662 gemini_fold_evals.clear();
663
664 // Witness commitments
665 gemini_masking_poly_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
666 for (size_t i = 0; i < NUM_BATCH_WITNESS_COMMS; ++i) {
667 witness_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
668 }
669 z_perm_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
670
671 // Libra pre-sumcheck
672 libra_concatenation_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
673 libra_sum = this->template deserialize_from_buffer<FF>(proof_data, offset);
674
675 // Sumcheck univariates (first LOG_MINI_CIRCUIT_SIZE rounds)
676 for (size_t i = 0; i < LOG_MINI_CIRCUIT_SIZE; ++i) {
677 sumcheck_univariates.push_back(
678 this->template deserialize_from_buffer<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(proof_data,
679 offset));
680 }
681 // Minicircuit evaluations (interleaved mid-sumcheck)
682 minicircuit_evaluations =
683 this->template deserialize_from_buffer<std::array<FF, NUM_MINICIRCUIT_EVALUATIONS>>(proof_data, offset);
684 // Sumcheck univariates (remaining rounds)
685 for (size_t i = LOG_MINI_CIRCUIT_SIZE; i < log_n; ++i) {
686 sumcheck_univariates.push_back(
687 this->template deserialize_from_buffer<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(proof_data,
688 offset));
689 }
690 // Full-circuit evaluations (excludes computable precomputed + concatenated + minicircuit)
691 full_circuit_evaluations =
692 this->template deserialize_from_buffer<std::array<FF, NUM_FULL_CIRCUIT_EVALUATIONS>>(proof_data, offset);
693 libra_claimed_evaluation = this->template deserialize_from_buffer<FF>(proof_data, offset);
694
695 // Libra post-sumcheck commitments
696 libra_grand_sum_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
697 libra_quotient_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
698
699 // Gemini fold commitments and evaluations
700 for (size_t i = 0; i < log_n - 1; ++i) {
701 gemini_fold_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
702 }
703 for (size_t i = 0; i < log_n; ++i) {
704 gemini_fold_evals.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
705 }
706
707 // Libra evaluations
708 libra_concatenation_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
709 libra_shifted_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
710 libra_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
711 libra_quotient_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
712
713 // Final PCS
714 shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
715 kzg_w_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
716 }
717
718 void serialize(ProofData& proof_data, size_t log_n) const
719 {
720 size_t old_size = proof_data.size();
721 proof_data.clear();
722
723 // Witness commitments
724 Base::serialize_to_buffer(gemini_masking_poly_comm, proof_data);
725 for (const auto& comm : witness_comms) {
726 Base::serialize_to_buffer(comm, proof_data);
727 }
728 Base::serialize_to_buffer(z_perm_comm, proof_data);
729
730 // Libra pre-sumcheck
731 Base::serialize_to_buffer(libra_concatenation_commitment, proof_data);
732 Base::serialize_to_buffer(libra_sum, proof_data);
733
734 // Sumcheck univariates (first LOG_MINI_CIRCUIT_SIZE rounds)
735 for (size_t i = 0; i < LOG_MINI_CIRCUIT_SIZE; ++i) {
736 Base::serialize_to_buffer(sumcheck_univariates[i], proof_data);
737 }
738 // Minicircuit evaluations (interleaved mid-sumcheck)
739 Base::serialize_to_buffer(minicircuit_evaluations, proof_data);
740 // Sumcheck univariates (remaining rounds)
741 for (size_t i = LOG_MINI_CIRCUIT_SIZE; i < log_n; ++i) {
742 Base::serialize_to_buffer(sumcheck_univariates[i], proof_data);
743 }
744 // Full-circuit evaluations
745 Base::serialize_to_buffer(full_circuit_evaluations, proof_data);
746 Base::serialize_to_buffer(libra_claimed_evaluation, proof_data);
747
748 // Libra post-sumcheck commitments
749 Base::serialize_to_buffer(libra_grand_sum_commitment, proof_data);
750 Base::serialize_to_buffer(libra_quotient_commitment, proof_data);
751
752 // Gemini fold commitments and evaluations
753 for (size_t i = 0; i < log_n - 1; ++i) {
754 Base::serialize_to_buffer(gemini_fold_comms[i], proof_data);
755 }
756 for (size_t i = 0; i < log_n; ++i) {
757 Base::serialize_to_buffer(gemini_fold_evals[i], proof_data);
758 }
759
760 // Libra evaluations
761 Base::serialize_to_buffer(libra_concatenation_eval, proof_data);
762 Base::serialize_to_buffer(libra_shifted_grand_sum_eval, proof_data);
763 Base::serialize_to_buffer(libra_grand_sum_eval, proof_data);
764 Base::serialize_to_buffer(libra_quotient_eval, proof_data);
765
766 // Final PCS
767 Base::serialize_to_buffer(shplonk_q_comm, proof_data);
768 Base::serialize_to_buffer(kzg_w_comm, proof_data);
769
770 BB_ASSERT_EQ(proof_data.size(), old_size);
771 }
772};
773
774// ============================================================================
775// ECCVM proof structure (always ZK, committed sumcheck, translation sub-protocol)
776// ============================================================================
777template <typename Flavor> struct ECCVMStructuredProofBase : StructuredProofHelper<Flavor> {
779 using Base::NUM_ALL_ENTITIES;
780 using typename Base::Commitment;
781 using typename Base::FF;
782 using typename Base::ProofData;
783
784 // Witness commitments (masking_poly + NUM_WIRES wires + lookup_inverses + z_perm)
786 std::vector<Commitment> wire_comms;
789
790 // Libra pre-sumcheck
793
794 // Committed sumcheck rounds (each round: commitment + eval_0 + eval_1, interleaved in proof)
795 std::vector<Commitment> sumcheck_round_comms;
796 std::vector<FF> sumcheck_round_eval_0s;
797 std::vector<FF> sumcheck_round_eval_1s;
798
799 // Sumcheck evaluations
800 std::array<FF, NUM_ALL_ENTITIES> sumcheck_evaluations;
801
802 // Libra post-sumcheck
806
807 // Gemini/Shplemini
808 std::vector<Commitment> gemini_fold_comms;
809 std::vector<FF> gemini_fold_evals;
810
811 // Libra SmallSubgroupIPA evaluations
816
817 // First Shplonk Q (from Shplemini)
819
820 // Translation data
834
835 // Final Shplonk Q
837
838 void deserialize(ProofData& proof_data, size_t /*num_public_inputs*/, size_t log_n)
839 {
840 size_t offset = 0;
841 wire_comms.clear();
842 sumcheck_round_comms.clear();
843 sumcheck_round_eval_0s.clear();
844 sumcheck_round_eval_1s.clear();
845 gemini_fold_comms.clear();
846 gemini_fold_evals.clear();
847
848 // Witness commitments
849 gemini_masking_poly_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
850 for (size_t i = 0; i < Flavor::NUM_WIRES; ++i) {
851 wire_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
852 }
853 lookup_inverses_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
854 z_perm_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
855
856 // Libra pre-sumcheck
857 libra_concatenation_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
858 libra_sum = this->template deserialize_from_buffer<FF>(proof_data, offset);
859
860 // Committed sumcheck rounds (interleaved: comm, eval_0, eval_1 per round)
861 for (size_t i = 0; i < log_n; ++i) {
862 sumcheck_round_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
863 sumcheck_round_eval_0s.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
864 sumcheck_round_eval_1s.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
865 }
866
867 // Sumcheck evaluations
868 sumcheck_evaluations =
869 this->template deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(proof_data, offset);
870
871 // Libra post-sumcheck
872 libra_claimed_evaluation = this->template deserialize_from_buffer<FF>(proof_data, offset);
873 libra_grand_sum_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
874 libra_quotient_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
875
876 // Gemini fold commitments and evaluations
877 for (size_t i = 0; i < log_n - 1; ++i) {
878 gemini_fold_comms.push_back(this->template deserialize_from_buffer<Commitment>(proof_data, offset));
879 }
880 for (size_t i = 0; i < log_n; ++i) {
881 gemini_fold_evals.push_back(this->template deserialize_from_buffer<FF>(proof_data, offset));
882 }
883
884 // Libra SmallSubgroupIPA evaluations
885 libra_concatenation_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
886 libra_shifted_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
887 libra_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
888 libra_quotient_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
889
890 // First Shplonk Q
891 shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
892
893 // Translation data
894 translation_masking_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
895 translation_op_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
896 translation_Px_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
897 translation_Py_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
898 translation_z1_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
899 translation_z2_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
900 translation_masking_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
901 translation_grand_sum_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
902 translation_quotient_commitment = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
903 translation_concatenation_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
904 translation_shifted_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
905 translation_grand_sum_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
906 translation_quotient_eval = this->template deserialize_from_buffer<FF>(proof_data, offset);
907
908 // Final Shplonk Q
909 final_shplonk_q_comm = this->template deserialize_from_buffer<Commitment>(proof_data, offset);
910 }
911
912 void serialize(ProofData& proof_data, size_t log_n) const
913 {
914 size_t old_size = proof_data.size();
915 proof_data.clear();
916
917 // Witness commitments
918 Base::serialize_to_buffer(gemini_masking_poly_comm, proof_data);
919 for (const auto& comm : wire_comms) {
920 Base::serialize_to_buffer(comm, proof_data);
921 }
922 Base::serialize_to_buffer(lookup_inverses_comm, proof_data);
923 Base::serialize_to_buffer(z_perm_comm, proof_data);
924
925 // Libra pre-sumcheck
926 Base::serialize_to_buffer(libra_concatenation_commitment, proof_data);
927 Base::serialize_to_buffer(libra_sum, proof_data);
928
929 // Committed sumcheck rounds
930 for (size_t i = 0; i < log_n; ++i) {
931 Base::serialize_to_buffer(sumcheck_round_comms[i], proof_data);
932 Base::serialize_to_buffer(sumcheck_round_eval_0s[i], proof_data);
933 Base::serialize_to_buffer(sumcheck_round_eval_1s[i], proof_data);
934 }
935
936 // Sumcheck evaluations
937 Base::serialize_to_buffer(sumcheck_evaluations, proof_data);
938
939 // Libra post-sumcheck
940 Base::serialize_to_buffer(libra_claimed_evaluation, proof_data);
941 Base::serialize_to_buffer(libra_grand_sum_commitment, proof_data);
942 Base::serialize_to_buffer(libra_quotient_commitment, proof_data);
943
944 // Gemini fold commitments and evaluations
945 for (size_t i = 0; i < log_n - 1; ++i) {
946 Base::serialize_to_buffer(gemini_fold_comms[i], proof_data);
947 }
948 for (size_t i = 0; i < log_n; ++i) {
949 Base::serialize_to_buffer(gemini_fold_evals[i], proof_data);
950 }
951
952 // Libra SmallSubgroupIPA evaluations
953 Base::serialize_to_buffer(libra_concatenation_eval, proof_data);
954 Base::serialize_to_buffer(libra_shifted_grand_sum_eval, proof_data);
955 Base::serialize_to_buffer(libra_grand_sum_eval, proof_data);
956 Base::serialize_to_buffer(libra_quotient_eval, proof_data);
957
958 // First Shplonk Q
959 Base::serialize_to_buffer(shplonk_q_comm, proof_data);
960
961 // Translation data
962 Base::serialize_to_buffer(translation_masking_comm, proof_data);
963 Base::serialize_to_buffer(translation_op_eval, proof_data);
964 Base::serialize_to_buffer(translation_Px_eval, proof_data);
965 Base::serialize_to_buffer(translation_Py_eval, proof_data);
966 Base::serialize_to_buffer(translation_z1_eval, proof_data);
967 Base::serialize_to_buffer(translation_z2_eval, proof_data);
968 Base::serialize_to_buffer(translation_masking_eval, proof_data);
969 Base::serialize_to_buffer(translation_grand_sum_commitment, proof_data);
970 Base::serialize_to_buffer(translation_quotient_commitment, proof_data);
971 Base::serialize_to_buffer(translation_concatenation_eval, proof_data);
972 Base::serialize_to_buffer(translation_shifted_grand_sum_eval, proof_data);
973 Base::serialize_to_buffer(translation_grand_sum_eval, proof_data);
974 Base::serialize_to_buffer(translation_quotient_eval, proof_data);
975
976 // Final Shplonk Q
977 Base::serialize_to_buffer(final_shplonk_q_comm, proof_data);
978
979 BB_ASSERT_EQ(proof_data.size(), old_size);
980 }
981};
982
983// ============================================================================
984// Flavor Specializations
985// ============================================================================
986
987// Ultra flavors (non-ZK)
990
991// Ultra ZK flavors
994
995// Mega flavors
998
999// Translator flavor
1001
1002// ECCVM flavor
1004
1005} // 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
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