#include #include #include #include #include #include #include #include #include #include static inline uint64_t rotl(const uint64_t x, int k) { return (x << k) | (x >> (64 - k)); } static uint64_t s[2] = { 1, -1 }; uint64_t next(void) { const uint64_t s0 = s[0]; uint64_t s1 = s[1]; const uint64_t result = s0 + s1; s1 ^= s0; s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b s[1] = rotl(s1, 37); // c return result; } unsigned long xoroshiro128p_bits(void *a, void *b) { return (uint32_t)next(); } double xoroshiro128p_01(void *a, void *b) { return (next() >> 11) * 0x1.0p-53; } void write_state(void *unused) {} int main(int argc, char *argv[]) { unif01_Gen gen; gen.name = "xoroshiro128+-lower32"; gen.Write = write_state; gen.GetBits = xoroshiro128p_bits; gen.GetU01 = xoroshiro128p_01; /* The following TestU01 tests give an idea of how the linear degree increases from low to high bits using the + scrambler. Linearity tests are failed on the lowest bits, but are passed as we go up. Estimations of the linear degree can be found in "Scrambled Linear Pseudorandom Number Generators". The failures are due exclusively to the bits of low degree, as there are no linear dependencies between the bits. */ // 600x600 Binary-rank test on the lower 4 bits (fail) smarsa_MatrixRank(&gen, NULL, 1, 100, 28, 4, 600, 600); // 5000x5000 binary-rank test on the lower 10 bits (fail) smarsa_MatrixRank(&gen, NULL, 1, 100, 22, 10, 5000, 5000); // 10000x10000 binary-rank test on bits [5..15) (pass) smarsa_MatrixRank(&gen, NULL, 1, 100, 17, 10, 10000, 10000); // Linear-complexity test on bit 0 (fail) scomp_LinearComp(&gen, NULL, 1, 400000, 31, 1); // Linear-complexity test on bit 1 (fail) scomp_LinearComp(&gen, NULL, 1, 400000, 30, 1); // Linear-complexity test on bit 2 (pass) scomp_LinearComp(&gen, NULL, 1, 400000, 29, 1); // Linear-complexity test with larger bound on bit 2 (fail) scomp_LinearComp(&gen, NULL, 1, 1000000, 29, 1); // Linear-complexity test with larger bound on bit 3 (pass) scomp_LinearComp(&gen, NULL, 1, 1000000, 28, 1); }