@@ -277,6 +277,8 @@ fn compute_packed_eval<E: ExtensionField>(
277277 }
278278}
279279
280+ // Batch the polynomials into pack_poly and final_poly
281+ // Returns the commitment to both (if exist)
280282pub fn pcs_batch_commit_diff_size < E : ExtensionField , Pcs : PolynomialCommitmentScheme < E > > (
281283 pack_pp : & Pcs :: ProverParam ,
282284 final_pp : & Option < Pcs :: ProverParam > ,
@@ -336,34 +338,31 @@ pub fn pcs_batch_open_diff_size<E: ExtensionField, Pcs: PolynomialCommitmentSche
336338 packed_comm : & Pcs :: CommitmentWithWitness ,
337339 final_comm : & Option < Pcs :: CommitmentWithWitness > ,
338340 points : & [ Vec < E > ] ,
339- _evals : & [ E ] ,
341+ _poly_evals : & [ E ] ,
340342 transcript : & mut impl Transcript < E > ,
341343) -> Result < ( IOPProof < E > , Vec < E > , Pcs :: Proof , Option < Pcs :: Proof > ) , Error > {
342344 assert_eq ! ( polys. len( ) , points. len( ) ) ;
343- // TODO: Sort the polys by decreasing size
344- let arc_polys: Vec < ArcMultilinearExtension < E > > = polys. into_iter ( ) . map ( |p| ArcMultilinearExtension :: from ( p. clone ( ) ) ) . collect ( ) ;
345+ // Assert that the poly are sorted in decreasing size
346+ for i in 0 ..polys. len ( ) - 1 {
347+ assert ! ( polys[ i] . num_vars >= polys[ i + 1 ] . num_vars) ;
348+ }
345349 // UNIFY SUMCHECK
346350 // Sample random coefficients for each poly
347351 let unify_coeffs = transcript. sample_vec ( polys. len ( ) ) ;
348- // First convert each point into EQ
352+ // Convert each point into EQ
349353 let eq_points = points. iter ( ) . map ( |p| build_eq_x_r ( p) ) . collect :: < Vec < _ > > ( ) ;
350-
354+ // Perform sumcheck
355+ let arc_polys: Vec < ArcMultilinearExtension < E > > = polys. into_iter ( ) . map ( |p| ArcMultilinearExtension :: from ( p. clone ( ) ) ) . collect ( ) ;
351356 let mut sumcheck_poly = VirtualPolynomial :: < E > :: new ( polys[ 0 ] . num_vars ( ) ) ;
352357 for ( ( eq, poly) , coeff) in eq_points. into_iter ( ) . zip ( arc_polys) . zip ( unify_coeffs) {
353- let claim = match ( & poly. evaluations ( ) , & eq. evaluations ) {
354- ( FieldType :: Base ( p) , FieldType :: Ext ( e) ) => {
355- p. iter ( ) . zip ( e) . map ( |( p, e) | E :: from_bases ( & [ * p, E :: BaseField :: ZERO ] ) * * e) . fold ( E :: ZERO , |s, i| s + i)
356- }
357- _ => unreachable ! ( )
358- } ;
359- println ! ( "C: {:?}" , claim) ;
360358 sumcheck_poly. add_mle_list ( vec ! [ eq, poly] , coeff) ;
361359 }
362360 let ( unify_proof, unify_prover_state) = IOPProverState :: prove_batch_polys ( 1 , vec ! [ sumcheck_poly] , transcript) ;
361+ // Obtain new point and evals
363362 let packed_point = unify_proof. point . clone ( ) ;
364- // sumcheck_poly is consisted of [eq, poly, eq, poly, ...], we only need the evaluations to `poly` here
363+ // sumcheck_poly is consisted of [eq, poly, eq, poly, ...], we only need the evaluations to the `poly`s here
365364 let sumcheck_evals = unify_prover_state. get_mle_final_evaluations ( ) ;
366- let ( _, evals ) : ( Vec < _ > , Vec < _ > ) = sumcheck_evals. into_iter ( ) . enumerate ( ) . partition_map ( |( i, e) | {
365+ let ( _, unify_evals ) : ( Vec < _ > , Vec < _ > ) = sumcheck_evals. into_iter ( ) . enumerate ( ) . partition_map ( |( i, e) | {
367366 if i % 2 == 0 {
368367 Either :: Left ( e)
369368 } else {
@@ -377,8 +376,8 @@ pub fn pcs_batch_open_diff_size<E: ExtensionField, Pcs: PolynomialCommitmentSche
377376 let packed_polys: Vec < ArcMultilinearExtension < E > > = packed_polys. into_iter ( ) . map ( |p| ArcMultilinearExtension :: from ( p) ) . collect ( ) ;
378377 // Note: the points are stored in reverse
379378 let final_point = if let Some ( final_poly) = & final_poly { packed_point[ ..final_poly. num_vars ] . to_vec ( ) } else { Vec :: new ( ) } ;
380- // Use comps to compute evals for packed polys from regular evals
381- let ( packed_evals, final_eval) = compute_packed_eval ( & packed_point, & final_point, & evals , & packed_comps, & final_comp) ;
379+ // Use comps to compute evals for packed polys from unify evals
380+ let ( packed_evals, final_eval) = compute_packed_eval ( & packed_point, & final_point, & unify_evals , & packed_comps, & final_comp) ;
382381
383382 let pack_proof = Pcs :: simple_batch_open ( pp, & packed_polys, packed_comm, & packed_point, & packed_evals, transcript) ?;
384383 let final_proof = match ( & final_poly, & final_comm, & final_eval) {
@@ -388,7 +387,7 @@ pub fn pcs_batch_open_diff_size<E: ExtensionField, Pcs: PolynomialCommitmentSche
388387 ( None , None , None ) => None ,
389388 _ => unreachable ! ( ) ,
390389 } ;
391- Ok ( ( unify_proof, evals , pack_proof, final_proof) )
390+ Ok ( ( unify_proof, unify_evals , pack_proof, final_proof) )
392391}
393392
394393pub fn pcs_verify < E : ExtensionField , Pcs : PolynomialCommitmentScheme < E > > (
@@ -434,11 +433,18 @@ where
434433{
435434 assert_eq ! ( poly_num_vars. len( ) , points. len( ) ) ;
436435 assert_eq ! ( poly_evals. len( ) , points. len( ) ) ;
436+ // Assert that the poly are sorted in decreasing size
437+ for i in 0 ..poly_num_vars. len ( ) - 1 {
438+ assert ! ( poly_num_vars[ i] >= poly_num_vars[ i + 1 ] ) ;
439+ }
437440 // UNIFY SUMCHECK
441+ let max_num_vars = poly_num_vars[ 0 ] ;
438442 // Sample random coefficients for each poly
439443 let unify_coeffs = transcript. sample_vec ( poly_num_vars. len ( ) ) ;
440- let claim = poly_evals. iter ( ) . zip ( & unify_coeffs) . map ( |( e, c) | * e * * c) . sum ( ) ;
441- let sumcheck_subclaim = IOPVerifierState :: verify ( claim, unify_proof, & VPAuxInfo { max_degree : 2 , max_num_variables : poly_num_vars[ 0 ] , phantom : Default :: default ( ) } , transcript) ;
444+ // Claim is obtained as eval * coeff * (1 << (max_num_vars - num_vars)) due to scaling factor: see prove_round_and_update_state in sumcheck/src/prover.rs
445+ let claim = poly_evals. iter ( ) . zip ( & unify_coeffs) . zip ( poly_num_vars) . map ( |( ( e, c) , n) | * e * * c * E :: from_u64 ( 1 << max_num_vars - n) ) . sum ( ) ;
446+ let sumcheck_subclaim = IOPVerifierState :: verify ( claim, unify_proof, & VPAuxInfo { max_degree : 2 , max_num_variables : max_num_vars, phantom : Default :: default ( ) } , transcript) ;
447+ // Obtain new point and evals
442448 let packed_point = sumcheck_subclaim. point . iter ( ) . map ( |c| c. elements ) . collect :: < Vec < _ > > ( ) ;
443449 let claimed_eval = sumcheck_subclaim. expected_evaluation ;
444450 // Compute the evaluation of every EQ
@@ -449,9 +455,6 @@ where
449455 // VERIFY PACK POLYS
450456 // Replicate packing
451457 let ( _, final_poly_num_vars, packed_comps, final_comp) = pack_poly_verifier ( poly_num_vars) ;
452- // TODO: Add unifying sumcheck if the points do not match
453- // For now, assume that all polys are evaluated on the same points
454- let packed_point = points[ 0 ] . clone ( ) ;
455458 let final_point = if let Some ( final_poly_num_vars) = & final_poly_num_vars { packed_point[ ..* final_poly_num_vars] . to_vec ( ) } else { Vec :: new ( ) } ;
456459 // Use comps to compute evals for packed polys from regular evals
457460 let ( packed_evals, final_eval) = compute_packed_eval ( & packed_point, & final_point, unify_evals, & packed_comps, & final_comp) ;
0 commit comments