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 */
9 * \brief A weak but fast PRNG based on a linear congruential generator.
11 * We don't want to use the platform random(), since some of them are even
15 #include "lib/intmath/weakrng.h"
16 #include "lib/err/torerr.h"
20 /** Initialize the insecure RNG <b>rng</b> from a seed value <b>seed</b>. */
22 tor_init_weak_random(tor_weak_rng_t
*rng
, unsigned seed
)
24 rng
->state
= (uint32_t)(seed
& 0x7fffffff);
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
32 tor_weak_random(tor_weak_rng_t
*rng
)
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
;
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. */
48 tor_weak_random_range(tor_weak_rng_t
*rng
, int32_t top
)
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. */
55 divisor
= TOR_WEAK_RANDOM_MAX
/ top
;
57 result
= (int32_t)(tor_weak_random(rng
) / divisor
);
58 } while (result
>= top
);