@@ -60,20 +60,9 @@ impl Inverter for BoxedBernsteinYangInverter {
6060
6161    fn  invert ( & self ,  value :  & BoxedUint )  -> CtOption < Self :: Output >  { 
6262        let  mut  d = BoxedInt62L :: zero ( self . modulus . 0 . len ( ) ) ; 
63-         let  mut  e = self . adjuster . clone ( ) ; 
64-         let  mut  f = self . modulus . clone ( ) ; 
6563        let  mut  g = BoxedInt62L :: from ( value) . widen ( d. 0 . len ( ) ) ; 
64+         let  f = divsteps ( & mut  d,  & self . adjuster ,  & self . modulus ,  & mut  g,  self . inverse ) ; 
6665
67-         debug_assert_eq ! ( g. 0 . len( ) ,  self . modulus. 0 . len( ) ) ; 
68- 
69-         let  mut  delta = 1 ; 
70-         let  mut  matrix; 
71- 
72-         while  !g. is_zero ( )  { 
73-             ( delta,  matrix)  = jump ( & f. 0 ,  & g. 0 ,  delta) ; 
74-             ( f,  g)  = fg ( f,  g,  matrix) ; 
75-             ( d,  e)  = de ( & self . modulus ,  self . inverse ,  d,  e,  matrix) ; 
76-         } 
7766        // At this point the absolute value of "f" equals the greatest common divisor of the 
7867        // integer to be inverted and the modulus the inverter was created for. 
7968        // Thus, if "f" is neither 1 nor -1, then the sought inverse does not exist. 
@@ -85,28 +74,48 @@ impl Inverter for BoxedBernsteinYangInverter {
8574    } 
8675} 
8776
77+ /// Algorithm `divsteps2` to compute (δₙ, fₙ, gₙ) = divstepⁿ(δ, f, g) as described in Figure 10.1 
78+ /// of <https://eprint.iacr.org/2019/266.pdf>. 
79+ fn  divsteps ( 
80+     d :  & mut  BoxedInt62L , 
81+     e :  & BoxedInt62L , 
82+     f_0 :  & BoxedInt62L , 
83+     g :  & mut  BoxedInt62L , 
84+     inverse :  i64 , 
85+ )  -> BoxedInt62L  { 
86+     debug_assert_eq ! ( f_0. 0 . len( ) ,  g. 0 . len( ) ) ; 
87+ 
88+     let  mut  e = e. clone ( ) ; 
89+     let  mut  f = f_0. clone ( ) ; 
90+     let  mut  delta = 1 ; 
91+     let  mut  matrix; 
92+ 
93+     while  !g. is_zero ( )  { 
94+         ( delta,  matrix)  = jump ( & f. 0 ,  & g. 0 ,  delta) ; 
95+         fg ( & mut  f,  g,  matrix) ; 
96+         de ( f_0,  inverse,  matrix,  d,  & mut  e) ; 
97+     } 
98+ 
99+     f
100+ } 
101+ 
88102/// Returns the updated values of the variables f and g for specified initial ones and 
89103/// Bernstein-Yang transition matrix multiplied by 2^62. The returned vector is 
90104/// "matrix * (f, g)' / 2^62", where "'" is the transpose operator. 
91- fn  fg ( f :  BoxedInt62L ,  g :  BoxedInt62L ,  t :  Matrix )  -> ( BoxedInt62L ,  BoxedInt62L )  { 
92-     ( 
93-         f. mul ( t[ 0 ] [ 0 ] ) . add ( & g. mul ( t[ 0 ] [ 1 ] ) ) . shr ( ) , 
94-         f. mul ( t[ 1 ] [ 0 ] ) . add ( & g. mul ( t[ 1 ] [ 1 ] ) ) . shr ( ) , 
95-     ) 
105+ fn  fg ( f :  & mut  BoxedInt62L ,  g :  & mut  BoxedInt62L ,  t :  Matrix )  { 
106+     // TODO(tarcieri): reduce allocations 
107+     let  f2 = f. mul ( t[ 0 ] [ 0 ] ) . add ( & g. mul ( t[ 0 ] [ 1 ] ) ) . shr ( ) ; 
108+     let  g2 = f. mul ( t[ 1 ] [ 0 ] ) . add ( & g. mul ( t[ 1 ] [ 1 ] ) ) . shr ( ) ; 
109+     * f = f2; 
110+     * g = g2; 
96111} 
97112
98113/// Returns the updated values of the variables d and e for specified initial ones and 
99114/// Bernstein-Yang transition matrix multiplied by 2^62. The returned vector is congruent modulo 
100115/// M to "matrix * (d, e)' / 2^62 (mod M)", where M is the modulus the inverter was created for 
101116/// and "'" stands for the transpose operator. Both the input and output values lie in the 
102117/// interval (-2 * M, M). 
103- fn  de ( 
104-     modulus :  & BoxedInt62L , 
105-     inverse :  i64 , 
106-     d :  BoxedInt62L , 
107-     e :  BoxedInt62L , 
108-     t :  Matrix , 
109- )  -> ( BoxedInt62L ,  BoxedInt62L )  { 
118+ fn  de ( modulus :  & BoxedInt62L ,  inverse :  i64 ,  t :  Matrix ,  d :  & mut  BoxedInt62L ,  e :  & mut  BoxedInt62L )  { 
110119    let  mask = BoxedInt62L :: MASK  as  i64 ; 
111120    let  mut  md = t[ 0 ] [ 0 ]  *  d. is_negative ( )  as  i64  + t[ 0 ] [ 1 ]  *  e. is_negative ( )  as  i64 ; 
112121    let  mut  me = t[ 1 ] [ 0 ]  *  d. is_negative ( )  as  i64  + t[ 1 ] [ 1 ]  *  e. is_negative ( )  as  i64 ; 
@@ -127,7 +136,8 @@ fn de(
127136    let  cd = d. mul ( t[ 0 ] [ 0 ] ) . add ( & e. mul ( t[ 0 ] [ 1 ] ) ) . add ( & modulus. mul ( md) ) ; 
128137    let  ce = d. mul ( t[ 1 ] [ 0 ] ) . add ( & e. mul ( t[ 1 ] [ 1 ] ) ) . add ( & modulus. mul ( me) ) ; 
129138
130-     ( cd. shr ( ) ,  ce. shr ( ) ) 
139+     * d = cd. shr ( ) ; 
140+     * e = ce. shr ( ) ; 
131141} 
132142
133143/// "Bigint"-like (62 * LIMBS)-bit signed integer type, whose variables store numbers in the two's 
@@ -402,7 +412,7 @@ mod tests {
402412            . into ( ) , 
403413        ) ; 
404414        let  inverse = 3687945983376704433 ; 
405-         let  d = BoxedInt62L ( 
415+         let  mut   d = BoxedInt62L ( 
406416            vec ! [ 
407417                3490544662636853909 , 
408418                2211268325417683828 , 
@@ -413,7 +423,7 @@ mod tests {
413423            ] 
414424            . into ( ) , 
415425        ) ; 
416-         let  e = BoxedInt62L ( 
426+         let  mut   e = BoxedInt62L ( 
417427            vec ! [ 
418428                4004071259428196451 , 
419429                1262234674432503659 , 
@@ -426,9 +436,9 @@ mod tests {
426436        ) ; 
427437        let  t = [ [ -45035996273704960 ,  409827566090715136 ] ,  [ -14 ,  25 ] ] ; 
428438
429-         let   ( new_d ,  new_e )  =  super :: de ( & modulus,  inverse,  d ,  e ,  t ) ; 
439+         super :: de ( & modulus,  inverse,  t ,   & mut  d ,   & mut  e ) ; 
430440        assert_eq ! ( 
431-             new_d , 
441+             d , 
432442            BoxedInt62L ( 
433443                vec![ 
434444                    1211048314408256470 , 
@@ -442,7 +452,7 @@ mod tests {
442452            ) 
443453        ) ; 
444454
445-         assert_eq ! ( new_e ,  BoxedInt62L ( vec![ 0 ,  0 ,  0 ,  0 ,  0 ,  0 ] . into( ) ) ) ; 
455+         assert_eq ! ( e ,  BoxedInt62L ( vec![ 0 ,  0 ,  0 ,  0 ,  0 ,  0 ] . into( ) ) ) ; 
446456    } 
447457
448458    #[ test]  
0 commit comments