1 /* $NetBSD: xoshiro128starstar.c,v 1.1 2024/02/18 20:57:51 christos Exp $ */
2
3 /*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 *
12 * See the COPYRIGHT file distributed with this work for additional
13 * information regarding copyright ownership.
14 */
15
16 /*
17 * Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
18 *
19 * To the extent possible under law, the author has dedicated all
20 * copyright and related and neighboring rights to this software to the
21 * public domain worldwide. This software is distributed without any
22 * warranty.
23 *
24 * See <http://creativecommons.org/publicdomain/zero/1.0/>.
25 */
26
27 #include <inttypes.h>
28
29 #include <isc/thread.h>
30
31 /*
32 * This is xoshiro128** 1.0, our 32-bit all-purpose, rock-solid generator.
33 * It has excellent (sub-ns) speed, a state size (128 bits) that is large
34 * enough for mild parallelism, and it passes all tests we are aware of.
35 *
36 * For generating just single-precision (i.e., 32-bit) floating-point
37 * numbers, xoshiro128+ is even faster.
38 *
39 * The state must be seeded so that it is not everywhere zero.
40 */
41 ISC_THREAD_LOCAL uint32_t seed[4] = { 0 };
42
43 static uint32_t
rotl(const uint32_t x,int k)44 rotl(const uint32_t x, int k) {
45 return ((x << k) | (x >> (32 - k)));
46 }
47
48 static uint32_t
next(void)49 next(void) {
50 uint32_t result_starstar, t;
51
52 result_starstar = rotl(seed[0] * 5, 7) * 9;
53 t = seed[1] << 9;
54
55 seed[2] ^= seed[0];
56 seed[3] ^= seed[1];
57 seed[1] ^= seed[2];
58 seed[0] ^= seed[3];
59
60 seed[2] ^= t;
61
62 seed[3] = rotl(seed[3], 11);
63
64 return (result_starstar);
65 }
66