@@ -5,43 +5,46 @@ use crate::{Limb, Odd, Uint};
55#[ cfg( feature = "alloc" ) ]  
66use  { crate :: BoxedUint ,  subtle:: Choice } ; 
77
8- /// Implement the Montgomery reduction algorithm. 
9- /// 
10- /// This is implemented as a macro to abstract over `const fn` and boxed use cases, since the latter 
11- /// needs mutable references and thus the unstable `const_mut_refs` feature (rust-lang/rust#57349). 
12- // TODO(tarcieri): change this into a `const fn` when `const_mut_refs` is stable 
13- macro_rules!  impl_montgomery_reduction { 
14-     ( $upper: expr,  $lower: expr,  $modulus: expr,  $mod_neg_inv: expr,  $limbs: expr)  => { { 
15-         let  mut  meta_carry = Limb :: ZERO ; 
16-         let  mut  new_sum; 
17- 
18-         let  mut  i = 0 ; 
19-         while  i < $limbs { 
20-             let  u = $lower[ i] . wrapping_mul( $mod_neg_inv) ; 
21- 
22-             let  ( _,  mut  carry)  = $lower[ i] . mac( u,  $modulus[ 0 ] ,  Limb :: ZERO ) ; 
23-             let  mut  new_limb; 
24- 
25-             let  mut  j = 1 ; 
26-             while  j < ( $limbs - i)  { 
27-                 ( new_limb,  carry)  = $lower[ i + j] . mac( u,  $modulus[ j] ,  carry) ; 
28-                 $lower[ i + j]  = new_limb; 
29-                 j += 1 ; 
30-             } 
31-             while  j < $limbs { 
32-                 ( new_limb,  carry)  = $upper[ i + j - $limbs] . mac( u,  $modulus[ j] ,  carry) ; 
33-                 $upper[ i + j - $limbs]  = new_limb; 
34-                 j += 1 ; 
35-             } 
36- 
37-             ( new_sum,  meta_carry)  = $upper[ i] . adc( carry,  meta_carry) ; 
38-             $upper[ i]  = new_sum; 
39- 
40-             i += 1 ; 
8+ /// Algorithm 14.32 in Handbook of Applied Cryptography <https://cacr.uwaterloo.ca/hac/about/chap14.pdf> 
9+ const  fn  montgomery_reduction_inner ( 
10+     upper :  & mut  [ Limb ] , 
11+     lower :  & mut  [ Limb ] , 
12+     modulus :  & [ Limb ] , 
13+     mod_neg_inv :  Limb , 
14+ )  -> Limb  { 
15+     let  nlimbs = modulus. len ( ) ; 
16+     debug_assert ! ( nlimbs == upper. len( ) ) ; 
17+     debug_assert ! ( nlimbs == lower. len( ) ) ; 
18+ 
19+     let  mut  meta_carry = Limb :: ZERO ; 
20+     let  mut  new_sum; 
21+ 
22+     let  mut  i = 0 ; 
23+     while  i < nlimbs { 
24+         let  u = lower[ i] . wrapping_mul ( mod_neg_inv) ; 
25+ 
26+         let  ( _,  mut  carry)  = lower[ i] . mac ( u,  modulus[ 0 ] ,  Limb :: ZERO ) ; 
27+         let  mut  new_limb; 
28+ 
29+         let  mut  j = 1 ; 
30+         while  j < ( nlimbs - i)  { 
31+             ( new_limb,  carry)  = lower[ i + j] . mac ( u,  modulus[ j] ,  carry) ; 
32+             lower[ i + j]  = new_limb; 
33+             j += 1 ; 
4134        } 
35+         while  j < nlimbs { 
36+             ( new_limb,  carry)  = upper[ i + j - nlimbs] . mac ( u,  modulus[ j] ,  carry) ; 
37+             upper[ i + j - nlimbs]  = new_limb; 
38+             j += 1 ; 
39+         } 
40+ 
41+         ( new_sum,  meta_carry)  = upper[ i] . adc ( carry,  meta_carry) ; 
42+         upper[ i]  = new_sum; 
43+ 
44+         i += 1 ; 
45+     } 
4246
43-         meta_carry
44-     } } ; 
47+     meta_carry
4548} 
4649
4750/// Algorithm 14.32 in Handbook of Applied Cryptography <https://cacr.uwaterloo.ca/hac/about/chap14.pdf> 
@@ -51,12 +54,11 @@ pub const fn montgomery_reduction<const LIMBS: usize>(
5154    mod_neg_inv :  Limb , 
5255)  -> Uint < LIMBS >  { 
5356    let  ( mut  lower,  mut  upper)  = * lower_upper; 
54-     let  meta_carry = impl_montgomery_reduction ! ( 
55-         upper. limbs, 
56-         lower. limbs, 
57+     let  meta_carry = montgomery_reduction_inner ( 
58+         & mut   upper. limbs , 
59+         & mut   lower. limbs , 
5760        & modulus. 0 . limbs , 
5861        mod_neg_inv, 
59-         LIMBS 
6062    ) ; 
6163
6264    // Division is simply taking the upper half of the limbs 
@@ -79,8 +81,7 @@ pub(crate) fn montgomery_reduction_boxed_mut(
7981    debug_assert_eq ! ( out. nlimbs( ) ,  modulus. nlimbs( ) ) ; 
8082
8183    let  ( lower,  upper)  = x. limbs . split_at_mut ( modulus. nlimbs ( ) ) ; 
82-     let  meta_carry =
83-         impl_montgomery_reduction ! ( upper,  lower,  & modulus. limbs,  mod_neg_inv,  modulus. nlimbs( ) ) ; 
84+     let  meta_carry = montgomery_reduction_inner ( upper,  lower,  & modulus. limbs ,  mod_neg_inv) ; 
8485
8586    out. limbs . copy_from_slice ( upper) ; 
8687    let  borrow = out. sbb_assign ( modulus,  Limb :: ZERO ) ; 
0 commit comments