2 * \file crypto_rand_numeric.c
4 * \brief Functions for retrieving uniformly distributed numbers
8 #include "lib/crypt_ops/crypto_rand.h"
9 #include "lib/log/util_bug.h"
12 * Implementation macro: yields code that returns a uniform unbiased
13 * random number between 0 and limit. "type" is the type of the number to
14 * return; "maxval" is the largest possible value of "type"; and "fill_stmt"
15 * is a code snippet that fills an object named "val" with random bits.
17 #define IMPLEMENT_RAND_UNSIGNED(type, maxval, limit, fill_stmt) \
21 tor_assert((limit) > 0); \
23 /* We ignore any values that are >= 'cutoff,' to avoid biasing */ \
24 /* the distribution with clipping at the upper end of the type's */ \
26 cutoff = (maxval) - ((maxval)%(limit)); \
30 return val % (limit); \
35 * Return a pseudorandom integer chosen uniformly from the values between 0
36 * and <b>limit</b>-1 inclusive. limit must be strictly greater than 0, and
37 * less than UINT_MAX. */
39 crypto_rand_uint(unsigned limit
)
41 tor_assert(limit
< UINT_MAX
);
42 IMPLEMENT_RAND_UNSIGNED(unsigned, UINT_MAX
, limit
,
43 crypto_rand((char*)&val
, sizeof(val
)));
47 * Return a pseudorandom integer, chosen uniformly from the values
48 * between 0 and <b>max</b>-1 inclusive. <b>max</b> must be between 1 and
49 * INT_MAX+1, inclusive.
52 crypto_rand_int(unsigned int max
)
54 /* We can't use IMPLEMENT_RAND_UNSIGNED directly, since we're trying
55 * to return a signed type. Instead we make sure that the range is
56 * reasonable for a nonnegative int, use crypto_rand_uint(), and cast.
58 tor_assert(max
<= ((unsigned int)INT_MAX
)+1);
60 return (int)crypto_rand_uint(max
);
64 * Return a pseudorandom integer, chosen uniformly from the values i such
65 * that min <= i < max.
67 * <b>min</b> MUST be in range [0, <b>max</b>).
68 * <b>max</b> MUST be in range (min, INT_MAX].
71 crypto_rand_int_range(unsigned int min
, unsigned int max
)
73 tor_assert(min
< max
);
74 tor_assert(max
<= INT_MAX
);
76 /* The overflow is avoided here because crypto_rand_int() returns a value
77 * between 0 and (max - min) inclusive. */
78 return min
+ crypto_rand_int(max
- min
);
82 * As crypto_rand_int_range, but supports uint64_t.
85 crypto_rand_uint64_range(uint64_t min
, uint64_t max
)
87 tor_assert(min
< max
);
88 return min
+ crypto_rand_uint64(max
- min
);
92 * As crypto_rand_int_range, but supports time_t.
95 crypto_rand_time_range(time_t min
, time_t max
)
97 tor_assert(min
< max
);
98 return min
+ (time_t)crypto_rand_uint64(max
- min
);
102 * Return a pseudorandom 64-bit integer, chosen uniformly from the values
103 * between 0 and <b>max</b>-1 inclusive.
106 crypto_rand_uint64(uint64_t max
)
108 tor_assert(max
< UINT64_MAX
);
109 IMPLEMENT_RAND_UNSIGNED(uint64_t, UINT64_MAX
, max
,
110 crypto_rand((char*)&val
, sizeof(val
)));
114 #define UINT_MAX_AS_DOUBLE 4294967296.0
115 #elif SIZEOF_INT == 8
116 #define UINT_MAX_AS_DOUBLE 1.8446744073709552e+19
118 #error SIZEOF_INT is neither 4 nor 8
119 #endif /* SIZEOF_INT == 4 || ... */
122 * Return a pseudorandom double d, chosen uniformly from the range
126 crypto_rand_double(void)
128 /* We just use an unsigned int here; we don't really care about getting
129 * more than 32 bits of resolution */
131 crypto_rand((char*)&u
, sizeof(u
));
132 return ((double)u
) / UINT_MAX_AS_DOUBLE
;
136 * As crypto_rand_uint, but extract the result from a crypto_fast_rng_t
139 crypto_fast_rng_get_uint(crypto_fast_rng_t
*rng
, unsigned limit
)
141 tor_assert(limit
< UINT_MAX
);
142 IMPLEMENT_RAND_UNSIGNED(unsigned, UINT_MAX
, limit
,
143 crypto_fast_rng_getbytes(rng
, (void*)&val
, sizeof(val
)));
147 * As crypto_rand_uint64, but extract the result from a crypto_fast_rng_t.
150 crypto_fast_rng_get_uint64(crypto_fast_rng_t
*rng
, uint64_t limit
)
152 tor_assert(limit
< UINT64_MAX
);
153 IMPLEMENT_RAND_UNSIGNED(uint64_t, UINT64_MAX
, limit
,
154 crypto_fast_rng_getbytes(rng
, (void*)&val
, sizeof(val
)));
158 * As crypto_rand_u32, but extract the result from a crypto_fast_rng_t.
161 crypto_fast_rng_get_u32(crypto_fast_rng_t
*rng
)
164 crypto_fast_rng_getbytes(rng
, (void*)&val
, sizeof(val
));
169 * As crypto_rand_uint64_range(), but extract the result from a
173 crypto_fast_rng_uint64_range(crypto_fast_rng_t
*rng
,
174 uint64_t min
, uint64_t max
)
176 /* Handle corrupted input */
177 if (BUG(min
>= max
)) {
181 return min
+ crypto_fast_rng_get_uint64(rng
, max
- min
);
185 * As crypto_rand_get_double() but extract the result from a crypto_fast_rng_t.
188 crypto_fast_rng_get_double(crypto_fast_rng_t
*rng
)
191 crypto_fast_rng_getbytes(rng
, (void*)&u
, sizeof(u
));
192 return ((double)u
) / UINT_MAX_AS_DOUBLE
;