Our test recommendation

The following code generates a 25.6 MB file from Python’s Mersenne Twister, but there’s a new twist! Every 256th byte is 42 so the badness is quite subtle. We used this for testing our fast and slow IID tests.

They both failed to detect the rogue 42s. It is a very subtle defect. The following following is the NIST test run finding the 42s:-

import random

with open('/tmp/badfile.bin', 'wb') as f:
    for i in range(100_000):
        for j in range(256):
            r = random.getrandbits(8)
            f.write(r.to_bytes(1, byteorder='big', signed=False))
        r = 42
        f.write(r.to_bytes(1, byteorder='big', signed=False))
nist-iid-tests/cpp/ea_iid -v   /tmp/badfile.bin
Opening file: '/tmp/badfile.bin'
Loaded 25700000 samples of 256 distinct 8-bit-wide symbols
Number of Binary samples: 205600000
Calculating baseline statistics...
        Raw Mean: 127.161515
        Median: 127.000000
        Binary: false

Literal MCV Estimate: mode = 200374, p-hat = 0.0077966536964980543, p_u = 0.0078413431447085739
Bitstring MCV Estimate: mode = 102894942, p-hat = 0.50046178015564202, p_u = 0.50055160063005621
H_original: 6.994683
H_bitstring: 0.998409
min(H_original, 8 X H_bitstring): 6.994683
Chi square independence
        score = 65076.192898
        degrees of freedom = 65280
        p-value = 0.713210

Chi square goodness of fit
        score = 2279.149983
        degrees of freedom = 2295
        p-value = 0.588872

** Passed chi square tests

LiteralLongest Repeated Substring results
        P_col: 0.00392148
        Length of LRS: 6
        Pr(X >= 1): 0.6991
** Passed length of longest repeated substring test

Beginning initial tests...

Initial test results
              excursion: 192089
     numDirectionalRuns: 1.71339e+07
     lenDirectionalRuns: 9
  numIncreasesDecreases: 1.28998e+07
          numRunsMedian: 1.28495e+07
          lenRunsMedian: 23
           avgCollision: 20.745
           maxCollision: 77
         periodicity(1): 99912
         periodicity(2): 100529
         periodicity(8): 101335
        periodicity(16): 99921
        periodicity(32): 100602
          covariance(1): 4.1559e+11
          covariance(2): 4.15587e+11
          covariance(8): 4.1559e+11
         covariance(16): 4.15585e+11
         covariance(32): 4.15579e+11
            compression: 2.74362e+07



                statistic  C[i][0]  C[i][1]  C[i][2]
----------------------------------------------------
                excursion      73       0       6
       numDirectionalRuns       6       0      26
       lenDirectionalRuns      23       6       0
    numIncreasesDecreases       8       0       6
            numRunsMedian       6       0       9
            lenRunsMedian      23       5       1
            avgCollision*       0       0   10000  <<<<
             maxCollision     310       3       3
           periodicity(1)     741       0       6
           periodicity(2)      12       0       6
           periodicity(8)       6       0      61
          periodicity(16)    1919       0       6
          periodicity(32)      19       0       6
            covariance(1)       6       0      12
            covariance(2)       6       0      14
            covariance(8)       6       0       8
           covariance(16)       6       0       6
           covariance(32)       6       0      13
              compression       6       0      15
(* denotes failed test)

** Failed IID permutation tests       

Surprisingly for such a simple program, ent also caught the recurring 42 in the Chi squared test, although it’s not a pure IID testing suite of course. But if you had passed IID testing, your next step would have been a randomness test and for smallish sample sizes (approx. 500 kB) ent is thee go-to program.

ent /tmp/badfile.bin
Entropy = 7.997822 bits per byte.

Optimum compression would reduce the size
of this 25700000 byte file by 0 percent.

Chi square distribution for 25700000 samples is 100190.22, and randomly
would exceed this value less than 0.01 percent of the times.

Arithmetic mean value of data bytes is 127.1615 (127.5 = random).
Monte Carlo value for Pi is 3.148333319 (error 0.21 percent).
Serial correlation coefficient is 0.000139 (totally uncorrelated = 0.0).

Grudgingly we have to admit that the NIST IID test is more powerful than either of our tests :-( For interest, if you have a good and proper IID file, the NIST test is pretty quick. For example, we tested 10 MB of /dev/urandom product, and it took less than 2 minutes. It’s only dog slow when the samples are very skewed (it happens randomly as randomness is pesky), or not IID.

We therefore recommend using the NIST ea_iid test. When passed, it also directly outputs the minimum entropy. Handy. The test recommends 1,000,000 bytes(samples) but that should be attainable by most DIY entropists. 10,000,000 bytes is indicated for our fast test, but our slow test has no lower size bound.