@@ -321,39 +321,6 @@ impl<P: Field<Limbs = [u64; 4]>> FieldElement<P> {
321321 }
322322}
323323
324- #[ inline]
325- fn wide_mul < P : Field > ( a : & P :: Limbs , b : & P :: Limbs ) -> ( P :: Limbs , P :: Limbs ) {
326- let a_slice = a. as_ref ( ) ;
327- let b_slice = b. as_ref ( ) ;
328- let n = a_slice. len ( ) ;
329- let mut lo = P :: Limbs :: default ( ) ;
330- let mut hi = P :: Limbs :: default ( ) ;
331- {
332- let lo_slice = lo. as_mut ( ) ;
333- let hi_slice = hi. as_mut ( ) ;
334- for i in 0 ..n {
335- let mut carry = 0u64 ;
336- for ( j, & bj) in b_slice. iter ( ) . enumerate ( ) {
337- let idx = i + j;
338- let cell = if idx < n {
339- lo_slice[ idx]
340- } else {
341- hi_slice[ idx - n]
342- } ;
343- let ( product, new_carry) = a_slice[ i] . carrying_mul_add ( bj, cell, carry) ;
344- if idx < n {
345- lo_slice[ idx] = product;
346- } else {
347- hi_slice[ idx - n] = product;
348- }
349- carry = new_carry;
350- }
351- hi_slice[ i] = carry;
352- }
353- }
354- ( lo, hi)
355- }
356-
357324#[ inline]
358325fn ge_modulus < P : Field > ( x : & P :: Limbs ) -> bool {
359326 let x_slice = x. as_ref ( ) ;
@@ -367,59 +334,61 @@ fn ge_modulus<P: Field>(x: &P::Limbs) -> bool {
367334 true
368335}
369336
370- fn montgomery_reduce < P : Field > ( mut lo : P :: Limbs , mut hi : P :: Limbs ) -> P :: Limbs {
371- let n = lo. as_ref ( ) . len ( ) ;
337+ pub fn mont_mul < P : Field > ( a : & P :: Limbs , b : & P :: Limbs ) -> P :: Limbs {
338+ let a = a. as_ref ( ) ;
339+ let b = b. as_ref ( ) ;
372340 let m = P :: MODULUS ;
373341 let p = m. as_ref ( ) ;
374342 let p_inv = P :: PARAMS . p_inv ;
375- let mut extra_carry = false ;
343+ let n = a . len ( ) ;
376344
377- for i in 0 ..n {
378- let m_i = lo. as_ref ( ) [ i] . wrapping_mul ( p_inv) ;
345+ let mut t = P :: Limbs :: default ( ) ;
346+ let mut t_hi: u64 = 0 ;
347+ let mut t_hi1: u64 = 0 ;
348+
349+ for & bi in b {
379350 let mut carry = 0u64 ;
380- for ( j, & pj) in p. iter ( ) . enumerate ( ) {
381- let idx = i + j;
382- let cell = if idx < n {
383- lo. as_ref ( ) [ idx]
384- } else {
385- hi. as_ref ( ) [ idx - n]
386- } ;
387- let ( prod, new_carry) = m_i. carrying_mul_add ( pj, cell, carry) ;
388- if idx < n {
389- lo. as_mut ( ) [ idx] = prod;
390- } else {
391- hi. as_mut ( ) [ idx - n] = prod;
351+ {
352+ let t_mut = t. as_mut ( ) ;
353+ for j in 0 ..n {
354+ let prod = ( a[ j] as u128 ) * ( bi as u128 ) + ( t_mut[ j] as u128 ) + ( carry as u128 ) ;
355+ t_mut[ j] = prod as u64 ;
356+ carry = ( prod >> 64 ) as u64 ;
392357 }
393- carry = new_carry;
394- }
395- let mut k = i + n;
396- while carry != 0 && k < 2 * n {
397- let cell = hi. as_ref ( ) [ k - n] ;
398- let ( v, nc) = cell. overflowing_add ( carry) ;
399- hi. as_mut ( ) [ k - n] = v;
400- carry = if nc { 1 } else { 0 } ;
401- k += 1 ;
402358 }
403- if carry != 0 {
404- extra_carry = true ;
359+ let s = ( t_hi as u128 ) + ( carry as u128 ) ;
360+ t_hi = s as u64 ;
361+ t_hi1 = t_hi1. wrapping_add ( ( s >> 64 ) as u64 ) ;
362+
363+ let mm = t. as_ref ( ) [ 0 ] . wrapping_mul ( p_inv) ;
364+ let prod0 = ( mm as u128 ) * ( p[ 0 ] as u128 ) + ( t. as_ref ( ) [ 0 ] as u128 ) ;
365+ let mut carry = ( prod0 >> 64 ) as u64 ;
366+ {
367+ let t_mut = t. as_mut ( ) ;
368+ for j in 1 ..n {
369+ let prod = ( mm as u128 ) * ( p[ j] as u128 ) + ( t_mut[ j] as u128 ) + ( carry as u128 ) ;
370+ t_mut[ j - 1 ] = prod as u64 ;
371+ carry = ( prod >> 64 ) as u64 ;
372+ }
405373 }
374+ let s = ( t_hi as u128 ) + ( carry as u128 ) ;
375+ t. as_mut ( ) [ n - 1 ] = s as u64 ;
376+ let cout = ( s >> 64 ) as u64 ;
377+ let s2 = ( t_hi1 as u128 ) + ( cout as u128 ) ;
378+ t_hi = s2 as u64 ;
379+ t_hi1 = ( s2 >> 64 ) as u64 ;
406380 }
407381
408- let mut r = hi ;
409- if extra_carry || ge_modulus :: < P > ( & r ) {
410- let mut b = false ;
411- for ( i , ri ) in r . as_mut ( ) . iter_mut ( ) . enumerate ( ) {
412- let ( d, nb) = ri . borrowing_sub ( p[ i] , b ) ;
413- * ri = d;
414- b = nb;
382+ if t_hi != 0 || ge_modulus :: < P > ( & t ) {
383+ let t_mut = t . as_mut ( ) ;
384+ let mut borrow = false ;
385+ for i in 0 ..n {
386+ let ( d, nb) = t_mut [ i ] . borrowing_sub ( p[ i] , borrow ) ;
387+ t_mut [ i ] = d;
388+ borrow = nb;
415389 }
416390 }
417- r
418- }
419-
420- pub fn mont_mul < P : Field > ( a : & P :: Limbs , b : & P :: Limbs ) -> P :: Limbs {
421- let ( lo, hi) = wide_mul :: < P > ( a, b) ;
422- montgomery_reduce :: < P > ( lo, hi)
391+ t
423392}
424393
425394impl < P : Field > Add for FieldElement < P > {
0 commit comments