@@ -6,14 +6,14 @@ use rand_core::{RngCore, TryRngCore};
66use subtle:: ConstantTimeLess ;
77
88impl < const LIMBS : usize > Random for Uint < LIMBS > {
9- fn random < R : RngCore + ?Sized > ( mut rng : & mut R ) -> Self {
9+ fn try_random < R : TryRngCore + ?Sized > ( rng : & mut R ) -> Result < Self , R :: Error > {
1010 let mut limbs = [ Limb :: ZERO ; LIMBS ] ;
1111
1212 for limb in & mut limbs {
13- * limb = Limb :: random ( & mut rng)
13+ * limb = Limb :: try_random ( rng) ?
1414 }
1515
16- limbs. into ( )
16+ Ok ( limbs. into ( ) )
1717 }
1818}
1919
@@ -83,35 +83,45 @@ impl<const LIMBS: usize> RandomBits for Uint<LIMBS> {
8383impl < const LIMBS : usize > RandomMod for Uint < LIMBS > {
8484 fn random_mod < R : RngCore + ?Sized > ( rng : & mut R , modulus : & NonZero < Self > ) -> Self {
8585 let mut n = Self :: ZERO ;
86- random_mod_core ( rng, & mut n, modulus, modulus. bits_vartime ( ) ) ;
86+ let Ok ( ( ) ) = random_mod_core ( rng, & mut n, modulus, modulus. bits_vartime ( ) ) ;
8787 n
8888 }
89+
90+ fn try_random_mod < R : TryRngCore + ?Sized > (
91+ rng : & mut R ,
92+ modulus : & NonZero < Self > ,
93+ ) -> Result < Self , R :: Error > {
94+ let mut n = Self :: ZERO ;
95+ random_mod_core ( rng, & mut n, modulus, modulus. bits_vartime ( ) ) ?;
96+ Ok ( n)
97+ }
8998}
9099
91100/// Generic implementation of `random_mod` which can be shared with `BoxedUint`.
92101// TODO(tarcieri): obtain `n_bits` via a trait like `Integer`
93- pub ( super ) fn random_mod_core < T , R : RngCore + ?Sized > (
102+ pub ( super ) fn random_mod_core < T , R : TryRngCore + ?Sized > (
94103 rng : & mut R ,
95104 n : & mut T ,
96105 modulus : & NonZero < T > ,
97106 n_bits : u32 ,
98- ) where
107+ ) -> Result < ( ) , R :: Error >
108+ where
99109 T : AsMut < [ Limb ] > + AsRef < [ Limb ] > + ConstantTimeLess + Zero ,
100110{
101111 #[ cfg( target_pointer_width = "64" ) ]
102- let mut next_word = || rng. next_u64 ( ) ;
112+ let mut next_word = || rng. try_next_u64 ( ) ;
103113 #[ cfg( target_pointer_width = "32" ) ]
104- let mut next_word = || rng. next_u32 ( ) ;
114+ let mut next_word = || rng. try_next_u32 ( ) ;
105115
106116 let n_limbs = n_bits. div_ceil ( Limb :: BITS ) as usize ;
107117
108118 let hi_word_modulus = modulus. as_ref ( ) . as_ref ( ) [ n_limbs - 1 ] . 0 ;
109119 let mask = !0 >> hi_word_modulus. leading_zeros ( ) ;
110- let mut hi_word = next_word ( ) & mask;
120+ let mut hi_word = next_word ( ) ? & mask;
111121
112122 loop {
113123 while hi_word > hi_word_modulus {
114- hi_word = next_word ( ) & mask;
124+ hi_word = next_word ( ) ? & mask;
115125 }
116126 // Set high limb
117127 n. as_mut ( ) [ n_limbs - 1 ] = Limb :: from_le_bytes ( hi_word. to_le_bytes ( ) ) ;
@@ -120,15 +130,16 @@ pub(super) fn random_mod_core<T, R: RngCore + ?Sized>(
120130 // Need to deserialize from little-endian to make sure that two 32-bit limbs
121131 // deserialized sequentially are equal to one 64-bit limb produced from the same
122132 // byte stream.
123- n. as_mut ( ) [ i] = Limb :: from_le_bytes ( next_word ( ) . to_le_bytes ( ) ) ;
133+ n. as_mut ( ) [ i] = Limb :: from_le_bytes ( next_word ( ) ? . to_le_bytes ( ) ) ;
124134 }
125135 // If the high limb is equal to the modulus' high limb, it's still possible
126136 // that the full uint is too big so we check and repeat if it is.
127137 if n. ct_lt ( modulus) . into ( ) {
128138 break ;
129139 }
130- hi_word = next_word ( ) & mask;
140+ hi_word = next_word ( ) ? & mask;
131141 }
142+ Ok ( ( ) )
132143}
133144
134145#[ cfg( test) ]
0 commit comments