@@ -18,11 +18,18 @@ impl<const LIMBS: usize> Random for Uint<LIMBS> {
18
18
}
19
19
}
20
20
21
+ /// Fill the given limbs slice with random bits.
22
+ ///
23
+ /// NOTE: Assumes that the limbs in the given slice are zeroed!
21
24
pub ( crate ) fn random_bits_core (
22
25
rng : & mut impl CryptoRngCore ,
23
- limbs : & mut [ Limb ] ,
26
+ zeroed_limbs : & mut [ Limb ] ,
24
27
bit_length : u32 ,
25
28
) -> Result < ( ) , RandomBitsError > {
29
+ if bit_length == 0 {
30
+ return Ok ( ( ) ) ;
31
+ }
32
+
26
33
let buffer: Word = 0 ;
27
34
let mut buffer = buffer. to_be_bytes ( ) ;
28
35
@@ -33,12 +40,12 @@ pub(crate) fn random_bits_core(
33
40
for i in 0 ..nonzero_limbs - 1 {
34
41
rng. try_fill_bytes ( & mut buffer)
35
42
. map_err ( RandomBitsError :: RandCore ) ?;
36
- limbs [ i] = Limb ( Word :: from_be_bytes ( buffer) ) ;
43
+ zeroed_limbs [ i] = Limb ( Word :: from_be_bytes ( buffer) ) ;
37
44
}
38
45
39
46
rng. try_fill_bytes ( & mut buffer)
40
47
. 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) ;
42
49
43
50
Ok ( ( ) )
44
51
}
@@ -190,5 +197,19 @@ mod tests {
190
197
assert ! ( res > ( U256 :: ONE << ( bit_length - lower_bound) ) ) ;
191
198
assert ! ( res < ( U256 :: ONE << bit_length) ) ;
192
199
}
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
+ }
193
214
}
194
215
}
0 commit comments