weakrng.c 2.1 KB

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