@@ -59,7 +59,9 @@ class ProofCompressor {
5959
6060 static uint256_t read_u256 (const std::vector<uint8_t >& data, size_t & pos)
6161 {
62- BB_ASSERT (pos + 32 <= data.size ());
62+ if (pos + 32 > data.size ()) {
63+ throw_or_abort (" proof_compression: read_u256 out of bounds" );
64+ }
6365 uint256_t val{ 0 , 0 , 0 , 0 };
6466 for (int i = 31 ; i >= 0 ; --i) {
6567 val.data [i / 8 ] |= static_cast <uint64_t >(data[pos++]) << (8 * (i % 8 ));
@@ -423,10 +425,14 @@ class ProofCompressor {
423425 */
424426 static size_t compressed_mega_num_public_inputs (size_t compressed_bytes)
425427 {
426- BB_ASSERT (compressed_bytes % 32 == 0 );
428+ if (compressed_bytes % 32 != 0 ) {
429+ throw_or_abort (" proof_compression: compressed size not aligned to 32 bytes" );
430+ }
427431 size_t total_elements = compressed_bytes / 32 ;
428432 size_t fixed_elements = compressed_element_count (0 );
429- BB_ASSERT (total_elements >= fixed_elements);
433+ if (total_elements < fixed_elements) {
434+ throw_or_abort (" proof_compression: compressed proof too short" );
435+ }
430436 return total_elements - fixed_elements;
431437 }
432438
@@ -493,7 +499,9 @@ class ProofCompressor {
493499 size_t mega_num_pub_inputs =
494500 proof.hiding_oink_proof .size () - ProofLength::Oink<MegaZKFlavor>::LENGTH_WITHOUT_PUB_INPUTS;
495501 walk_chonk_proof (bn254_scalar, bn254_comm, grumpkin_scalar, grumpkin_comm, mega_num_pub_inputs);
496- BB_ASSERT (offset == flat.size ());
502+ if (offset != flat.size ()) {
503+ throw_or_abort (" proof_compression: compress did not consume all proof elements" );
504+ }
497505 return out;
498506 }
499507
@@ -505,7 +513,9 @@ class ProofCompressor {
505513 // BN254 callbacks
506514 auto bn254_scalar = [&]() {
507515 uint256_t raw = read_u256 (compressed, pos);
508- BB_ASSERT (raw < Fr::modulus);
516+ if (raw >= Fr::modulus) {
517+ throw_or_abort (" proof_compression: BN254 scalar out of range" );
518+ }
509519 flat.emplace_back (raw);
510520 };
511521
@@ -523,11 +533,15 @@ class ProofCompressor {
523533 return ;
524534 }
525535
526- BB_ASSERT (x_val < Fq::modulus);
536+ if (x_val >= Fq::modulus) {
537+ throw_or_abort (" proof_compression: BN254 x-coordinate out of range" );
538+ }
527539 Fq x (x_val);
528540 Fq y_squared = x * x * x + Bn254G1Params::b;
529541 auto [is_square, y] = y_squared.sqrt ();
530- BB_ASSERT (is_square);
542+ if (!is_square) {
543+ throw_or_abort (" proof_compression: BN254 point not on curve" );
544+ }
531545
532546 if (y_is_negative (y) != sign) {
533547 y = -y;
@@ -555,11 +569,15 @@ class ProofCompressor {
555569 return ;
556570 }
557571
558- BB_ASSERT (x_val < Fr::modulus);
572+ if (x_val >= Fr::modulus) {
573+ throw_or_abort (" proof_compression: Grumpkin x-coordinate out of range" );
574+ }
559575 Fr x (x_val);
560576 Fr y_squared = x * x * x + grumpkin::G1Params::b;
561577 auto [is_square, y] = y_squared.sqrt ();
562- BB_ASSERT (is_square);
578+ if (!is_square) {
579+ throw_or_abort (" proof_compression: Grumpkin point not on curve" );
580+ }
563581
564582 if (y_is_negative (y) != sign) {
565583 y = -y;
@@ -571,15 +589,19 @@ class ProofCompressor {
571589
572590 auto grumpkin_scalar = [&]() {
573591 uint256_t raw = read_u256 (compressed, pos);
574- BB_ASSERT (raw < Fq::modulus);
592+ if (raw >= Fq::modulus) {
593+ throw_or_abort (" proof_compression: Grumpkin scalar out of range" );
594+ }
575595 Fq fq_val (raw);
576596 auto [lo, hi] = split_fq (fq_val);
577597 flat.emplace_back (lo);
578598 flat.emplace_back (hi);
579599 };
580600
581601 walk_chonk_proof (bn254_scalar, bn254_comm, grumpkin_scalar, grumpkin_comm, mega_num_public_inputs);
582- BB_ASSERT (pos == compressed.size ());
602+ if (pos != compressed.size ()) {
603+ throw_or_abort (" proof_compression: decompression did not consume all bytes" );
604+ }
583605 return ChonkProof::from_field_elements (flat);
584606 }
585607};
0 commit comments