arc4random.c (180687) | arc4random.c (180688) |
---|---|
1/* 2 * Copyright (c) 1996, David Mazieres <dm@uun.org> 3 * Copyright (c) 2008, Damien Miller <djm@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * --- 19 unchanged lines hidden (view full) --- 28 * when initializing the state. That makes it impossible to 29 * regenerate the same random sequence twice, so this can't be used 30 * for encryption, but will generate good random numbers. 31 * 32 * RC4 is a registered trademark of RSA Laboratories. 33 */ 34 35#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 1996, David Mazieres <dm@uun.org> 3 * Copyright (c) 2008, Damien Miller <djm@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * --- 19 unchanged lines hidden (view full) --- 28 * when initializing the state. That makes it impossible to 29 * regenerate the same random sequence twice, so this can't be used 30 * for encryption, but will generate good random numbers. 31 * 32 * RC4 is a registered trademark of RSA Laboratories. 33 */ 34 35#include <sys/cdefs.h> |
36__FBSDID("$FreeBSD: head/lib/libc/gen/arc4random.c 180687 2008-07-22 10:31:29Z ache $"); | 36__FBSDID("$FreeBSD: head/lib/libc/gen/arc4random.c 180688 2008-07-22 11:33:49Z ache $"); |
37 38#include "namespace.h" 39#include <sys/types.h> 40#include <sys/time.h> 41#include <stdlib.h> 42#include <fcntl.h> 43#include <unistd.h> 44#include <pthread.h> --- 190 unchanged lines hidden (view full) --- 235 while (n--) { 236 arc4_check_stir(); 237 buf[n] = arc4_getbyte(); 238 arc4_count--; 239 } 240 THREAD_UNLOCK(); 241} 242 | 37 38#include "namespace.h" 39#include <sys/types.h> 40#include <sys/time.h> 41#include <stdlib.h> 42#include <fcntl.h> 43#include <unistd.h> 44#include <pthread.h> --- 190 unchanged lines hidden (view full) --- 235 while (n--) { 236 arc4_check_stir(); 237 buf[n] = arc4_getbyte(); 238 arc4_count--; 239 } 240 THREAD_UNLOCK(); 241} 242 |
243/* 244 * Calculate a uniformly distributed random number less than upper_bound 245 * avoiding "modulo bias". 246 * 247 * Uniformity is achieved by generating new random numbers until the one 248 * returned is outside the range [0, 2**32 % upper_bound). This 249 * guarantees the selected random number will be inside 250 * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) 251 * after reduction modulo upper_bound. 252 */ 253u_int32_t 254arc4random_uniform(u_int32_t upper_bound) 255{ 256 u_int32_t r, min; 257 258 if (upper_bound < 2) 259 return 0; 260 261#if (ULONG_MAX > 0xffffffffUL) 262 min = 0x100000000UL % upper_bound; 263#else 264 /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ 265 if (upper_bound > 0x80000000) 266 min = 1 + ~upper_bound; /* 2**32 - upper_bound */ 267 else { 268 /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ 269 min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; 270 } 271#endif 272 273 /* 274 * This could theoretically loop forever but each retry has 275 * p > 0.5 (worst case, usually far better) of selecting a 276 * number inside the range we need, so it should rarely need 277 * to re-roll. 278 */ 279 for (;;) { 280 r = arc4random(); 281 if (r >= min) 282 break; 283 } 284 285 return (r % upper_bound); 286} 287 |
|
243#if 0 244/*-------- Test code for i386 --------*/ 245#include <stdio.h> 246#include <machine/pctr.h> 247int 248main(int argc, char **argv) 249{ 250 const int iter = 1000000; --- 12 unchanged lines hidden --- | 288#if 0 289/*-------- Test code for i386 --------*/ 290#include <stdio.h> 291#include <machine/pctr.h> 292int 293main(int argc, char **argv) 294{ 295 const int iter = 1000000; --- 12 unchanged lines hidden --- |