tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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 }