summaryrefslogtreecommitdiff
path: root/src/lib/libc/crypt/arc4random.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/crypt/arc4random.c')
-rw-r--r--src/lib/libc/crypt/arc4random.c38
1 files changed, 1 insertions, 37 deletions
diff --git a/src/lib/libc/crypt/arc4random.c b/src/lib/libc/crypt/arc4random.c
index 13b94ed111..9460af1e54 100644
--- a/src/lib/libc/crypt/arc4random.c
+++ b/src/lib/libc/crypt/arc4random.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: arc4random.c,v 1.40 2014/07/09 16:52:09 bcook Exp $ */ 1/* $OpenBSD: arc4random.c,v 1.41 2014/07/12 13:24:54 deraadt Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996, David Mazieres <dm@uun.org> 4 * Copyright (c) 1996, David Mazieres <dm@uun.org>
@@ -211,39 +211,3 @@ arc4random_buf(void *buf, size_t n)
211 _rs_random_buf(buf, n); 211 _rs_random_buf(buf, n);
212 _ARC4_UNLOCK(); 212 _ARC4_UNLOCK();
213} 213}
214
215/*
216 * Calculate a uniformly distributed random number less than upper_bound
217 * avoiding "modulo bias".
218 *
219 * Uniformity is achieved by generating new random numbers until the one
220 * returned is outside the range [0, 2**32 % upper_bound). This
221 * guarantees the selected random number will be inside
222 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
223 * after reduction modulo upper_bound.
224 */
225uint32_t
226arc4random_uniform(uint32_t upper_bound)
227{
228 uint32_t r, min;
229
230 if (upper_bound < 2)
231 return 0;
232
233 /* 2**32 % x == (2**32 - x) % x */
234 min = -upper_bound % upper_bound;
235
236 /*
237 * This could theoretically loop forever but each retry has
238 * p > 0.5 (worst case, usually far better) of selecting a
239 * number inside the range we need, so it should rarely need
240 * to re-roll.
241 */
242 for (;;) {
243 r = arc4random();
244 if (r >= min)
245 break;
246 }
247
248 return r % upper_bound;
249}