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
|
Xoroshiro128+ is an RNG algorithm developed in 2016 by David Blackman
|
||||||
and Sebastiano Vigna. It is a further development of the Xorshift algorithm
|
and Sebastiano Vigna. The VHDL code matches an updated version of
|
||||||
invented by George Marsaglia
|
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
|
This RNG passes many statistical tests, but the least significant
|
||||||
compared to a typical LFSR, but much shorter than the Mersenne Twister.
|
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 output is 1-dimensionally equidistributed.
|
||||||
|
|
||||||
The VHDL implementation produces 64 new random bits on every (enabled)
|
The VHDL implementation produces 64 new random bits on every (enabled)
|
||||||
|
@ -43,7 +47,7 @@ Seed length: 128 bits
|
||||||
Period: 2**128 - 1
|
Period: 2**128 - 1
|
||||||
|
|
||||||
FPGA resources: general logic and 64-bit adder
|
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
|
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
|
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
|
This VHDL library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Lesser General Public License
|
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
|
CXXFLAGS = -std=c++11 -Wall -O2
|
||||||
|
|
||||||
.PHONY: all
|
.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
|
ref_mt19937: ref_mt19937.cpp
|
||||||
|
|
||||||
|
@ -20,5 +20,5 @@ ref_trivium: ref_trivium.cpp
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
$(RM) ref_xoroshiro ref_mt19937 ref_trivium
|
$(RM) ref_xoroshiro128plus ref_mt19937 ref_trivium
|
||||||
|
|
||||||
|
|
|
@ -13,14 +13,13 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* ========== BEGIN of reference implementation of xoroshiro128+ ==========
|
/* ========== 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
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
and related and neighboring rights to this software to the public domain
|
and related and neighboring rights to this software to the public domain
|
||||||
|
@ -28,20 +27,46 @@ worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
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) {
|
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) {
|
uint64_t next(void) {
|
||||||
const uint64_t s0 = s[0];
|
const uint64_t s0 = s[0];
|
||||||
uint64_t s1 = s[1];
|
uint64_t s1 = s[1];
|
||||||
const uint64_t result = s0 + s1;
|
const uint64_t result = s0 + s1;
|
||||||
|
|
||||||
s1 ^= s0;
|
s1 ^= s0;
|
||||||
s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
|
s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
|
||||||
s[1] = rotl(s1, 36); // c
|
s[1] = rotl(s1, 37); // c
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -58,12 +83,12 @@ int main(int argc, const char **argv)
|
||||||
if (argc != 4) {
|
if (argc != 4) {
|
||||||
fprintf(stderr, "Reference implementation of RNG xoroshiro128+\n");
|
fprintf(stderr, "Reference implementation of RNG xoroshiro128+\n");
|
||||||
fprintf(stderr, "\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, " SEED0 seed value in range 0 .. (2**64-1)\n");
|
||||||
fprintf(stderr, " SEED1 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, " NUMVALUE number of values to get from generator\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "Example: ref_xoroshiro 0x3141592653589793 "
|
fprintf(stderr, "Example: ref_xoroshiro128plus 0x3141592653589793 "
|
||||||
"0x0123456789abcdef 100\n");
|
"0x0123456789abcdef 100\n");
|
||||||
exit(1);
|
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>
|
-- Author: Joris van Rantwijk <joris@jorisvr.nl>
|
||||||
--
|
--
|
||||||
|
@ -7,9 +7,9 @@
|
||||||
-- The generator can produce 64 new random bits on every clock cycle.
|
-- The generator can produce 64 new random bits on every clock cycle.
|
||||||
--
|
--
|
||||||
-- The algorithm "xoroshiro128+" is by David Blackman and Sebastiano Vigna.
|
-- 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
|
-- A default seed must be supplied at compile time and will be used
|
||||||
-- to initialize the generator at reset. The generator also supports
|
-- to initialize the generator at reset. The generator also supports
|
||||||
-- re-seeding at run time.
|
-- re-seeding at run time.
|
||||||
|
@ -19,12 +19,12 @@
|
||||||
--
|
--
|
||||||
-- NOTE: This is not a cryptographic random number generator.
|
-- NOTE: This is not a cryptographic random number generator.
|
||||||
--
|
--
|
||||||
-- NOTE: The least significant output bit is less random than
|
-- NOTE: The least significant output bits are not fully random and
|
||||||
-- all other output bits.
|
-- 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
|
-- This code is free software; you can redistribute it and/or
|
||||||
-- modify it under the terms of the GNU Lesser General Public
|
-- modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -131,12 +131,12 @@ begin
|
||||||
-- Update internal state.
|
-- Update internal state.
|
||||||
reg_state_s0 <= reg_state_s0 xor
|
reg_state_s0 <= reg_state_s0 xor
|
||||||
reg_state_s1 xor
|
reg_state_s1 xor
|
||||||
shiftl(reg_state_s0, 14) xor
|
rotl(reg_state_s0, 24) xor
|
||||||
shiftl(reg_state_s1, 14) xor
|
shiftl(reg_state_s0, 16) xor
|
||||||
rotl(reg_state_s0, 55);
|
shiftl(reg_state_s1, 16);
|
||||||
|
|
||||||
reg_state_s1 <= rotl(reg_state_s0, 36) xor
|
reg_state_s1 <= rotl(reg_state_s0, 37) xor
|
||||||
rotl(reg_state_s1, 36);
|
rotl(reg_state_s1, 37);
|
||||||
|
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue