Skip to content

Commit 42ea8e6

Browse files
authored
Add a proper handling of bit_length = 0 in RandomBits (#524)
1 parent fcd621b commit 42ea8e6

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

src/uint/rand.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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!
2124
pub(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

Comments
 (0)