Testing the PCG random number generator
M. E. O'Neill's PCG family of random number generators looks very promising. It appears to have excellent statistical and cryptographic properties. And it takes remarkably little code to implement. (PCG stands for Permuted Congruential Generator.)
The journal article announcing PCG gives the results of testing it with the TestU01 test suite. I wanted to try it out by testing it with the DIEHARDER test suite (Robert G. Brown's extension of George Marsaglia's DIEHARD test suite) and the NIST Statistical Test Suite. I used what the generator's website calls the "minimal C implementation."
(The preprint of the journal article is dated 2015 but apparently hasn't been published yet.)
For the NIST test suite, I generated 10,000,000 bits and divided them into 10 streams.
For the DIEHARDER test suite, I generated 800,000,000 unsigned 32-bit integers. (DIEHARDER requires a lot of random numbers as input.)
For both test suites I used the seed (state) 20170707105851 and sequence constant (inc) 42.
The PCG generator did well on all the NIST tests. For every test, at least least 9 out of 10 streams passed. The test authors say you should expect at least 8 out of 10 streams to pass.
Here's an excerpt from the results. You can find the full results here.
-------------------------------------------------------- C1 C2 C3 ... C10 P-VALUE PROPORTION STATISTICAL TEST-------------------------------------------------------- 2 0 2 0 0.213309 10/10 Frequency 0 0 1 3 0.534146 10/10 BlockFrequency 3 0 0 0 0.350485 10/10 CumulativeSums 1 1 0 2 0.350485 10/10 CumulativeSums 0 2 2 1 0.911413 10/10 Runs 0 0 1 1 0.534146 10/10 LongestRun 0 1 2 0 0.739918 10/10 Rank 0 4 0 0 0.122325 10/10 FFT 1 0 0 1 0.000439 10/10 NonOverlappingTemplate ... 2 1 0 0 0.350485 9/10 NonOverlappingTemplate 0 2 1 0 0.739918 10/10 OverlappingTemplate 1 1 0 2 0.911413 10/10 Universal 1 1 0 0 0.017912 10/10 ApproximateEntropy 1 0 1 1 ---- 3/4 RandomExcursions ... 0 0 0 1 ---- 4/4 RandomExcursions 2 0 0 0 ---- 4/4 RandomExcursionsVariant ... 0 0 3 0 ---- 4/4 RandomExcursionsVariant 1 2 3 0 0.350485 9/10 Serial 1 1 1 0 0.739918 10/10 Serial 1 2 0 0 0.911413 10/10 LinearComplexity...
The DIEHARDER suite has 31 kinds tests, some of which are run many times, making a total of 114 tests. Out of the 114 tests, two returned a weak pass for the PCG input and all the rest passed. A few weak passes are to be expected from running so many tests and so this isn't a strike against the generator. In fact, it might be suspicious if no tests returned a weak pass.
Here's an edited version of the results. The full results are here.
#=============================================================================# test_name |ntup| tsamples |psamples| p-value |Assessment#=============================================================================# diehard_birthdays| 0| 100| 100|0.46682782| PASSED diehard_operm5| 0| 1000000| 100|0.83602120| PASSED diehard_rank_32x32| 0| 40000| 100|0.11092547| PASSED diehard_rank_6x8| 0| 100000| 100|0.78938803| PASSED diehard_bitstream| 0| 2097152| 100|0.81624396| PASSED diehard_opso| 0| 2097152| 100|0.95589325| PASSED diehard_oqso| 0| 2097152| 100|0.86171368| PASSED diehard_dna| 0| 2097152| 100|0.24812341| PASSEDdiehard_count_1s_str| 0| 256000| 100|0.75417270| PASSEDdiehard_count_1s_byt| 0| 256000| 100|0.25725000| PASSED diehard_parking_lot| 0| 12000| 100|0.59288414| PASSED diehard_2dsphere| 2| 8000| 100|0.79652706| PASSED diehard_3dsphere| 3| 4000| 100|0.14978100| PASSED diehard_squeeze| 0| 100000| 100|0.35356584| PASSED diehard_sums| 0| 100| 100|0.04522121| PASSED diehard_runs| 0| 100000| 100|0.39739835| PASSED diehard_runs| 0| 100000| 100|0.99128296| PASSED diehard_craps| 0| 200000| 100|0.64934221| PASSED diehard_craps| 0| 200000| 100|0.27352733| PASSED marsaglia_tsang_gcd| 0| 10000000| 100|0.10570816| PASSED marsaglia_tsang_gcd| 0| 10000000| 100|0.00267789| WEAK sts_monobit| 1| 100000| 100|0.98166534| PASSED sts_runs| 2| 100000| 100|0.05017630| PASSED sts_serial| 1| 100000| 100|0.95153782| PASSED... sts_serial| 16| 100000| 100|0.59342390| PASSED rgb_bitdist| 1| 100000| 100|0.50763759| PASSED... rgb_bitdist| 12| 100000| 100|0.98576422| PASSEDrgb_minimum_distance| 2| 10000| 1000|0.23378443| PASSED...rgb_minimum_distance| 5| 10000| 1000|0.13215367| PASSED rgb_permutations| 2| 100000| 100|0.54142546| PASSED... rgb_permutations| 5| 100000| 100|0.96040216| PASSED rgb_lagged_sum| 0| 1000000| 100|0.66587166| PASSED... rgb_lagged_sum| 31| 1000000| 100|0.00183752| WEAK rgb_lagged_sum| 32| 1000000| 100|0.13582393| PASSED rgb_kstest_test| 0| 10000| 1000|0.74708548| PASSED dab_bytedistrib| 0| 51200000| 1|0.30789191| PASSED dab_dct| 256| 50000| 1|0.89665788| PASSED dab_filltree| 32| 15000000| 1|0.67278231| PASSED dab_filltree| 32| 15000000| 1|0.35348003| PASSED dab_filltree2| 0| 5000000| 1|0.18749029| PASSED dab_filltree2| 1| 5000000| 1|0.92600020| PASSED