weakrng.c (2191B)
1 /* Copyright (c) 2003, Roger Dingledine 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 /** 7 * \file weakrng.c 8 * 9 * \brief A weak but fast PRNG based on a linear congruential generator. 10 * 11 * We don't want to use the platform random(), since some of them are even 12 * worse than this. 13 **/ 14 15 #include "lib/intmath/weakrng.h" 16 #include "lib/err/torerr.h" 17 18 #include <stdlib.h> 19 20 /** Initialize the insecure RNG <b>rng</b> from a seed value <b>seed</b>. */ 21 void 22 tor_init_weak_random(tor_weak_rng_t *rng, unsigned seed) 23 { 24 rng->state = (uint32_t)(seed & 0x7fffffff); 25 } 26 27 /** Return a randomly chosen value in the range 0..TOR_WEAK_RANDOM_MAX based 28 * on the RNG state of <b>rng</b>. This entropy will not be cryptographically 29 * strong; do not rely on it for anything an adversary should not be able to 30 * predict. */ 31 int32_t 32 tor_weak_random(tor_weak_rng_t *rng) 33 { 34 /* Here's a linear congruential generator. OpenBSD and glibc use these 35 * parameters; they aren't too bad, and should have maximal period over the 36 * range 0..INT32_MAX. We don't want to use the platform rand() or random(), 37 * since some platforms have bad weak RNGs that only return values in the 38 * range 0..INT16_MAX, which just isn't enough. */ 39 rng->state = (rng->state * 1103515245 + 12345) & 0x7fffffff; 40 return (int32_t) rng->state; 41 } 42 43 /** Return a random number in the range [0 , <b>top</b>). {That is, the range 44 * of integers i such that 0 <= i < top.} Chooses uniformly. Requires that 45 * top is greater than 0. This randomness is not cryptographically strong; do 46 * not rely on it for anything an adversary should not be able to predict. */ 47 int32_t 48 tor_weak_random_range(tor_weak_rng_t *rng, int32_t top) 49 { 50 /* We don't want to just do tor_weak_random() % top, since random() is often 51 * implemented with an LCG whose modulus is a power of 2, and those are 52 * cyclic in their low-order bits. */ 53 int divisor, result; 54 raw_assert(top > 0); 55 divisor = TOR_WEAK_RANDOM_MAX / top; 56 do { 57 result = (int32_t)(tor_weak_random(rng) / divisor); 58 } while (result >= top); 59 return result; 60 }