Update xoroshiro128+ to 1.0 version
This commit is contained in:
parent
e92ed9ea54
commit
2085470db4
18
README.txt
18
README.txt
|
@ -25,13 +25,17 @@ NOTE: This library is not designed for cryptographic applications
|
|||
------------------
|
||||
|
||||
Xoroshiro128+ is an RNG algorithm developed in 2016 by David Blackman
|
||||
and Sebastiano Vigna. It is a further development of the Xorshift algorithm
|
||||
invented by George Marsaglia
|
||||
and Sebastiano Vigna. The VHDL code matches an updated version of
|
||||
the algorithm called "xoroshiro128+ 1.0", released in 2018.
|
||||
The Xoroshiro algorithm is based on the Xorshift concept invented
|
||||
by George Marsaglia.
|
||||
|
||||
See also http://xoroshiro.di.unimi.it/
|
||||
See also http://prng.di.unimi.it/
|
||||
|
||||
This RNG passes many statistical tests. Its period, 2**128 - 1, is long
|
||||
compared to a typical LFSR, but much shorter than the Mersenne Twister.
|
||||
This RNG passes many statistical tests, but the least significant
|
||||
output bits are known to be not fully random and fail certain tests.
|
||||
The generator has a long period (2**128 - 1) compared to a typical LFSR,
|
||||
but much shorter than the Mersenne Twister.
|
||||
The output is 1-dimensionally equidistributed.
|
||||
|
||||
The VHDL implementation produces 64 new random bits on every (enabled)
|
||||
|
@ -43,7 +47,7 @@ Seed length: 128 bits
|
|||
Period: 2**128 - 1
|
||||
|
||||
FPGA resources: general logic and 64-bit adder
|
||||
Synthesis results: 194 LUTs, 192 registers on Spartan-6
|
||||
Synthesis results: 198 LUTs, 193 registers on Spartan-6
|
||||
Timing results: 333 MHz on Spartan-6 LX45-3
|
||||
|
||||
|
||||
|
@ -141,7 +145,7 @@ Timing results: 380 MHz on Spartan-6 LX45-3 (32 bits output)
|
|||
License
|
||||
-------
|
||||
|
||||
Copyright (C) 2016 Joris van Rantwijk
|
||||
Copyright (C) 2016-2020 Joris van Rantwijk
|
||||
|
||||
This VHDL library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License
|
||||
|
|
|
@ -10,9 +10,9 @@ CFLAGS = -std=c11 -Wall -O2
|
|||
CXXFLAGS = -std=c++11 -Wall -O2
|
||||
|
||||
.PHONY: all
|
||||
all: ref_xoroshiro ref_mt19937 ref_trivium
|
||||
all: ref_xoroshiro128plus ref_mt19937 ref_trivium
|
||||
|
||||
ref_xoroshiro: ref_xoroshiro.c
|
||||
ref_xoroshiro128plus: ref_xoroshiro128plus.c
|
||||
|
||||
ref_mt19937: ref_mt19937.cpp
|
||||
|
||||
|
@ -20,5 +20,5 @@ ref_trivium: ref_trivium.cpp
|
|||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) ref_xoroshiro ref_mt19937 ref_trivium
|
||||
$(RM) ref_xoroshiro128plus ref_mt19937 ref_trivium
|
||||
|
||||
|
|
|
@ -13,14 +13,13 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
/* ========== BEGIN of reference implementation of xoroshiro128+ ==========
|
||||
* Source: http://xoroshiro.di.unimi.it/
|
||||
* Source: http://prng.di.unimi.it/
|
||||
*/
|
||||
|
||||
/* Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||
/* Written in 2016-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
|
||||
|
@ -28,22 +27,48 @@ worldwide. This software is distributed without any warranty.
|
|||
|
||||
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||
|
||||
int64_t s[2];
|
||||
#include <stdint.h>
|
||||
|
||||
/* This is xoroshiro128+ 1.0, our best and fastest small-state generator
|
||||
for floating-point numbers. We suggest to use its upper bits for
|
||||
floating-point generation, as it is slightly faster than
|
||||
xoroshiro128++/xoroshiro128**. It passes all tests we are aware of
|
||||
except for the four lower bits, which might fail linearity tests (and
|
||||
just those), so if low linear complexity is not considered an issue (as
|
||||
it is usually the case) it can be used to generate 64-bit outputs, too;
|
||||
moreover, this generator has a very mild Hamming-weight dependency
|
||||
making our test (http://prng.di.unimi.it/hwd.php) fail after 5 TB of
|
||||
output; we believe this slight bias cannot affect any application. If
|
||||
you are concerned, use xoroshiro128++, xoroshiro128** or xoshiro256+.
|
||||
|
||||
We suggest to use a sign test to extract a random Boolean value, and
|
||||
right shifts to extract subsets of bits.
|
||||
|
||||
The state must be seeded so that it is not everywhere zero. If you have
|
||||
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
|
||||
output to fill s.
|
||||
|
||||
NOTE: the parameters (a=24, b=16, b=37) of this version give slightly
|
||||
better results in our test than the 2016 version (a=55, b=14, c=36).
|
||||
*/
|
||||
|
||||
static inline uint64_t rotl(const uint64_t x, int k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
|
||||
static uint64_t s[2];
|
||||
|
||||
uint64_t next(void) {
|
||||
const uint64_t s0 = s[0];
|
||||
uint64_t s1 = s[1];
|
||||
const uint64_t result = s0 + s1;
|
||||
const uint64_t s0 = s[0];
|
||||
uint64_t s1 = s[1];
|
||||
const uint64_t result = s0 + s1;
|
||||
|
||||
s1 ^= s0;
|
||||
s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
|
||||
s[1] = rotl(s1, 36); // c
|
||||
s1 ^= s0;
|
||||
s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
|
||||
s[1] = rotl(s1, 37); // c
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ========== END of reference implementation of xoroshiro128+ ========== */
|
||||
|
@ -58,12 +83,12 @@ int main(int argc, const char **argv)
|
|||
if (argc != 4) {
|
||||
fprintf(stderr, "Reference implementation of RNG xoroshiro128+\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Usage: ref_xoroshiro SEED0 SEED1 NUMVALUE\n");
|
||||
fprintf(stderr, "Usage: ref_xoroshiro128plus SEED0 SEED1 NUMVALUE\n");
|
||||
fprintf(stderr, " SEED0 seed value in range 0 .. (2**64-1)\n");
|
||||
fprintf(stderr, " SEED1 seed value in range 0 .. (2**64-1)\n");
|
||||
fprintf(stderr, " NUMVALUE number of values to get from generator\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Example: ref_xoroshiro 0x3141592653589793 "
|
||||
fprintf(stderr, "Example: ref_xoroshiro128plus 0x3141592653589793 "
|
||||
"0x0123456789abcdef 100\n");
|
||||
exit(1);
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
--
|
||||
-- Pseudo Random Number Generator "xoroshiro128+".
|
||||
-- Pseudo Random Number Generator "xoroshiro128+ 1.0".
|
||||
--
|
||||
-- Author: Joris van Rantwijk <joris@jorisvr.nl>
|
||||
--
|
||||
|
@ -7,9 +7,9 @@
|
|||
-- The generator can produce 64 new random bits on every clock cycle.
|
||||
--
|
||||
-- The algorithm "xoroshiro128+" is by David Blackman and Sebastiano Vigna.
|
||||
-- See also http://xoroshiro.di.unimi.it/
|
||||
-- See also http://prng.di.unimi.it/
|
||||
--
|
||||
-- The generator requires a 128-bit seed value, not equal to zero.
|
||||
-- The generator requires a 128-bit seed value, not equal to all zeros.
|
||||
-- A default seed must be supplied at compile time and will be used
|
||||
-- to initialize the generator at reset. The generator also supports
|
||||
-- re-seeding at run time.
|
||||
|
@ -19,12 +19,12 @@
|
|||
--
|
||||
-- NOTE: This is not a cryptographic random number generator.
|
||||
--
|
||||
-- NOTE: The least significant output bit is less random than
|
||||
-- all other output bits.
|
||||
-- NOTE: The least significant output bits are not fully random and
|
||||
-- fail certain statistical tests.
|
||||
--
|
||||
|
||||
--
|
||||
-- Copyright (C) 2016 Joris van Rantwijk
|
||||
-- Copyright (C) 2016-2020 Joris van Rantwijk
|
||||
--
|
||||
-- This code is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -131,12 +131,12 @@ begin
|
|||
-- Update internal state.
|
||||
reg_state_s0 <= reg_state_s0 xor
|
||||
reg_state_s1 xor
|
||||
shiftl(reg_state_s0, 14) xor
|
||||
shiftl(reg_state_s1, 14) xor
|
||||
rotl(reg_state_s0, 55);
|
||||
rotl(reg_state_s0, 24) xor
|
||||
shiftl(reg_state_s0, 16) xor
|
||||
shiftl(reg_state_s1, 16);
|
||||
|
||||
reg_state_s1 <= rotl(reg_state_s0, 36) xor
|
||||
rotl(reg_state_s1, 36);
|
||||
reg_state_s1 <= rotl(reg_state_s0, 37) xor
|
||||
rotl(reg_state_s1, 37);
|
||||
|
||||
end if;
|
||||
|
||||
|
|
Loading…
Reference in New Issue