aboutsummaryrefslogtreecommitdiffstats
path: root/random.c
diff options
context:
space:
mode:
authorThomas Gschwantner <tharre3@gmail.com>2019-09-28 18:59:31 +0200
committerThomas Gschwantner <tharre3@gmail.com>2019-12-11 06:22:17 +0100
commit4a12b8eff80d369ab3b220aa9d533faf88dd4df9 (patch)
tree46767f57b47084507b9c41c8cf990f72922689b3 /random.c
parentFixup client, including a lot of refactoring (diff)
downloadwg-dynamic-4a12b8eff80d369ab3b220aa9d533faf88dd4df9.tar.xz
wg-dynamic-4a12b8eff80d369ab3b220aa9d533faf88dd4df9.zip
Fix random_bounded() to always be in [0, bound)
Previously random_bounded(1) would return values in [0, 1], while values > 1 would return [0, bound).
Diffstat (limited to 'random.c')
-rw-r--r--random.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/random.c b/random.c
index eedb52f..ba8acfe 100644
--- a/random.c
+++ b/random.c
@@ -68,24 +68,27 @@ get_random_bytes(uint8_t *out, size_t len)
return i == len;
}
-uint64_t random_bounded(uint64_t bound)
+uint64_t random_u64()
{
uint64_t ret;
+ if (!get_random_bytes((uint8_t *)&ret, sizeof(ret)))
+ fatal("get_random_bytes()");
- if (bound == 0)
- return 0;
+ return ret;
+}
- if (bound == 1) {
- if (!get_random_bytes((uint8_t *)&ret, sizeof(ret)))
- fatal("get_random_bytes()");
- return (ret > 0x7FFFFFFFFFFFFFFF) ? 1 : 0;
- }
+/* Returns a random number [0, bound) (exclusive) */
+uint64_t random_bounded(uint64_t bound)
+{
+ uint64_t ret, max_mod_bound;
+
+ if (bound < 2)
+ return 0;
- const uint64_t max_mod_bound = (1 + ~bound) % bound;
+ max_mod_bound = (1 + ~bound) % bound;
do {
- if (!get_random_bytes((uint8_t *)&ret, sizeof(ret)))
- fatal("get_random_bytes()");
+ ret = random_u64();
} while (ret < max_mod_bound);
return ret % bound;