SmokeRand is a set of tests for pseudorandom number generators (PRNGs). Tested generators should return either 32-bit or 64-bit unsigned uniformly distributed unsigned integers.
The current version of SmokeRand can be found here.
- Direct support of both 32-bit and 64-bit generators without taking upper/lower parts, interleaving etc. Even the lowest bits are tests.
- Two interfaces for PRNGs: either
stdin/stdoutor C API for plugins loaded as shared libraries. - A minimalistic but rather sensitive and fast set of statistical tests.
They are grouped in several batteries that take from 1 second (
express) to less than 1 hour (full). - A simple heuristic scoring of generators.
- Cross-platform multithreading support (only for PRNGs implemented as shared libraries).
- Easy integration with TestU01 and PractRand.
SmokeRand is written in C99. Compile SmokeRand using GNU Make (Makefile.gnu
or make_pkg.sh if DEB package is desired) or CMake (CMakeLists.txt), see
Compilation section for details. Then test one of the supplied
generators implemented as plugins:
$ make -f Makefile.gnu
$ cd bin
$ ./smokerand express generators/lcg64.so [--threads]You can also write a program that sends your PRNG output as binary stream to
stdout and connect it to SmokeRand through a pipe:
$ py ../misc/pyrand.py | ./smokerand express stdin32An example of Python script that will send an infinite stream of bytes to stdout:
import sys, random
while True:
random_bytes = random.randbytes(1024)
sys.stdout.buffer.write(random_bytes)A similar example in C99 for a 64-bit linear congruential generator:
#include <stdio.h>
#include <stdint.h>
#include <time.h>
#include <fcntl.h>
#if defined(_MSC_VER) || defined(__WATCOMC__)
#include <io.h>
#endif
#define BUFSIZE 256
int main() {
uint64_t x = (uint64_t) time(NULL);
uint32_t buf[BUFSIZE];
#if defined(_WIN32)
(void) _setmode( _fileno(stdout), _O_BINARY);
#endif
while (1) {
for (size_t i = 0; i < BUFSIZE; i++) {
x = 6906969069U * x + 12345U;
buf[i] = x >> 32;
}
fwrite(buf, sizeof(uint32_t), BUFSIZE, stdout);
}
return 0;
}See details in the How to test a PRNG section.
SmokeRand supports four software build systems: GNU Make, CMake, Ninja and
WMake (Open Watcom make). All plugins with pseudorandom number generators
are built as dynamic libraries: .dll (dynamic linked libraries) for Windows
and 32-bit DOS and .so (shared objects) for GNU/Linux and other UNIX-like
systems. Usage of GNU Make and CMake is considered here, information about
Ninja, WMake, compilation for DOS and other technical details can be found in
Technical notes
The manually written script for GNU Make is Makefile.gnu and doesn't require
CMake. GNU Make: supports gcc, clang (as zig cc) but not MSVC or Open Watcom.
Has install and uninstall pseudotargets for GNU/Linux.
If you work under Debian-based GNU/Linux distribution - you can run the
make_pkg.sh script that will compile SmokeRand and will create .deb package.
Otherwise just use GNU Make (install is optional):
$ make -f Makefile.gnu
$ make -f Makefile.gnu installThis makefile supports GNU/Linux, Windows (MinGW) and DOS (DJGPP).
$ cmake CMakeLists.txt [-G "Target_platform"]
$ makeFour batteries are implemented in SmokeRand:
express- simplified battery that consists of 7 tests and can be rewritten for 16-bit platforms with 64KiB segments of data and code. Less powerful thanbriefbut may be more sensitive than diehard or even dieharder.brief- a fast battery that includes a reduced set of tests, e.g. matrix rank tests and some tests for higher bits of generators are excluded.default- a more comprehensive but slower battery with extra tests for higher bits of generators and matrix rank tests. Other tests use larger samples that make them more sensitive.full- similar do default but uses larger samples.
| Battery | Number of tests | Bytes (32-bit PRNG) | Bytes (64-bit PRNG) |
|---|---|---|---|
| express | 7 | 2^26 | 2^27 |
| brief | 25 | 2^35 | 2^36 |
| default | 42 | 2^37 | 2^38 |
| full | 46 | 2^40 | 2^41 |
Custom batteries of tests also can be created as both scripts and dynamic libraries.
The are two ways to test PRNGs using SmokeRand:
- Through stdin/stdio pipes. Simple but doesn't support multithreading.
- Load PRNG from a shared library. More complex but allows multithreading. A lot of PRNG plugins are supplied with SmokeRand.
The first method can be used to test e.g. PRNG from Python standard library:
$ py ../misc/pyrand.py | ./smokerand default stdin32
Use stdin32 for 32-bit generators and stdin64 for 64-bit generators
respectively.
The second method is to test the generator implemented as a plugin. A lot of
plugins are supplied with SmokeRand, the source code is in the generators/
directory. Compiled plugins are inside the bin/generators/ directory.
Use the next command to test the generator:
$ ./smokerand default generators/lcg64.so [--threads]
SmokeRand can send the generator output to stdout in binary form and this
can be used for testing the PRNG with PractRand:
$ ./smokerand stdout generators/lcg64.so | RNG_test stdin32 -multithreaded
Getting PRNG input from stdin (multithreading is not supported in this case):
$ ./smokerand stdout generators/lcg64.so | ./smokerand express stdin32
TestU01 is a well known and very respected set of statistical tests for pseudorandom number generators. It can be used as a custom battery for SmokeRand by means of the TestU01-threads wrapper. This wrapper supports parallel run of tests from SmallCrush, Crush and BigCrush batteries by implementing its own multithreading dispatcher.
$ ./smokerand s=libtestu01th_sr_ext.so generators/lcg64.so --batparam=SmallCrush --threads
SmokeRand resolves an old problem of 64-bit PRNG testing by supplying different filters than transform 64-bit PRNG into a 32-bit one:
- Interleaved 32-bit parts:
--filter=interleaved32 - Higher 32 bits (default):
--filter=high32 - Lower 32 bits:
--filter=low32
The more detailed information about SmokeRand tests, supplied generators, batteries and other technical details can be found at:
- Generators: a short reviews of supplied PRNGs.
- Plugins: description of C API for plugins with PRNGs.
- Results: statistical tests results.
- Technical notes: details about compilation, heuristic scaling, built-in and custom batteries etc.
- Tests: a detailed description of statistical tests.
- Existing solutions: a review of other existing PRNG test suites (TestU01, PractRand etc.).