@@ -478,13 +478,12 @@ fn compute_f_at_point<E: ExtensionField>(
478478/// 1. Batch the K column claims via a random column challenge `z_col`.
479479/// 2. Run the jagged sumcheck to reduce to a single evaluation of q'.
480480/// 3. Open q' at the sumcheck output point via the inner PCS.
481- pub fn jagged_batch_open < E : ExtensionField , InnerPcs : PolynomialCommitmentScheme < E > > (
482- pp : & InnerPcs :: ProverParam ,
481+ fn jagged_batch_open_round < E : ExtensionField , InnerPcs : PolynomialCommitmentScheme < E > > (
483482 comm : & JaggedCommitmentWithWitness < E , InnerPcs > ,
484483 point : & [ E ] ,
485484 evals : & [ E ] ,
486485 transcript : & mut impl Transcript < E > ,
487- ) -> Result < JaggedBatchOpenProof < E , InnerPcs > , Error > {
486+ ) -> Result < ( JaggedBatchOpenProof < E , InnerPcs > , InnerOpenings < E > ) , Error > {
488487 let num_polys = comm. num_polys ( ) ;
489488 if evals. len ( ) != num_polys {
490489 return Err ( Error :: InvalidPcsParam ( format ! (
@@ -593,38 +592,44 @@ pub fn jagged_batch_open<E: ExtensionField, InnerPcs: PolynomialCommitmentScheme
593592 transcript,
594593 ) ;
595594
596- // Open column MLEs at ρ_row via inner PCS.
597- let inner_proof = InnerPcs :: batch_open (
598- pp,
599- vec ! [ (
600- & comm. inner,
601- inner_openings_for_col_evals( rho_row, & col_evals) ,
602- ) ] ,
603- transcript,
604- ) ?;
595+ let inner_openings = inner_openings_for_col_evals ( rho_row, & col_evals) ;
605596
606- Ok ( JaggedBatchOpenProof {
607- sumcheck_proof,
608- col_evals,
609- f_at_rho,
610- assist_proof,
597+ Ok ( (
598+ JaggedBatchOpenProof {
599+ sumcheck_proof,
600+ col_evals,
601+ f_at_rho,
602+ assist_proof,
603+ marker : PhantomData ,
604+ } ,
605+ inner_openings,
606+ ) )
607+ }
608+
609+ pub fn jagged_batch_open < E : ExtensionField , InnerPcs : PolynomialCommitmentScheme < E > > (
610+ pp : & InnerPcs :: ProverParam ,
611+ comm : & JaggedCommitmentWithWitness < E , InnerPcs > ,
612+ point : & [ E ] ,
613+ evals : & [ E ] ,
614+ transcript : & mut impl Transcript < E > ,
615+ ) -> Result < JaggedProof < E , InnerPcs > , Error > {
616+ let ( round, inner_openings) =
617+ jagged_batch_open_round :: < E , InnerPcs > ( comm, point, evals, transcript) ?;
618+ let inner_proof = InnerPcs :: batch_open ( pp, vec ! [ ( & comm. inner, inner_openings) ] , transcript) ?;
619+ Ok ( JaggedProof {
620+ rounds : vec ! [ round] ,
611621 inner_proof,
612622 } )
613623}
614624
615- /// Verify that evaluation claims `evals[i] = p_i(point_i)` are consistent with a
616- /// jagged commitment.
617- ///
618- /// Polynomials may have different heights. `point` has length `max_s`. Polynomial
619- /// `i` with `s_i` variables is evaluated at the prefix `point[..s_i]`.
620- pub fn jagged_batch_verify < E : ExtensionField , InnerPcs : PolynomialCommitmentScheme < E > > (
621- vp : & InnerPcs :: VerifierParam ,
625+ fn jagged_batch_verify_without_inner < E : ExtensionField , InnerPcs : PolynomialCommitmentScheme < E > > (
626+ _vp : & InnerPcs :: VerifierParam ,
622627 comm : & JaggedCommitment < E , InnerPcs > ,
623628 point : & [ E ] ,
624629 evals : & [ E ] ,
625630 proof : & JaggedBatchOpenProof < E , InnerPcs > ,
626631 transcript : & mut impl Transcript < E > ,
627- ) -> Result < ( ) , Error > {
632+ ) -> Result < ( InnerPcs :: Commitment , InnerVerifyOpenings < E > ) , Error > {
628633 let num_polys = comm. cumulative_heights . len ( ) - 1 ;
629634 if evals. len ( ) != num_polys {
630635 return Err ( Error :: InvalidPcsOpen ( format ! (
@@ -734,16 +739,40 @@ pub fn jagged_batch_verify<E: ExtensionField, InnerPcs: PolynomialCommitmentSche
734739 ) ) ;
735740 }
736741
737- // Verify the inner PCS opening at ρ_row with col_evals.
738- InnerPcs :: batch_verify (
742+ Ok ( (
743+ comm. inner . clone ( ) ,
744+ inner_verify_openings_for_col_evals ( log_h, rho_row, & proof. col_evals ) ,
745+ ) )
746+ }
747+
748+ /// Verify that evaluation claims `evals[i] = p_i(point_i)` are consistent with a
749+ /// jagged commitment.
750+ ///
751+ /// Polynomials may have different heights. `point` has length `max_s`. Polynomial
752+ /// `i` with `s_i` variables is evaluated at the prefix `point[..s_i]`.
753+ pub fn jagged_batch_verify < E : ExtensionField , InnerPcs : PolynomialCommitmentScheme < E > > (
754+ vp : & InnerPcs :: VerifierParam ,
755+ comm : & JaggedCommitment < E , InnerPcs > ,
756+ point : & [ E ] ,
757+ evals : & [ E ] ,
758+ proof : & JaggedProof < E , InnerPcs > ,
759+ transcript : & mut impl Transcript < E > ,
760+ ) -> Result < ( ) , Error > {
761+ if proof. rounds . len ( ) != 1 {
762+ return Err ( Error :: InvalidPcsOpeningProof ( format ! (
763+ "jagged: expected one proof round, got {}" ,
764+ proof. rounds. len( )
765+ ) ) ) ;
766+ }
767+ let inner_round = jagged_batch_verify_without_inner :: < E , InnerPcs > (
739768 vp,
740- vec ! [ (
741- comm. inner. clone( ) ,
742- inner_verify_openings_for_col_evals( log_h, rho_row, & proof. col_evals) ,
743- ) ] ,
744- & proof. inner_proof ,
769+ comm,
770+ point,
771+ evals,
772+ & proof. rounds [ 0 ] ,
745773 transcript,
746774 ) ?;
775+ InnerPcs :: batch_verify ( vp, vec ! [ inner_round] , & proof. inner_proof , transcript) ?;
747776
748777 Ok ( ( ) )
749778}
@@ -825,13 +854,19 @@ where
825854 transcript : & mut impl Transcript < E > ,
826855 ) -> Result < Self :: Proof , Error > {
827856 let mut proofs = Vec :: with_capacity ( rounds. len ( ) ) ;
857+ let mut inner_rounds = Vec :: with_capacity ( rounds. len ( ) ) ;
828858 for ( comm, openings) in rounds {
829859 let ( point, evals) = flatten_padded_openings_as_native ( & comm. poly_heights , openings) ?;
830- proofs. push ( jagged_batch_open :: < E , InnerPcs > (
831- pp, comm, & point, & evals, transcript,
832- ) ?) ;
860+ let ( proof, inner_openings) =
861+ jagged_batch_open_round :: < E , InnerPcs > ( comm, & point, & evals, transcript) ?;
862+ proofs. push ( proof) ;
863+ inner_rounds. push ( ( & comm. inner , inner_openings) ) ;
833864 }
834- Ok ( JaggedProof { rounds : proofs } )
865+ let inner_proof = InnerPcs :: batch_open ( pp, inner_rounds, transcript) ?;
866+ Ok ( JaggedProof {
867+ rounds : proofs,
868+ inner_proof,
869+ } )
835870 }
836871
837872 fn simple_batch_open (
@@ -869,6 +904,7 @@ where
869904 proof. rounds. len( )
870905 ) ) ) ;
871906 }
907+ let mut inner_rounds = Vec :: with_capacity ( rounds. len ( ) ) ;
872908 for ( ( comm, openings) , round_proof) in rounds. into_iter ( ) . zip_eq ( proof. rounds . iter ( ) ) {
873909 let poly_heights = comm
874910 . cumulative_heights
@@ -880,8 +916,17 @@ where
880916 . map ( |( _, ( point, evals) ) | ( point, evals) )
881917 . collect_vec ( ) ;
882918 let ( point, evals) = flatten_padded_openings_as_native ( & poly_heights, openings) ?;
883- jagged_batch_verify :: < E , InnerPcs > ( vp, & comm, & point, & evals, round_proof, transcript) ?;
919+ let inner_round = jagged_batch_verify_without_inner :: < E , InnerPcs > (
920+ vp,
921+ & comm,
922+ & point,
923+ & evals,
924+ round_proof,
925+ transcript,
926+ ) ?;
927+ inner_rounds. push ( inner_round) ;
884928 }
929+ InnerPcs :: batch_verify ( vp, inner_rounds, & proof. inner_proof , transcript) ?;
885930 Ok ( ( ) )
886931 }
887932
@@ -901,6 +946,55 @@ where
901946 ) -> Vec < ArcMultilinearExtension < ' static , E > > {
902947 commitment. polys . clone ( )
903948 }
949+
950+ fn proof_size_breakdown ( proof : & Self :: Proof ) -> Vec < ( String , u64 ) > {
951+ let mut breakdown = vec ! [
952+ (
953+ "total" . to_string( ) ,
954+ bincode:: serialized_size( proof) . unwrap_or( 0 ) ,
955+ ) ,
956+ (
957+ "rounds" . to_string( ) ,
958+ bincode:: serialized_size( & proof. rounds) . unwrap_or( 0 ) ,
959+ ) ,
960+ (
961+ "inner_proof" . to_string( ) ,
962+ bincode:: serialized_size( & proof. inner_proof) . unwrap_or( 0 ) ,
963+ ) ,
964+ ] ;
965+
966+ for ( round_idx, round) in proof. rounds . iter ( ) . enumerate ( ) {
967+ breakdown. extend ( [
968+ (
969+ format ! ( "round[{round_idx}].total" ) ,
970+ bincode:: serialized_size ( round) . unwrap_or ( 0 ) ,
971+ ) ,
972+ (
973+ format ! ( "round[{round_idx}].sumcheck_proof" ) ,
974+ bincode:: serialized_size ( & round. sumcheck_proof ) . unwrap_or ( 0 ) ,
975+ ) ,
976+ (
977+ format ! ( "round[{round_idx}].col_evals" ) ,
978+ bincode:: serialized_size ( & round. col_evals ) . unwrap_or ( 0 ) ,
979+ ) ,
980+ (
981+ format ! ( "round[{round_idx}].f_at_rho" ) ,
982+ bincode:: serialized_size ( & round. f_at_rho ) . unwrap_or ( 0 ) ,
983+ ) ,
984+ (
985+ format ! ( "round[{round_idx}].assist_proof" ) ,
986+ bincode:: serialized_size ( & round. assist_proof ) . unwrap_or ( 0 ) ,
987+ ) ,
988+ ] ) ;
989+ }
990+
991+ breakdown. extend (
992+ InnerPcs :: proof_size_breakdown ( & proof. inner_proof )
993+ . into_iter ( )
994+ . map ( |( name, size) | ( format ! ( "inner_proof.{name}" ) , size) ) ,
995+ ) ;
996+ breakdown
997+ }
904998}
905999
9061000#[ cfg( test) ]
@@ -1274,7 +1368,7 @@ mod tests {
12741368
12751369 let proof = jagged_batch_open :: < E , Pcs > ( & pp, & comm, & point, & evals, & mut transcript_p)
12761370 . expect ( "batch open" ) ;
1277- assert_eq ! ( proof. col_evals. len( ) , w) ;
1371+ assert_eq ! ( proof. rounds [ 0 ] . col_evals. len( ) , w) ;
12781372
12791373 let mut transcript_v = BasicTranscript :: < E > :: new ( b"jagged_reshape_single" ) ;
12801374 Pcs :: write_commitment ( & comm. to_commitment ( ) . inner , & mut transcript_v) . unwrap ( ) ;
@@ -1325,7 +1419,7 @@ mod tests {
13251419
13261420 let proof = jagged_batch_open :: < E , Pcs > ( & pp, & comm, & point, & evals, & mut transcript_p)
13271421 . expect ( "batch open should succeed" ) ;
1328- assert_eq ! ( proof. col_evals. len( ) , w) ;
1422+ assert_eq ! ( proof. rounds [ 0 ] . col_evals. len( ) , w) ;
13291423
13301424 let mut transcript_v = BasicTranscript :: < E > :: new ( b"jagged_reshape_multi" ) ;
13311425 Pcs :: write_commitment ( & comm. to_commitment ( ) . inner , & mut transcript_v) . unwrap ( ) ;
@@ -1374,7 +1468,7 @@ mod tests {
13741468
13751469 let proof = jagged_batch_open :: < E , Pcs > ( & pp, & comm, & point, & evals, & mut transcript_p)
13761470 . expect ( "batch open" ) ;
1377- assert_eq ! ( proof. col_evals. len( ) , w) ;
1471+ assert_eq ! ( proof. rounds [ 0 ] . col_evals. len( ) , w) ;
13781472
13791473 let mut transcript_v = BasicTranscript :: < E > :: new ( b"jagged_reshape_non_power" ) ;
13801474 Pcs :: write_commitment ( & comm. to_commitment ( ) . inner , & mut transcript_v) . unwrap ( ) ;
0 commit comments