weakrng.c 1.9 KB

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