| 321 | } |
| 322 | |
| 323 | fn generate_u32_in_range(&mut self, aes: &mut Crypter, modulus: u32) -> Result<u32> { |
| 324 | let modulus = modulus as u64; |
| 325 | // Generate one extra byte of randomness to have reasonably low resampling probability. |
| 326 | let need_bytes = (modulus.next_power_of_two().trailing_zeros() + 7) / 8 + 1; |
| 327 | // The maximum possible value we could generate with `need_bytes` random bytes. |
| 328 | // need_bytes <= 5 because modulus is below 2^32. |
| 329 | let max_rand_value = (1u64 << (need_bytes as u64 * 8)) - 1; |
| 330 | let num_biased = (max_rand_value + 1) % modulus; |
| 331 | let rejection_bound = max_rand_value - num_biased; |
| 332 | loop { |
| 333 | let rand_value = self.generate_random_number(aes, need_bytes as usize)?; |
| 334 | if rand_value <= rejection_bound { |
| 335 | return Ok((rand_value % modulus) as u32); |
| 336 | } |
| 337 | } |
| 338 | } |
| 339 | } |
| 340 | |
| 341 | // Basic entropy test. |