@@ -30,10 +30,12 @@ pub struct VIDProof {
3030}
3131
3232/// Divide `self` by the vanishing polynomial for the sub-domain, `X^{domain_size} - coeff`.
33+ ///
34+ /// coeff_powers are w^i starting with i = 0
3335pub fn divide_by_sub_vanishing_poly (
3436 poly : & DensePolynomial < ScalarField > ,
3537 domain_size : usize ,
36- coeff : ScalarField ,
38+ coeff_powers : & [ ScalarField ] ,
3739) -> DensePolynomial < ScalarField > {
3840 if poly. coeffs . len ( ) < domain_size {
3941 // If degree(poly) < len(Domain), then the quotient is zero, and the entire polynomial is the remainder
@@ -48,16 +50,48 @@ pub fn divide_by_sub_vanishing_poly(
4850 // which can be computed using the following algorithm.
4951 //
5052
51- // TODO parallelise
52- let mut quotient_vec = poly. coeffs [ domain_size..] . to_vec ( ) ;
53- //println!("poly.len(): {:?}", poly.len());
54- //assert!(poly.len() / domain_size <= 2);
55- for i in 1 ..( poly. len ( ) / domain_size) {
56- quotient_vec
57- . iter_mut ( )
58- . zip ( & poly. coeffs [ domain_size * ( i + 1 ) ..] )
59- . for_each ( |( s, c) | * s += c * & ( coeff. pow ( [ i as u64 ] ) ) ) ;
60- }
53+ let quotient_vec = ( 0 ..( poly. len ( ) / domain_size) )
54+ . into_par_iter ( )
55+ . map ( |i| poly. coeffs [ domain_size * ( i + 1 ) ..] . to_vec ( ) )
56+ . zip ( coeff_powers)
57+ . map ( |( poly, pow) | poly. into_iter ( ) . map ( |v| v * pow) . collect :: < Vec < _ > > ( ) )
58+ . reduce_with ( |mut l, r| {
59+ for i in 0 ..std:: cmp:: min ( l. len ( ) , r. len ( ) ) {
60+ l[ i] += r[ i]
61+ }
62+ l
63+ } )
64+ . unwrap ( ) ;
65+
66+ // // TODO parallelise
67+ // let mut quotient_vec = poly.coeffs[domain_size..].to_vec();
68+ //
69+ // //println!("poly.len(): {:?}", poly.len());
70+ // //assert!(poly.len() / domain_size <= 2);
71+ //
72+ // if poly.len() / domain_size > 1 {
73+ // let mut addons: Vec<_> = (1..(poly.len() / domain_size))
74+ // .into_par_iter()
75+ // .map(|i| poly.coeffs[domain_size * (i + 1)..].to_vec())
76+ // .zip(coeff_powers)
77+ // .map(|(poly, pow)| poly.into_iter().map(|v| v * pow).collect::<Vec<_>>())
78+ // .reduce_with(|mut l, r| {
79+ // for i in 0..std::cmp::min(l.len(), r.len()) {
80+ // l[i] += r[i]
81+ // }
82+ // l
83+ // })
84+ // .unwrap();
85+ //
86+ // for i in 1..(poly.len() / domain_size) {
87+ // quotient_vec
88+ // .iter_mut()
89+ // .zip(&poly.coeffs[domain_size * (i + 1)..])
90+ // .for_each(|(s, c)| *s += c * &(coeff_powers[i]));
91+ // }
92+ // }
93+ // .reduce_with(|mut l, r| &l * &r)
94+ // .unwrap()
6195
6296 let quotient = DensePolynomial :: from_coefficients_vec ( quotient_vec) ;
6397 quotient
@@ -222,6 +256,10 @@ where
222256
223257 let coset_omega = all_omegas[ node_ix * per_node_size] . clone ( ) ;
224258
259+ let coeff_powers: Vec < _ > = ( 0 ..proofs_number)
260+ . map ( |i| coset_omega. pow ( [ i as u64 ] ) )
261+ . collect ( ) ;
262+
225263 for j in indices. iter ( ) {
226264 assert ! ( all_divisors[ node_ix] . evaluate( & all_omegas[ * j] ) == ScalarField :: zero( ) ) ;
227265 }
@@ -248,7 +286,7 @@ where
248286 let quotient = divide_by_sub_vanishing_poly (
249287 & numerator_eval_interpolated,
250288 per_node_size,
251- coset_omega ,
289+ & coeff_powers ,
252290 ) ;
253291 // let (quotient, res) = DenseOrSparsePolynomial::divide_with_q_and_r(
254292 // &From::from(numerator_eval_interpolated),
@@ -687,9 +725,16 @@ mod tests {
687725 }
688726 }
689727
728+ let coeff_powers: Vec < _ > = ( 0 ..proofs_number)
729+ . map ( |i| coset_omega. pow ( [ i as u64 ] ) )
730+ . collect ( ) ;
731+
690732 println ! ( "Division" ) ;
691- let quot =
692- divide_by_sub_vanishing_poly ( & numerator_eval_interpolated, per_node_size, coset_omega) ;
733+ let quot = divide_by_sub_vanishing_poly (
734+ & numerator_eval_interpolated,
735+ per_node_size,
736+ & coeff_powers,
737+ ) ;
693738
694739 println ! (
695740 "Degree of numerator_eval_interpolated: {:?}" ,
0 commit comments