@@ -18,11 +18,18 @@ impl<const LIMBS: usize> Random for Uint<LIMBS> {
1818 }
1919}
2020
21+ /// Fill the given limbs slice with random bits.
22+ ///
23+ /// NOTE: Assumes that the limbs in the given slice are zeroed!
2124pub ( crate ) fn random_bits_core (
2225 rng : & mut impl CryptoRngCore ,
23- limbs : & mut [ Limb ] ,
26+ zeroed_limbs : & mut [ Limb ] ,
2427 bit_length : u32 ,
2528) -> Result < ( ) , RandomBitsError > {
29+ if bit_length == 0 {
30+ return Ok ( ( ) ) ;
31+ }
32+
2633 let buffer: Word = 0 ;
2734 let mut buffer = buffer. to_be_bytes ( ) ;
2835
@@ -33,12 +40,12 @@ pub(crate) fn random_bits_core(
3340 for i in 0 ..nonzero_limbs - 1 {
3441 rng. try_fill_bytes ( & mut buffer)
3542 . map_err ( RandomBitsError :: RandCore ) ?;
36- limbs [ i] = Limb ( Word :: from_be_bytes ( buffer) ) ;
43+ zeroed_limbs [ i] = Limb ( Word :: from_be_bytes ( buffer) ) ;
3744 }
3845
3946 rng. try_fill_bytes ( & mut buffer)
4047 . map_err ( RandomBitsError :: RandCore ) ?;
41- limbs [ nonzero_limbs - 1 ] = Limb ( Word :: from_be_bytes ( buffer) & mask) ;
48+ zeroed_limbs [ nonzero_limbs - 1 ] = Limb ( Word :: from_be_bytes ( buffer) & mask) ;
4249
4350 Ok ( ( ) )
4451}
@@ -190,5 +197,19 @@ mod tests {
190197 assert ! ( res > ( U256 :: ONE << ( bit_length - lower_bound) ) ) ;
191198 assert ! ( res < ( U256 :: ONE << bit_length) ) ;
192199 }
200+
201+ // One incomplete limb
202+ let bit_length = 7 ;
203+ for _ in 0 ..10 {
204+ let res = U256 :: random_bits ( & mut rng, bit_length) ;
205+ assert ! ( res < ( U256 :: ONE << bit_length) ) ;
206+ }
207+
208+ // Zero bits
209+ let bit_length = 0 ;
210+ for _ in 0 ..10 {
211+ let res = U256 :: random_bits ( & mut rng, bit_length) ;
212+ assert_eq ! ( res, U256 :: ZERO ) ;
213+ }
193214 }
194215}
0 commit comments