Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
proof_compression.hpp
Go to the documentation of this file.
1#pragma once
2
13#include <cstddef>
14#include <cstdint>
15#include <vector>
16
17namespace bb {
18
19namespace proof_compression_detail {
20
21// =========================================================================
22// Walk functions — define proof layouts once for compress/decompress
23// =========================================================================
24
30template <typename ScalarFn, typename CommitmentFn>
31static constexpr void walk_mega_zk_oink_proof(ScalarFn&& process_scalar,
32 CommitmentFn&& process_commitment,
33 size_t num_public_inputs)
34{
35 // Public inputs
36 for (size_t i = 0; i < num_public_inputs; i++) {
37 process_scalar();
38 }
39 // Witness commitments (NUM_WITNESS_ENTITIES)
40 for (size_t i = 0; i < MegaZKFlavor::NUM_WITNESS_ENTITIES; i++) {
41 process_commitment();
42 }
43}
44
49template <typename ScalarFn, typename CommitmentFn>
50static constexpr void walk_merge_proof(ScalarFn&& process_scalar, CommitmentFn&& process_commitment)
51{
52 // 4 merged table commitments
53 for (size_t i = 0; i < 4; i++) {
54 process_commitment();
55 }
56 // Reversed batched left tables commitment
57 process_commitment();
58 // 4 left + 4 right + 4 merged table evaluations + 1 reversed eval = 13 scalars
59 for (size_t i = 0; i < 13; i++) {
60 process_scalar();
61 }
62 // Shplonk Q + KZG W
63 process_commitment();
64 process_commitment();
65}
66
73template <typename ScalarFn, typename CommitmentFn>
74static constexpr void walk_eccvm_proof(ScalarFn&& process_scalar, CommitmentFn&& process_commitment)
75{
76 constexpr size_t log_n = CONST_ECCVM_LOG_N;
78
79 // Witness commitments (wires + derived + masking poly)
80 for (size_t i = 0; i < num_witness; i++) {
81 process_commitment();
82 }
83 // Libra concatenation commitment
84 process_commitment();
85 // Libra sum
86 process_scalar();
87 // Sumcheck round univariates: per round, Grumpkin commits then sends 2 evaluations
88 for (size_t i = 0; i < log_n; i++) {
89 process_commitment(); // univariate commitment for round i
90 process_scalar(); // eval at 0 for round i
91 process_scalar(); // eval at 1 for round i
92 }
93 // Sumcheck evaluations
94 for (size_t i = 0; i < ECCVMFlavor::NUM_ALL_ENTITIES; i++) {
95 process_scalar();
96 }
97 // Libra claimed evaluation
98 process_scalar();
99 // Libra grand sum + quotient commitments
100 process_commitment();
101 process_commitment();
102 // Small IPA evaluations (for sumcheck libra)
103 for (size_t i = 0; i < NUM_SMALL_IPA_TRANSCRIPT_EVALS; i++) {
104 process_scalar();
105 }
106
107 // --- Translation section ---
108 // Translator concatenated masking commitment
109 process_commitment();
110 // 5 translation evaluations (op, Px, Py, z1, z2)
111 for (size_t i = 0; i < NUM_TRANSLATION_EVALUATIONS; i++) {
112 process_scalar();
113 }
114 // Translation masking term evaluation
115 process_scalar();
116 // Translation grand sum + quotient commitments
117 process_commitment();
118 process_commitment();
119 // Translation SmallSubgroupIPA evaluations
120 for (size_t i = 0; i < NUM_SMALL_IPA_TRANSCRIPT_EVALS; i++) {
121 process_scalar();
122 }
123 // TripleIPA pow-tensor masking commitment + evaluation (sent by prove_pow_masking_opening_claim, just before
124 // the single Shplonk that batches all univariate claims).
125 process_commitment();
126 process_scalar();
127 // Shplonk Q
128 process_commitment();
129}
130
134template <typename ScalarFn, typename CommitmentFn>
135static constexpr void walk_ipa_proof(ScalarFn&& process_scalar, CommitmentFn&& process_commitment)
136{
137 // TripleIPA cross sums
138 for (size_t i = 0; i < 3; i++) {
139 process_scalar();
140 }
141 // L and R commitments per round
142 for (size_t i = 0; i < CONST_ECCVM_LOG_N; i++) {
143 process_commitment(); // L_i
144 process_commitment(); // R_i
145 }
146 // G_0 commitment
147 process_commitment();
148 // a_0 scalar
149 process_scalar();
150}
151
158template <typename ScalarFn, typename CommitmentFn>
159static constexpr void walk_joint_proof(ScalarFn&& process_scalar, CommitmentFn&& process_commitment)
160{
161 constexpr size_t JOINT_LOG_N = TranslatorFlavor::CONST_TRANSLATOR_LOG_N; // 17
162 // --- Translator Oink ---
163 // Gemini masking poly commitment
164 process_commitment();
165 // Wire commitments: concatenated + ordered range constraints
166 for (size_t i = 0; i < TranslatorFlavor::NUM_COMMITMENTS_IN_PROOF; i++) {
167 process_commitment();
168 }
169 // Z_PERM commitment
170 process_commitment();
171
172 // --- Joint Sumcheck (Libra header) ---
173 // Libra concatenation commitment
174 process_commitment();
175 // Libra sum
176 process_scalar();
177
178 // Committed sumcheck rounds 0..JOINT_LOG_N-1 (commitment + 2 evals per round)
179 for (size_t round = 0; round < JOINT_LOG_N; round++) {
180 // Minicircuit evaluations sent at round LOG_MINI_CIRCUIT_SIZE - 1
182 for (size_t j = 0; j < TranslatorFlavor::NUM_MINICIRCUIT_EVALUATIONS; j++) {
183 process_scalar();
184 }
185 }
186 process_commitment(); // round univariate commitment
187 process_scalar(); // eval at 0
188 process_scalar(); // eval at 1
189 }
190
191 // MegaZK evaluations (sent after all sumcheck rounds)
192 for (size_t i = 0; i < MegaZKFlavor::NUM_ALL_ENTITIES; i++) {
193 process_scalar();
194 }
195
196 // Translator evaluations (sent after all rounds)
197 for (size_t i = 0; i < TranslatorFlavor::NUM_FULL_CIRCUIT_EVALUATIONS; i++) {
198 process_scalar();
199 }
200
201 // --- Joint Sumcheck (Libra footer) ---
202 // Libra claimed evaluation
203 process_scalar();
204 // Libra grand sum + quotient commitments
205 process_commitment();
206 process_commitment();
207
208 // --- Joint PCS ---
209 // Gemini fold commitments
210 for (size_t i = 0; i < JOINT_LOG_N - 1; i++) {
211 process_commitment();
212 }
213 // Gemini fold evaluations
214 for (size_t i = 0; i < JOINT_LOG_N; i++) {
215 process_scalar();
216 }
217 // Small IPA evaluations
218 for (size_t i = 0; i < NUM_SMALL_IPA_TRANSCRIPT_EVALS; i++) {
219 process_scalar();
220 }
221 // Shplonk Q + KZG W
222 process_commitment();
223 process_commitment();
224}
225
230template <typename BN254ScalarFn, typename BN254CommFn, typename GrumpkinScalarFn, typename GrumpkinCommFn>
231static constexpr void walk_chonk_proof(BN254ScalarFn&& bn254_scalar,
232 BN254CommFn&& bn254_comm,
233 GrumpkinScalarFn&& grumpkin_scalar,
234 GrumpkinCommFn&& grumpkin_comm,
235 size_t mega_num_public_inputs)
236{
237 walk_mega_zk_oink_proof(bn254_scalar, bn254_comm, mega_num_public_inputs);
238 walk_merge_proof(bn254_scalar, bn254_comm);
239 walk_eccvm_proof(grumpkin_scalar, grumpkin_comm);
240 walk_ipa_proof(grumpkin_scalar, grumpkin_comm);
241 walk_joint_proof(bn254_scalar, bn254_comm);
242}
243
244// =========================================================================
245// Walk count validation — the walkers define the compression layout. These checks keep that layout in sync with
246// the corresponding proof-length constants.
247// =========================================================================
248
249// Fr-elements per element type for each curve
250static constexpr size_t BN254_FRS_PER_SCALAR = 1;
251static constexpr size_t BN254_FRS_PER_COMM = 4; // Fq x,y each as (lo,hi) Fr pair
252static constexpr size_t GRUMPKIN_FRS_PER_SCALAR = 2; // Fq stored as (lo,hi) Fr pair
253static constexpr size_t GRUMPKIN_FRS_PER_COMM = 2; // Fr x,y coordinates
254
256 size_t scalars = 0;
257 size_t commitments = 0;
258
259 constexpr size_t field_elements(size_t scalar_frs, size_t commitment_frs) const
260 {
261 return scalars * scalar_frs + commitments * commitment_frs;
262 }
263};
264
265template <typename WalkFn> static constexpr WalkCounts count_walk(WalkFn walk)
266{
267 WalkCounts counts;
268 walk([&] { ++counts.scalars; }, [&] { ++counts.commitments; });
269 return counts;
270}
271
272template <typename WalkFn> static constexpr size_t count_bn254_frs(WalkFn walk)
273{
274 return count_walk(walk).field_elements(BN254_FRS_PER_SCALAR, BN254_FRS_PER_COMM);
275}
276
277template <typename WalkFn> static constexpr size_t count_grumpkin_frs(WalkFn walk)
278{
279 return count_walk(walk).field_elements(GRUMPKIN_FRS_PER_SCALAR, GRUMPKIN_FRS_PER_COMM);
280}
281
282static constexpr size_t EXPECTED_HIDING_OINK_FRS =
283 count_bn254_frs([](auto&& scalar, auto&& commitment) { walk_mega_zk_oink_proof(scalar, commitment, 0); });
284static_assert(EXPECTED_HIDING_OINK_FRS == ProofLength::Oink<MegaZKFlavor>::LENGTH_WITHOUT_PUB_INPUTS);
285
286static constexpr size_t EXPECTED_MERGE_FRS =
287 count_bn254_frs([](auto&& scalar, auto&& commitment) { walk_merge_proof(scalar, commitment); });
288static_assert(EXPECTED_MERGE_FRS == MERGE_PROOF_SIZE);
289
290static constexpr size_t EXPECTED_ECCVM_FRS =
291 count_grumpkin_frs([](auto&& scalar, auto&& commitment) { walk_eccvm_proof(scalar, commitment); });
292static_assert(EXPECTED_ECCVM_FRS == ECCVMFlavor::PROOF_LENGTH);
293
294static constexpr size_t EXPECTED_IPA_FRS =
295 count_grumpkin_frs([](auto&& scalar, auto&& commitment) { walk_ipa_proof(scalar, commitment); });
296static_assert(EXPECTED_IPA_FRS == ECCVMFlavor::TRIPLE_IPA_PROOF_LENGTH);
297
298static constexpr size_t EXPECTED_JOINT_FRS =
299 count_bn254_frs([](auto&& scalar, auto&& commitment) { walk_joint_proof(scalar, commitment); });
300
301// Cross-check: walk-based count must match ChonkProof's structural constants
302static_assert(EXPECTED_HIDING_OINK_FRS + EXPECTED_MERGE_FRS + EXPECTED_ECCVM_FRS + EXPECTED_IPA_FRS +
303 EXPECTED_JOINT_FRS ==
305
306} // namespace proof_compression_detail
307
325
326 static constexpr uint256_t SIGN_BIT_MASK = uint256_t(1) << 255;
327
328 // Fq values are stored as (lo, hi) Fr pairs split at 2*NUM_LIMB_BITS = 136 bits.
329 static constexpr uint64_t NUM_LIMB_BITS = 68;
330 static constexpr uint64_t FQ_SPLIT_BITS = NUM_LIMB_BITS * 2; // 136
331
333 template <typename Field> static bool y_is_negative(const Field& y)
334 {
335 return uint256_t(y) > (uint256_t(Field::modulus) - 1) / 2;
336 }
337
338 // =========================================================================
339 // Serialization helpers
340 // =========================================================================
341
342 static void write_u256(std::vector<uint8_t>& out, const uint256_t& val)
343 {
344 for (int i = 31; i >= 0; --i) {
345 out.push_back(static_cast<uint8_t>(val.data[i / 8] >> (8 * (i % 8))));
346 }
347 }
348
349 static uint256_t read_u256(const std::vector<uint8_t>& data, size_t& pos)
350 {
351 if (pos + 32 > data.size()) {
352 throw_or_abort("proof_compression: read_u256 out of bounds");
353 }
354 uint256_t val{ 0, 0, 0, 0 };
355 for (int i = 31; i >= 0; --i) {
356 val.data[i / 8] |= static_cast<uint64_t>(data[pos++]) << (8 * (i % 8));
357 }
358 return val;
359 }
360
361 static Fq reconstruct_fq(const Fr& lo, const Fr& hi)
362 {
363 return Fq(uint256_t(lo) + (uint256_t(hi) << FQ_SPLIT_BITS));
364 }
365
366 static std::pair<Fr, Fr> split_fq(const Fq& val)
367 {
368 constexpr uint256_t LOWER_MASK = (uint256_t(1) << FQ_SPLIT_BITS) - 1;
369 const uint256_t v = uint256_t(val);
370 return { Fr(v & LOWER_MASK), Fr(v >> FQ_SPLIT_BITS) };
371 }
372
373 public:
374 static constexpr size_t BYTES_PER_COMPRESSED_ELEMENT = 32;
375 static constexpr size_t BN254_SCALAR_FIELD_ELEMENTS = proof_compression_detail::BN254_FRS_PER_SCALAR;
376 static constexpr size_t BN254_COMMITMENT_FIELD_ELEMENTS = proof_compression_detail::BN254_FRS_PER_COMM;
377 static constexpr size_t GRUMPKIN_SCALAR_FIELD_ELEMENTS = proof_compression_detail::GRUMPKIN_FRS_PER_SCALAR;
378 static constexpr size_t GRUMPKIN_COMMITMENT_FIELD_ELEMENTS = proof_compression_detail::GRUMPKIN_FRS_PER_COMM;
379 static constexpr size_t ECCVM_PROOF_FIELD_ELEMENTS = proof_compression_detail::EXPECTED_ECCVM_FRS;
380
381 static constexpr size_t compressed_size_bytes_for_elements(size_t compressed_elements)
382 {
383 return compressed_elements * BYTES_PER_COMPRESSED_ELEMENT;
384 }
385
387 {
388 size_t count = 0;
389 auto counter = [&]() { count++; };
390 proof_compression_detail::walk_eccvm_proof(counter, counter);
391 return count;
392 }
393
398
403 static size_t compressed_element_count(size_t mega_num_public_inputs = 0)
404 {
405 size_t count = 0;
406 auto counter = [&]() { count++; };
407 proof_compression_detail::walk_chonk_proof(counter, counter, counter, counter, mega_num_public_inputs);
408 return count;
409 }
410
415 static size_t compressed_mega_num_public_inputs(size_t compressed_bytes)
416 {
417 if (compressed_bytes % 32 != 0) {
418 throw_or_abort("proof_compression: compressed size not aligned to 32 bytes");
419 }
420 size_t total_elements = compressed_bytes / 32;
421 size_t fixed_elements = compressed_element_count(0);
422 if (total_elements < fixed_elements) {
423 throw_or_abort("proof_compression: compressed proof too short");
424 }
425 return total_elements - fixed_elements;
426 }
427
428 // =========================================================================
429 // Chonk proof compression
430 // =========================================================================
431
432 static std::vector<uint8_t> compress_chonk_proof(const ChonkProof& proof)
433 {
434 auto flat = proof.to_field_elements();
435 std::vector<uint8_t> out;
436 out.reserve(flat.size() * 32); // upper bound: every element compresses to 32 bytes
437 size_t offset = 0;
438
439 // BN254 callbacks
440 auto bn254_scalar = [&]() { write_u256(out, uint256_t(flat[offset++])); };
441
442 auto bn254_comm = [&]() {
443 bool is_infinity = flat[offset].is_zero() && flat[offset + 1].is_zero() && flat[offset + 2].is_zero() &&
444 flat[offset + 3].is_zero();
445 if (is_infinity) {
447 offset += 4;
448 return;
449 }
450
451 Fq x = reconstruct_fq(flat[offset], flat[offset + 1]);
452 Fq y = reconstruct_fq(flat[offset + 2], flat[offset + 3]);
453 offset += 4;
454
455 uint256_t x_val = uint256_t(x);
456 if (y_is_negative(y)) {
457 x_val |= SIGN_BIT_MASK;
458 }
459 write_u256(out, x_val);
460 };
461
462 // Grumpkin callbacks
463 // Grumpkin commitments have coordinates in BN254::ScalarField (Fr), so x and y are each 1 Fr.
464 auto grumpkin_comm = [&]() {
465 Fr x = flat[offset];
466 Fr y = flat[offset + 1];
467 offset += 2;
468
469 if (x.is_zero() && y.is_zero()) {
471 return;
472 }
473
474 uint256_t x_val = uint256_t(x);
475 if (y_is_negative(y)) {
476 x_val |= SIGN_BIT_MASK;
477 }
478 write_u256(out, x_val);
479 };
480
481 // Grumpkin scalars are Fq values stored as (lo, hi) Fr pairs
482 auto grumpkin_scalar = [&]() {
483 Fq fq_val = reconstruct_fq(flat[offset], flat[offset + 1]);
484 offset += 2;
485 write_u256(out, uint256_t(fq_val));
486 };
487
488 size_t mega_num_pub_inputs =
490 proof_compression_detail::walk_chonk_proof(
491 bn254_scalar, bn254_comm, grumpkin_scalar, grumpkin_comm, mega_num_pub_inputs);
492 if (offset != flat.size()) {
493 throw_or_abort("proof_compression: compress did not consume all proof elements");
494 }
495 return out;
496 }
497
498 static ChonkProof decompress_chonk_proof(const std::vector<uint8_t>& compressed, size_t mega_num_public_inputs)
499 {
500 HonkProof flat;
501 size_t pos = 0;
502
503 // BN254 callbacks
504 auto bn254_scalar = [&]() {
505 uint256_t raw = read_u256(compressed, pos);
506 if (raw >= Fr::modulus) {
507 throw_or_abort("proof_compression: BN254 scalar out of range");
508 }
509 flat.emplace_back(raw);
510 };
511
512 auto bn254_comm = [&]() {
513 uint256_t raw = read_u256(compressed, pos);
514 bool sign = (raw & SIGN_BIT_MASK) != 0;
515 uint256_t x_val = raw & ~SIGN_BIT_MASK;
516
517 // Point-at-infinity is encoded as all zeros (x=0, sign=false).
518 // Unambiguous because x=0 is not on BN254
519 if (x_val == uint256_t(0) && !sign) {
520 for (int j = 0; j < 4; j++) {
521 flat.emplace_back(Fr::zero());
522 }
523 return;
524 }
525
526 if (x_val >= Fq::modulus) {
527 throw_or_abort("proof_compression: BN254 x-coordinate out of range");
528 }
529 Fq x(x_val);
530 Fq y_squared = x * x * x + Bn254G1Params::b;
531 auto [is_square, y] = y_squared.sqrt();
532 if (!is_square) {
533 throw_or_abort("proof_compression: BN254 point not on curve");
534 }
535
536 if (y_is_negative(y) != sign) {
537 y = -y;
538 }
539
540 auto [x_lo, x_hi] = split_fq(x);
541 auto [y_lo, y_hi] = split_fq(y);
542 flat.emplace_back(x_lo);
543 flat.emplace_back(x_hi);
544 flat.emplace_back(y_lo);
545 flat.emplace_back(y_hi);
546 };
547
548 // Grumpkin callbacks
549 auto grumpkin_comm = [&]() {
550 uint256_t raw = read_u256(compressed, pos);
551 bool sign = (raw & SIGN_BIT_MASK) != 0;
552 uint256_t x_val = raw & ~SIGN_BIT_MASK;
553
554 // Point-at-infinity is encoded as all zeros (x=0, sign=false).
555 // Unambiguous because x=0 is not on Grumpkin
556 if (x_val == uint256_t(0) && !sign) {
557 flat.emplace_back(Fr::zero());
558 flat.emplace_back(Fr::zero());
559 return;
560 }
561
562 if (x_val >= Fr::modulus) {
563 throw_or_abort("proof_compression: Grumpkin x-coordinate out of range");
564 }
565 Fr x(x_val);
566 Fr y_squared = x * x * x + grumpkin::G1Params::b;
567 auto [is_square, y] = y_squared.sqrt();
568 if (!is_square) {
569 throw_or_abort("proof_compression: Grumpkin point not on curve");
570 }
571
572 if (y_is_negative(y) != sign) {
573 y = -y;
574 }
575
576 flat.emplace_back(x);
577 flat.emplace_back(y);
578 };
579
580 auto grumpkin_scalar = [&]() {
581 uint256_t raw = read_u256(compressed, pos);
582 if (raw >= Fq::modulus) {
583 throw_or_abort("proof_compression: Grumpkin scalar out of range");
584 }
585 Fq fq_val(raw);
586 auto [lo, hi] = split_fq(fq_val);
587 flat.emplace_back(lo);
588 flat.emplace_back(hi);
589 };
590
591 proof_compression_detail::walk_chonk_proof(
592 bn254_scalar, bn254_comm, grumpkin_scalar, grumpkin_comm, mega_num_public_inputs);
593 if (pos != compressed.size()) {
594 throw_or_abort("proof_compression: decompression did not consume all bytes");
595 }
597 }
598};
599
600} // namespace bb
static constexpr size_t NUM_MASKING_POLYNOMIALS
static constexpr size_t NUM_ALL_ENTITIES
static constexpr size_t PROOF_LENGTH
static constexpr size_t TRIPLE_IPA_PROOF_LENGTH
static constexpr size_t NUM_WITNESS_ENTITIES
static constexpr size_t NUM_ALL_ENTITIES
static constexpr size_t NUM_WITNESS_ENTITIES
Compresses Chonk proofs from vector<fr> to compact byte representations.
static constexpr size_t BYTES_PER_COMPRESSED_ELEMENT
static constexpr uint64_t FQ_SPLIT_BITS
static std::vector< uint8_t > compress_chonk_proof(const ChonkProof &proof)
static ChonkProof decompress_chonk_proof(const std::vector< uint8_t > &compressed, size_t mega_num_public_inputs)
static size_t compressed_element_count(size_t mega_num_public_inputs=0)
Count the total compressed elements for a Chonk proof. Each element (scalar or commitment,...
static constexpr size_t BN254_SCALAR_FIELD_ELEMENTS
static size_t eccvm_compressed_element_count()
static constexpr size_t ECCVM_PROOF_FIELD_ELEMENTS
static constexpr size_t GRUMPKIN_SCALAR_FIELD_ELEMENTS
curve::BN254::ScalarField Fr
static constexpr uint256_t SIGN_BIT_MASK
static constexpr size_t GRUMPKIN_COMMITMENT_FIELD_ELEMENTS
curve::BN254::BaseField Fq
static size_t eccvm_compressed_size_bytes()
static void write_u256(std::vector< uint8_t > &out, const uint256_t &val)
static bool y_is_negative(const Field &y)
True if y is in the "upper half" of its field, used for point compression sign bit.
static size_t compressed_mega_num_public_inputs(size_t compressed_bytes)
Derive mega_num_public_inputs from compressed proof size.
static Fq reconstruct_fq(const Fr &lo, const Fr &hi)
static constexpr size_t compressed_size_bytes_for_elements(size_t compressed_elements)
static constexpr size_t BN254_COMMITMENT_FIELD_ELEMENTS
static uint256_t read_u256(const std::vector< uint8_t > &data, size_t &pos)
static constexpr uint64_t NUM_LIMB_BITS
static std::pair< Fr, Fr > split_fq(const Fq &val)
static constexpr size_t NUM_FULL_CIRCUIT_EVALUATIONS
static constexpr size_t CONST_TRANSLATOR_LOG_N
static constexpr size_t NUM_MINICIRCUIT_EVALUATIONS
static constexpr size_t LOG_MINI_CIRCUIT_SIZE
static constexpr size_t NUM_COMMITMENTS_IN_PROOF
bb::fq BaseField
Definition bn254.hpp:19
bb::fr ScalarField
Definition bn254.hpp:18
ssize_t offset
Definition engine.cpp:62
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr size_t NUM_SMALL_IPA_TRANSCRIPT_EVALS
std::vector< fr > HonkProof
Definition proof.hpp:15
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::byte * data
bb::VectorAffineElementPushSpan< BaseParams > out
static constexpr fq b
Definition g1.hpp:30
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS
static ChonkProof_ from_field_elements(const std::vector< FF > &fields)
Reconstruct proof from field elements.
HonkProof hiding_oink_proof
std::vector< FF > to_field_elements() const
Serialize proof to field elements (native mode)
Computes Oink proof length from flavor traits.
static constexpr size_t LENGTH_WITHOUT_PUB_INPUTS
static constexpr uint256_t modulus
constexpr std::pair< bool, field > sqrt() const noexcept
Compute square root of the field element.
BB_INLINE constexpr bool is_zero() const noexcept
static constexpr field zero()
static constexpr bb::fr b
Definition grumpkin.hpp:30
constexpr size_t field_elements(size_t scalar_frs, size_t commitment_frs) const
void throw_or_abort(std::string const &err)