From 1b8dc7f05e05c3e2a4620a171e413249caa6807c Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Thu, 13 Oct 2022 08:43:11 -0400 Subject: [PATCH] random: Use sfc64 instead of gjrand. --- nk/random.c | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/nk/random.c b/nk/random.c index df30272..5500fc9 100644 --- a/nk/random.c +++ b/nk/random.c @@ -1,17 +1,16 @@ -// Copyright 2013-2018 Nicholas J. Kain +// Copyright 2013-2022 Nicholas J. Kain // SPDX-License-Identifier: MIT #include #include "nk/hwrng.h" #include "nk/random.h" -// GJrand64: https://gjrand.sourceforge.net +// SFC64 modified to use a Weyl counter. void nk_random_init(struct nk_random_state *s) { - nk_hwrng_bytes(s->seed, sizeof(uint64_t) * 2); - s->seed[2] = 2000001; - s->seed[3] = 0; - for (size_t i = 0; i < 14; ++i) nk_random_u64(s); + nk_hwrng_bytes(s->seed, sizeof(uint64_t) * 3); + s->seed[3] = 1; + for (size_t i = 0; i < 12; ++i) nk_random_u64(s); } static inline uint64_t rotl64(const uint64_t x, int k) { @@ -20,17 +19,11 @@ static inline uint64_t rotl64(const uint64_t x, int k) { uint64_t nk_random_u64(struct nk_random_state *s) { - s->seed[1] += s->seed[2]; - s->seed[0] = rotl64(s->seed[0], 32); - s->seed[2] ^= s->seed[1]; - s->seed[3] += 0x55aa96a5; - s->seed[0] += s->seed[1]; - s->seed[2] = rotl64(s->seed[2], 23); - s->seed[1] ^= s->seed[0]; - s->seed[0] += s->seed[2]; - s->seed[1] = rotl64(s->seed[1], 19); - s->seed[2] += s->seed[0]; - s->seed[1] += s->seed[3]; - return s->seed[0]; + const uint64_t t = (s->seed[0] + s->seed[1]) ^ s->seed[3]; + s->seed[3] += 0x6a09e667a7541669ull; + s->seed[0] = s->seed[1] ^ (s->seed[1] >> 11); + s->seed[1] = s->seed[2] + (s->seed[2] << 3); + s->seed[2] = rotl64(s->seed[2], 24) + t; + return t; }