/sp800_22_tests

A python implementation of the SP800-22 Rev 1a PRNG test suite.

Primary LanguagePythonGNU General Public License v2.0GPL-2.0

sp800_22_tests

A python implementation of the SP800-22 Rev 1a PRNG test suite.

The NIST STS-2.1.2 implementation of the SP800-22 Rev1a tests has some problems. It tends to crash a lot and give the wrong result.

This implementation provides a separate python file, one for each test and a program to read a binary data file and send it to each of the tests. The summary results are output at the end.

In the example below a 1 Mibibit uniform random binary file is generated with djenrandom (https://github.com/dj-on-github/djenrandom) and run through the test.

$ djenrandom -b -k 128 > megabitrand.bin
$ ./sp800_22_tests.py megabitrand.bin
Tests of Distinguishability from Random
TEST: monobit_test
  Ones count   = 523619
  Zeroes count = 524957
  PASS
  P=0.191334792562

[ Lots of per test output ]

SUMMARY
-------
monobit_test                             0.191334792562   PASS
frequency_within_block_test              0.866040491238   PASS
runs_test                                0.45073315513    PASS
longest_run_ones_in_a_block_test         0.464001170438   PASS
binary_matrix_rank_test                  0.405449005115   PASS
dft_test                                 0.852965102607   PASS
non_overlapping_template_matching_test   1.0              PASS
overlapping_template_matching_test       0.91976483935    PASS
maurers_universal_test                   0.998884573989   PASS
linear_complexity_test                   0.0406698787073  PASS
serial_test                              0.895646559993   PASS
approximate_entropy_test                 0.895690030562   PASS
cumulative_sums_test                     0.18603533058    PASS
random_excursion_test                    0.151908516968   PASS
random_excursion_variant_test            0.019160041631   PASS

Next we create a biased data file, where the probability of a 1 is 40% and a 0 is 60% and run it through the test.

$ djenrandom -b -k 128 -m biased --bias=0.4 > biased_megabitrand.bin
$ ./sp800_22_tests.py biased_megabitrand.bin
Tests of Distinguishability from Random
TEST: monobit_test
  Ones count   = 420122
  Zeroes count = 628454
  FAIL

[ Lots of per test output ]

SUMMARY
-------
monobit_test                             0.0                FAIL
frequency_within_block_test              0.0                FAIL
runs_test                                0.0                FAIL
longest_run_ones_in_a_block_test         1.81518103863e-81  FAIL
binary_matrix_rank_test                  0.22156738316      PASS
dft_test                                 3.56787241447e-17  FAIL
non_overlapping_template_matching_test   0.759928185368     PASS
overlapping_template_matching_test       5.31335556946e-91  FAIL
maurers_universal_test                   0.910613044038     PASS
linear_complexity_test                   0.317575269575     PASS
serial_test                              0.0                FAIL
approximate_entropy_test                 0.0                FAIL
cumulative_sums_test                     0.0                FAIL
random_excursion_test                    9.15178471457e-06  FAIL
random_excursion_variant_test            0.121267812518     PASS

Next we create some serially correlated data and run it through the tests.

$ djenrandom -b -k 128 -m correlated --correlation=-0.2 > correlated_megrandom.bin
$ ./sp800_22_tests.py correlated_megabitrand.bin
Tests of Distinguishability from Random
TEST: monobit_test
  Ones count   = 524242
  Zeroes count = 524334
  PASS
  P=0.928411381275

[ Lots of per test output ]

SUMMARY
-------
monobit_test                             0.928411381275     PASS
frequency_within_block_test              0.99598493834      PASS
runs_test                                0.0                FAIL
longest_run_ones_in_a_block_test         3.45886379519e-81  FAIL
binary_matrix_rank_test                  0.379259346315     PASS
dft_test                                 8.67506291511e-16  FAIL
non_overlapping_template_matching_test   0.999999863695     PASS
overlapping_template_matching_test       1.1953875512e-90   FAIL
maurers_universal_test                   0.923207164612     PASS
linear_complexity_test                   0.47696777353      PASS
serial_test                              0.0                FAIL
approximate_entropy_test                 0.0                FAIL
cumulative_sums_test                     0.853890590584     PASS
random_excursion_test                    7.63411305092e-09  FAIL
random_excursion_variant_test            0.0662033926665    PASS

Next we create some data with both bias and serial correlation from an Ornstein–Uhlenbeck process and run it through the tool

$ djenrandom -b -k 128 -m sums -l 0.2 -r 0.3 > sums_megrandom.bin
$ ./sp800_22_tests.py sums_megrandom.bin
Tests of Distinguishability from Random
TEST: monobit_test
  Ones count   = 419429
  Zeroes count = 629147
  FAIL
  P=0.0

[ Lots of per test output ]

SUMMARY
-------
monobit_test                             0.0                FAIL
frequency_within_block_test              0.0                FAIL
runs_test                                0.0                FAIL
longest_run_ones_in_a_block_test         2.32811341972e-159 FAIL
binary_matrix_rank_test                  0.702984863193     PASS
dft_test                                 7.91957168353e-06  FAIL
non_overlapping_template_matching_test   0.949847572332     PASS
overlapping_template_matching_test       1.16046343793e-137 FAIL
maurers_universal_test                   0.90191137295      PASS
linear_complexity_test                   0.16038668337      PASS
serial_test                              0.0                FAIL
approximate_entropy_test                 0.0                FAIL
cumulative_sums_test                     0.0                FAIL
random_excursion_test                    2.20517667303e-09  FAIL
random_excursion_variant_test            0.0                FAIL