Generates a random 64-bit integer modulo a given modulus. To avoid modulo bias, rejection sampling is performed. Rejection sampling bound is 2^64 - (2^64 mod modulus). Each sampling attempt can succeed with probability 1 - (2^64 mod modulus)/2^64. Thus, the expected number of sampling rounds is 2^64/(2^64 - (2^64 mod modulus)) < 2 according to the geometric distribution. WARNING**: this function
(&mut self, modulus: Option<u64>)
| 104 | // |
| 105 | // **WARNING**: this function might leak modulus bits. Don't use it if you want to hide the modulus. |
| 106 | pub fn get_random_in_range(&mut self, modulus: Option<u64>) -> Result<u64> { |
| 107 | if let Some(m) = modulus { |
| 108 | let rem = ((u64::MAX % m) + 1) % m; |
| 109 | let rejection_bound = u64::MAX - rem; |
| 110 | let mut r; |
| 111 | loop { |
| 112 | r = vec_u64_from_bytes(&self.get_random_bytes(8)?, UINT64)?[0]; |
| 113 | if r <= rejection_bound { |
| 114 | break; |
| 115 | } |
| 116 | } |
| 117 | Ok(r % m) |
| 118 | } else { |
| 119 | Ok(vec_u64_from_bytes(&self.get_random_bytes(8)?, UINT64)?[0]) |
| 120 | } |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | /// Pseudo-random function (Prf/PRF) based on AES-128. |