crypto_rand_numeric.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /**
  2. * \file crypto_rand_numeric.c
  3. *
  4. * \brief Functions for retrieving uniformly distributed numbers
  5. * from our PRNGs.
  6. **/
  7. #include "lib/crypt_ops/crypto_rand.h"
  8. #include "lib/log/util_bug.h"
  9. /**
  10. * Implementation macro: yields code that returns a uniform unbiased
  11. * random number between 0 and limit. "type" is the type of the number to
  12. * return; "maxval" is the largest possible value of "type"; and "fill_stmt"
  13. * is a code snippet that fills an object named "val" with random bits.
  14. **/
  15. #define IMPLEMENT_RAND_UNSIGNED(type, maxval, limit, fill_stmt) \
  16. do { \
  17. type val; \
  18. type cutoff; \
  19. tor_assert((limit) > 0); \
  20. \
  21. /* We ignore any values that are >= 'cutoff,' to avoid biasing */ \
  22. /* the distribution with clipping at the upper end of the type's */ \
  23. /* range. */ \
  24. cutoff = (maxval) - ((maxval)%(limit)); \
  25. while (1) { \
  26. fill_stmt; \
  27. if (val < cutoff) \
  28. return val % (limit); \
  29. } \
  30. } while (0)
  31. /**
  32. * Return a pseudorandom integer chosen uniformly from the values between 0
  33. * and <b>limit</b>-1 inclusive. limit must be strictly between 0 and
  34. * UINT_MAX. */
  35. unsigned
  36. crypto_rand_uint(unsigned limit)
  37. {
  38. tor_assert(limit < UINT_MAX);
  39. IMPLEMENT_RAND_UNSIGNED(unsigned, UINT_MAX, limit,
  40. crypto_rand((char*)&val, sizeof(val)));
  41. }
  42. /**
  43. * Return a pseudorandom integer, chosen uniformly from the values
  44. * between 0 and <b>max</b>-1 inclusive. <b>max</b> must be between 1 and
  45. * INT_MAX+1, inclusive.
  46. */
  47. int
  48. crypto_rand_int(unsigned int max)
  49. {
  50. /* We can't use IMPLEMENT_RAND_UNSIGNED directly, since we're trying
  51. * to return a signed type. Instead we make sure that the range is
  52. * reasonable for a nonnegative int, use crypto_rand_uint(), and cast.
  53. */
  54. tor_assert(max <= ((unsigned int)INT_MAX)+1);
  55. return (int)crypto_rand_uint(max);
  56. }
  57. /**
  58. * Return a pseudorandom integer, chosen uniformly from the values i such
  59. * that min <= i < max.
  60. *
  61. * <b>min</b> MUST be in range [0, <b>max</b>).
  62. * <b>max</b> MUST be in range (min, INT_MAX].
  63. **/
  64. int
  65. crypto_rand_int_range(unsigned int min, unsigned int max)
  66. {
  67. tor_assert(min < max);
  68. tor_assert(max <= INT_MAX);
  69. /* The overflow is avoided here because crypto_rand_int() returns a value
  70. * between 0 and (max - min) inclusive. */
  71. return min + crypto_rand_int(max - min);
  72. }
  73. /**
  74. * As crypto_rand_int_range, but supports uint64_t.
  75. **/
  76. uint64_t
  77. crypto_rand_uint64_range(uint64_t min, uint64_t max)
  78. {
  79. tor_assert(min < max);
  80. return min + crypto_rand_uint64(max - min);
  81. }
  82. /**
  83. * As crypto_rand_int_range, but supports time_t.
  84. **/
  85. time_t
  86. crypto_rand_time_range(time_t min, time_t max)
  87. {
  88. tor_assert(min < max);
  89. return min + (time_t)crypto_rand_uint64(max - min);
  90. }
  91. /**
  92. * Return a pseudorandom 64-bit integer, chosen uniformly from the values
  93. * between 0 and <b>max</b>-1 inclusive.
  94. **/
  95. uint64_t
  96. crypto_rand_uint64(uint64_t max)
  97. {
  98. tor_assert(max < UINT64_MAX);
  99. IMPLEMENT_RAND_UNSIGNED(uint64_t, UINT64_MAX, max,
  100. crypto_rand((char*)&val, sizeof(val)));
  101. }
  102. #if SIZEOF_INT == 4
  103. #define UINT_MAX_AS_DOUBLE 4294967296.0
  104. #elif SIZEOF_INT == 8
  105. #define UINT_MAX_AS_DOUBLE 1.8446744073709552e+19
  106. #else
  107. #error SIZEOF_INT is neither 4 nor 8
  108. #endif /* SIZEOF_INT == 4 || ... */
  109. /**
  110. * Return a pseudorandom double d, chosen uniformly from the range
  111. * 0.0 <= d < 1.0.
  112. **/
  113. double
  114. crypto_rand_double(void)
  115. {
  116. /* We just use an unsigned int here; we don't really care about getting
  117. * more than 32 bits of resolution */
  118. unsigned int u;
  119. crypto_rand((char*)&u, sizeof(u));
  120. return ((double)u) / UINT_MAX_AS_DOUBLE;
  121. }
  122. /**
  123. * As crypto_rand_uint, but extract the result from a crypto_fast_rng_t
  124. */
  125. unsigned
  126. crypto_fast_rng_get_uint(crypto_fast_rng_t *rng, unsigned limit)
  127. {
  128. tor_assert(limit < UINT_MAX);
  129. IMPLEMENT_RAND_UNSIGNED(unsigned, UINT_MAX, limit,
  130. crypto_fast_rng_getbytes(rng, (void*)&val, sizeof(val)));
  131. }
  132. /**
  133. * As crypto_rand_uint64, but extract the result from a crypto_fast_rng_t.
  134. */
  135. uint64_t
  136. crypto_fast_rng_get_uint64(crypto_fast_rng_t *rng, uint64_t limit)
  137. {
  138. tor_assert(limit < UINT64_MAX);
  139. IMPLEMENT_RAND_UNSIGNED(uint64_t, UINT64_MAX, limit,
  140. crypto_fast_rng_getbytes(rng, (void*)&val, sizeof(val)));
  141. }
  142. /**
  143. * As crypto_rand_, but extract the result from a crypto_fast_rng_t.
  144. */
  145. double
  146. crypto_fast_rng_get_double(crypto_fast_rng_t *rng)
  147. {
  148. unsigned int u;
  149. crypto_fast_rng_getbytes(rng, (void*)&u, sizeof(u));
  150. return ((double)u) / UINT_MAX_AS_DOUBLE;
  151. }