diff options
Diffstat (limited to 'lib/isc/xoshiro128starstar.c')
-rw-r--r-- | lib/isc/xoshiro128starstar.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/isc/xoshiro128starstar.c b/lib/isc/xoshiro128starstar.c new file mode 100644 index 0000000..7698ee8 --- /dev/null +++ b/lib/isc/xoshiro128starstar.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) + * + * To the extent possible under law, the author has dedicated all + * copyright and related and neighboring rights to this software to the + * public domain worldwide. This software is distributed without any + * warranty. + * + * See <http://creativecommons.org/publicdomain/zero/1.0/>. + */ + +#include <inttypes.h> + +#include <isc/thread.h> + +/* + * This is xoshiro128** 1.0, our 32-bit all-purpose, rock-solid generator. + * It has excellent (sub-ns) speed, a state size (128 bits) that is large + * enough for mild parallelism, and it passes all tests we are aware of. + * + * For generating just single-precision (i.e., 32-bit) floating-point + * numbers, xoshiro128+ is even faster. + * + * The state must be seeded so that it is not everywhere zero. + */ +ISC_THREAD_LOCAL uint32_t seed[4] = { 0 }; + +static uint32_t +rotl(const uint32_t x, int k) { + return ((x << k) | (x >> (32 - k))); +} + +static uint32_t +next(void) { + uint32_t result_starstar, t; + + result_starstar = rotl(seed[0] * 5, 7) * 9; + t = seed[1] << 9; + + seed[2] ^= seed[0]; + seed[3] ^= seed[1]; + seed[1] ^= seed[2]; + seed[0] ^= seed[3]; + + seed[2] ^= t; + + seed[3] = rotl(seed[3], 11); + + return (result_starstar); +} |