11//! Reciprocal, shared across Uint and BoxedUint
2- use crate :: { ConstChoice , Limb , NonZero , WideWord , Word } ;
2+ use crate :: { ConstChoice , Limb , NonZero , Word , primitives } ;
33use subtle:: { Choice , ConditionallySelectable } ;
44
55/// Calculates the reciprocal of the given 32-bit divisor with the highmost bit set.
@@ -49,17 +49,17 @@ pub const fn reciprocal(d: Word) -> Word {
4949 let v2 = ( v1 << 13 ) + ( ( v1 * ( ( 1 << 60 ) - v1 * d40) ) >> 47 ) ;
5050
5151 // Checks that the expression for `e` can be simplified in the way we did below.
52- debug_assert ! ( mulhilo( v2, d63) . 0 == ( 1 << 32 ) - 1 ) ;
52+ debug_assert ! ( primitives :: mulhilo( v2, d63) . 0 == ( 1 << 32 ) - 1 ) ;
5353 let e = Word :: MAX - v2. wrapping_mul ( d63) + 1 + ( v2 >> 1 ) * d0;
5454
55- let ( hi, _lo) = mulhilo ( v2, e) ;
55+ let ( hi, _lo) = primitives :: mulhilo ( v2, e) ;
5656 let v3 = ( v2 << 31 ) . wrapping_add ( hi >> 1 ) ;
5757
5858 // The paper has `(v3 + 1) * d / 2^64` (there's another 2^64, but it's accounted for later).
5959 // If `v3 == 2^64-1` this should give `d`, but we can't achieve this in our wrapping arithmetic.
6060 // Hence the `ct_select()`.
6161 let x = v3. wrapping_add ( 1 ) ;
62- let ( hi, _lo) = mulhilo ( x, d) ;
62+ let ( hi, _lo) = primitives :: mulhilo ( x, d) ;
6363 let hi = ConstChoice :: from_word_nonzero ( x) . select_word ( d, hi) ;
6464
6565 v3. wrapping_sub ( hi) . wrapping_sub ( d)
@@ -108,23 +108,6 @@ const fn short_div(dividend: u32, dividend_bits: u32, divisor: u32, divisor_bits
108108 quotient
109109}
110110
111- /// Multiplies `x` and `y`, returning the most significant
112- /// and the least significant words as `(hi, lo)`.
113- #[ inline( always) ]
114- const fn mulhilo ( x : Word , y : Word ) -> ( Word , Word ) {
115- let res = ( x as WideWord ) * ( y as WideWord ) ;
116- ( ( res >> Word :: BITS ) as Word , res as Word )
117- }
118-
119- /// Adds wide numbers represented by pairs of (most significant word, least significant word)
120- /// and returns the result in the same format `(hi, lo)`.
121- #[ inline( always) ]
122- const fn addhilo ( x_hi : Word , x_lo : Word , y_hi : Word , y_lo : Word ) -> ( Word , Word ) {
123- let res = ( ( ( x_hi as WideWord ) << Word :: BITS ) | ( x_lo as WideWord ) )
124- + ( ( ( y_hi as WideWord ) << Word :: BITS ) | ( y_lo as WideWord ) ) ;
125- ( ( res >> Word :: BITS ) as Word , res as Word )
126- }
127-
128111/// Calculate the quotient and the remainder of the division of a wide word
129112/// (supplied as high and low words) by `d`, with a precalculated reciprocal `v`.
130113#[ inline( always) ]
@@ -134,8 +117,8 @@ pub(crate) const fn div2by1(u1: Word, u0: Word, reciprocal: &Reciprocal) -> (Wor
134117 debug_assert ! ( d >= ( 1 << ( Word :: BITS - 1 ) ) ) ;
135118 debug_assert ! ( u1 < d) ;
136119
137- let ( q1, q0) = mulhilo ( reciprocal. reciprocal , u1) ;
138- let ( q1, q0) = addhilo ( q1, q0, u1, u0) ;
120+ let ( q1, q0) = primitives :: mulhilo ( reciprocal. reciprocal , u1) ;
121+ let ( q1, q0) = primitives :: addhilo ( q1, q0, u1, u0) ;
139122 let q1 = q1. wrapping_add ( 1 ) ;
140123 let r = u0. wrapping_sub ( q1. wrapping_mul ( d) ) ;
141124
0 commit comments