@@ -55,13 +55,21 @@ pub fn pcs_batch_commit<E: ExtensionField, Pcs: PolynomialCommitmentScheme<E>>(
5555 Pcs :: batch_commit ( pp, polys)
5656}
5757
58+ pub fn pcs_batch_commit_and_write < E : ExtensionField , Pcs : PolynomialCommitmentScheme < E > > (
59+ pp : & Pcs :: ProverParam ,
60+ polys : & [ DenseMultilinearExtension < E > ] ,
61+ transcript : & mut impl Transcript < E > ,
62+ ) -> Result < Pcs :: CommitmentWithWitness , Error > {
63+ Pcs :: batch_commit_and_write ( pp, polys, transcript)
64+ }
65+
5866// Express Value as binary in big-endian
5967fn compute_binary_with_length ( length : usize , mut value : usize ) -> Vec < bool > {
60- assert ! ( value < 1 << length) ;
68+ assert ! ( value < ( 1 << length) ) ;
6169 let mut bin = Vec :: new ( ) ;
6270 for _ in 0 ..length {
6371 bin. insert ( 0 , value % 2 == 1 ) ;
64- value << = 1 ;
72+ value >> = 1 ;
6573 }
6674 bin
6775}
@@ -233,26 +241,32 @@ fn compute_packed_eval<E: ExtensionField>(
233241 // Use comps to compute evals for packed polys from regular evals
234242 let mut packed_evals = Vec :: new ( ) ;
235243 let mut next_orig_poly = 0 ;
244+ let pack_num_vars = packed_point. len ( ) ;
236245 for next_packed_comp in packed_comps {
237246 let mut packed_eval = E :: ZERO ;
238247 for next_index in next_packed_comp {
239248 let mut next_eval = evals[ next_orig_poly] ;
249+ // Note: the points are stored in reverse
240250 for ( j, b) in next_index. iter ( ) . enumerate ( ) {
241- if * b { next_eval *= packed_point[ j] }
251+ let next_point = packed_point[ pack_num_vars - 1 - j] ;
252+ if * b { next_eval *= next_point } else { next_eval *= E :: ONE - next_point }
242253 }
243- packed_eval * = next_eval;
254+ packed_eval + = next_eval;
244255 next_orig_poly += 1 ;
245256 }
246257 packed_evals. push ( packed_eval) ;
247258 }
248259 if let Some ( final_comp) = final_comp {
249260 let mut final_eval = E :: ZERO ;
261+ let final_num_vars = final_point. len ( ) ;
250262 for next_index in final_comp {
251263 let mut next_eval = evals[ next_orig_poly] ;
264+ // Note: the points are stored in reverse
252265 for ( j, b) in next_index. iter ( ) . enumerate ( ) {
253- if * b { next_eval *= final_point[ j] }
266+ let next_point = final_point[ final_num_vars - 1 - j] ;
267+ if * b { next_eval *= next_point } else { next_eval *= E :: ONE - next_point }
254268 }
255- final_eval * = next_eval;
269+ final_eval + = next_eval;
256270 next_orig_poly += 1 ;
257271 }
258272 ( packed_evals, Some ( final_eval) )
@@ -262,25 +276,35 @@ fn compute_packed_eval<E: ExtensionField>(
262276}
263277
264278pub fn pcs_batch_commit_diff_size < E : ExtensionField , Pcs : PolynomialCommitmentScheme < E > > (
265- pp : & Pcs :: ProverParam ,
279+ pack_pp : & Pcs :: ProverParam ,
280+ final_pp : & Option < Pcs :: ProverParam > ,
266281 polys : & [ DenseMultilinearExtension < E > ] ,
267282) -> Result < ( Pcs :: CommitmentWithWitness , Option < Pcs :: CommitmentWithWitness > ) , Error > {
268283 let ( packed_polys, final_poly, _, _) = pack_poly_prover ( polys) ;
269284 // Final packed poly
270- if let Some ( final_poly ) = final_poly {
271- Ok ( ( Pcs :: batch_commit ( pp , & packed_polys) ?, Some ( Pcs :: batch_commit ( pp , & [ final_poly] ) ?) ) )
272- } else {
273- Ok ( ( Pcs :: batch_commit ( pp , & packed_polys ) ? , None ) )
285+ match ( final_pp , final_poly) {
286+ ( Some ( final_pp ) , Some ( final_poly ) ) => Ok ( ( Pcs :: batch_commit ( pack_pp , & packed_polys) ?, Some ( Pcs :: batch_commit ( final_pp , & [ final_poly] ) ?) ) ) ,
287+ ( None , None ) => Ok ( ( Pcs :: batch_commit ( pack_pp , & packed_polys ) ? , None ) ) ,
288+ _ => unreachable ! ( )
274289 }
275290}
276291
277- pub fn pcs_batch_commit_and_write < E : ExtensionField , Pcs : PolynomialCommitmentScheme < E > > (
292+ pub fn pcs_batch_commit_diff_size_and_write < E : ExtensionField , Pcs : PolynomialCommitmentScheme < E > > (
278293 pp : & Pcs :: ProverParam ,
279294 polys : & [ DenseMultilinearExtension < E > ] ,
280295 transcript : & mut impl Transcript < E > ,
281- ) -> Result < Pcs :: CommitmentWithWitness , Error > {
282- Pcs :: batch_commit_and_write ( pp, polys, transcript)
283- }
296+ ) -> Result < ( Pcs :: CommitmentWithWitness , Option < Pcs :: CommitmentWithWitness > ) , Error > {
297+ let ( packed_polys, final_poly, _, _) = pack_poly_prover ( polys) ;
298+ // Final packed poly
299+ if let Some ( final_poly) = final_poly {
300+ Ok ( (
301+ Pcs :: batch_commit_and_write ( pp, & packed_polys, transcript) ?,
302+ Some ( Pcs :: commit_and_write ( pp, & final_poly, transcript) ?)
303+ ) )
304+ } else {
305+ Ok ( ( Pcs :: batch_commit_and_write ( pp, & packed_polys, transcript) ?, None ) )
306+ }
307+ }
284308
285309pub fn pcs_open < E : ExtensionField , Pcs : PolynomialCommitmentScheme < E > > (
286310 pp : & Pcs :: ProverParam ,
@@ -316,18 +340,22 @@ pub fn pcs_batch_open_diff_size<E: ExtensionField, Pcs: PolynomialCommitmentSche
316340 // TODO: Sort the polys by decreasing size
317341 // TODO: The prover should be able to avoid packing the polys again
318342 let ( packed_polys, final_poly, packed_comps, final_comp) = pack_poly_prover ( polys) ;
319- let packed_polys: Vec < ArcMultilinearExtension < E > > = packed_polys. into_iter ( ) . map ( |p| ArcMultilinearExtension :: from ( p) ) . collect ( ) ;
320343 // TODO: Add unifying sumcheck if the points do not match
321344 // For now, assume that all polys are evaluated on the same points
322345 let packed_point = points[ 0 ] . clone ( ) ;
323- let final_point = if let Some ( final_poly) = & final_poly { packed_point[ packed_point. len ( ) - final_poly. num_vars ..packed_point. len ( ) ] . to_vec ( ) } else { Vec :: new ( ) } ;
346+ // Note: the points are stored in reverse
347+ let final_point = if let Some ( final_poly) = & final_poly { packed_point[ ..final_poly. num_vars ] . to_vec ( ) } else { Vec :: new ( ) } ;
324348 // Use comps to compute evals for packed polys from regular evals
325349 let ( packed_evals, final_eval) = compute_packed_eval ( & packed_point, & final_point, evals, & packed_comps, & final_comp) ;
326350
351+ let packed_polys: Vec < ArcMultilinearExtension < E > > = packed_polys. into_iter ( ) . map ( |p| ArcMultilinearExtension :: from ( p) ) . collect ( ) ;
327352 let pack_proof = Pcs :: simple_batch_open ( pp, & packed_polys, packed_comm, & packed_point, & packed_evals, transcript) ?;
328353 let final_proof = match ( & final_poly, & final_comm, & final_eval) {
329- ( Some ( final_poly) , Some ( final_comm) , Some ( final_eval) ) => Some ( Pcs :: open ( pp, final_poly, final_comm, & final_point, final_eval, transcript) ?) ,
330- _ => None ,
354+ ( Some ( final_poly) , Some ( final_comm) , Some ( final_eval) ) => {
355+ Some ( Pcs :: open ( pp, final_poly, final_comm, & final_point, final_eval, transcript) ?)
356+ }
357+ ( None , None , None ) => None ,
358+ _ => unreachable ! ( ) ,
331359 } ;
332360 Ok ( ( pack_proof, final_proof) )
333361}
@@ -376,13 +404,17 @@ where
376404 // TODO: Add unifying sumcheck if the points do not match
377405 // For now, assume that all polys are evaluated on the same points
378406 let packed_point = points[ 0 ] . clone ( ) ;
379- let final_point = if let Some ( final_poly_num_vars) = & final_poly_num_vars { packed_point[ packed_point . len ( ) - final_poly_num_vars..packed_point . len ( ) ] . to_vec ( ) } else { Vec :: new ( ) } ;
407+ 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 ( ) } ;
380408 // Use comps to compute evals for packed polys from regular evals
381409 let ( packed_evals, final_eval) = compute_packed_eval ( & packed_point, & final_point, evals, & packed_comps, & final_comp) ;
410+
382411 Pcs :: simple_batch_verify ( vp, packed_comm, & packed_point, & packed_evals, packed_proof, transcript) ?;
383412 match ( & final_comm, & final_eval, & final_proof) {
384- ( Some ( final_comm) , Some ( final_eval) , Some ( final_proof) ) => Pcs :: verify ( vp, final_comm, & final_point, & final_eval, final_proof, transcript) ,
385- _ => Ok ( ( ) ) ,
413+ ( Some ( final_comm) , Some ( final_eval) , Some ( final_proof) ) => {
414+ Pcs :: verify ( vp, final_comm, & final_point, & final_eval, final_proof, transcript)
415+ }
416+ ( None , None , None ) => Ok ( ( ) ) ,
417+ _ => unreachable ! ( ) ,
386418 }
387419}
388420
@@ -926,24 +958,26 @@ pub mod test_util {
926958 E : ExtensionField ,
927959 Pcs : PolynomialCommitmentScheme < E > ,
928960 {
929- use crate :: { pcs_batch_commit_diff_size , pcs_batch_open_diff_size, pcs_batch_verify_diff_size} ;
961+ use crate :: { pcs_batch_commit_diff_size_and_write , pcs_batch_open_diff_size, pcs_batch_verify_diff_size} ;
930962
931963 for vars_gap in 1 ..=max_vars_gap {
932964 assert ! ( max_num_vars > vars_gap * batch_size) ;
933965 let ( pp, vp) = setup_pcs :: < E , Pcs > ( max_num_vars) ;
934966
935967 let ( poly_num_vars, packed_comm, final_comm, evals, packed_proof, final_proof, challenge) = {
936968 let mut transcript = BasicTranscript :: new ( b"BaseFold" ) ;
937- let polys: Vec < DenseMultilinearExtension < E > > = ( 0 ..batch_size) . map ( |i| gen_rand_polys ( |_| max_num_vars - i * vars_gap, 1 , gen_rand_poly) ) . flatten ( ) . collect ( ) ;
938- let ( packed_comm, final_comm) = pcs_batch_commit_diff_size :: < E , Pcs > ( & pp, & polys) . unwrap ( ) ;
969+ let polys: Vec < DenseMultilinearExtension < E > > = ( 0 ..batch_size) . map ( |i|
970+ gen_rand_polys ( |_| max_num_vars - i * vars_gap, 1 , gen_rand_poly)
971+ ) . flatten ( ) . collect ( ) ;
972+ let ( packed_comm, final_comm) = pcs_batch_commit_diff_size_and_write :: < E , Pcs > ( & pp, & polys, & mut transcript) . unwrap ( ) ;
939973 let point = get_point_from_challenge ( max_num_vars, & mut transcript) ;
940- let points: Vec < Vec < E > > = polys. iter ( ) . map ( |p| point[ max_num_vars - p . num_vars .. ] . to_vec ( ) ) . collect ( ) ;
974+ let points: Vec < Vec < E > > = polys. iter ( ) . map ( |p| point[ ..p . num_vars ] . to_vec ( ) ) . collect ( ) ;
941975 let evals = polys. iter ( ) . zip ( & points) . map ( |( poly, point) | poly. evaluate ( point) ) . collect_vec ( ) ;
942976 transcript. append_field_element_exts ( & evals) ;
943977
944978 let ( packed_proof, final_proof) = pcs_batch_open_diff_size :: < E , Pcs > ( & pp, & polys, & packed_comm, & final_comm, & points, & evals, & mut transcript) . unwrap ( ) ;
945979 (
946- polys. iter ( ) . map ( |p| p. num_vars ) . collect :: < Vec < usize > > ( ) ,
980+ polys. iter ( ) . map ( |p| p. num_vars ( ) ) . collect :: < Vec < _ > > ( ) ,
947981 Pcs :: get_pure_commitment ( & packed_comm) ,
948982 if let Some ( final_comm) = final_comm { Some ( Pcs :: get_pure_commitment ( & final_comm) ) } else { None } ,
949983 evals,
@@ -961,7 +995,7 @@ pub mod test_util {
961995 }
962996
963997 let point = get_point_from_challenge ( max_num_vars, & mut transcript) ;
964- let points: Vec < Vec < E > > = poly_num_vars. iter ( ) . map ( |n| point[ max_num_vars - n.. ] . to_vec ( ) ) . collect ( ) ;
998+ let points: Vec < Vec < E > > = poly_num_vars. iter ( ) . map ( |n| point[ .. * n ] . to_vec ( ) ) . collect ( ) ;
965999 transcript. append_field_element_exts ( & evals) ;
9661000
9671001 pcs_batch_verify_diff_size :: < E , Pcs > ( & vp, & poly_num_vars, & packed_comm, & final_comm, & points, & evals, & packed_proof, & final_proof, & mut transcript) . unwrap ( ) ;
@@ -980,6 +1014,12 @@ pub mod test_util {
9801014
9811015#[ cfg( test) ]
9821016mod test {
1017+ use ark_std:: test_rng;
1018+ use ff_ext:: GoldilocksExt2 ;
1019+ use multilinear_extensions:: mle:: { DenseMultilinearExtension , FieldType , MultilinearExtension } ;
1020+ use p3_field:: PrimeCharacteristicRing ;
1021+ use p3_goldilocks:: Goldilocks ;
1022+ type E = GoldilocksExt2 ;
9831023
9841024 #[ test]
9851025 fn test_packing ( ) {
@@ -993,4 +1033,34 @@ mod test {
9931033 println ! ( "FINAL_COMP: {:?}" , final_comp) ;
9941034 }
9951035
1036+ #[ test]
1037+ fn test_packing_eval ( ) {
1038+ let mut rng = test_rng ( ) ;
1039+ let poly0 = DenseMultilinearExtension :: < E > :: random ( 4 , & mut rng) ;
1040+ let poly1 = DenseMultilinearExtension :: < E > :: random ( 3 , & mut rng) ;
1041+ let poly2 = DenseMultilinearExtension :: < E > :: random ( 2 , & mut rng) ;
1042+ let point = [ E :: from_i32 ( 5 ) , E :: from_i32 ( 7 ) , E :: from_i32 ( 9 ) , E :: from_i32 ( 11 ) , E :: from_i32 ( 13 ) ] ;
1043+ let eval0 = poly0. evaluate ( & point[ ..4 ] ) ;
1044+ let eval1 = poly1. evaluate ( & point[ ..3 ] ) ;
1045+ let eval2 = poly2. evaluate ( & point[ ..2 ] ) ;
1046+ let claim =
1047+ ( E :: ONE - point[ 4 ] ) * eval0 +
1048+ point[ 4 ] * ( E :: ONE - point[ 3 ] ) * eval1 +
1049+ point[ 4 ] * point[ 3 ] * ( E :: ONE - point[ 2 ] ) * eval2;
1050+
1051+ let mut poly = poly0. clone ( ) ;
1052+ poly. merge ( poly1. clone ( ) ) ;
1053+ poly. merge ( poly2. clone ( ) ) ;
1054+ match & mut poly. evaluations {
1055+ FieldType :: Base ( e) => {
1056+ e. extend ( vec ! [ Goldilocks :: ZERO ; 4 ] )
1057+ }
1058+ FieldType :: Ext ( e) => {
1059+ e. extend ( vec ! [ E :: ZERO ; 4 ] )
1060+ }
1061+ _ => ( )
1062+ }
1063+ let eval = poly. evaluate ( & point) ;
1064+ println ! ( "CLAIM: {:?}, EXPECTED: {:?}" , claim, eval) ;
1065+ }
9961066}
0 commit comments