35static void approx(
const char* label,
double got,
double want,
double tol) {
36 if (fabs(got - want) > tol) {
37 n_log(
LOG_ERR,
"%s: got %.4f, expected %.4f", label, got, want);
43 unsigned char uni[256];
44 unsigned char same[64];
47 unsigned char half[8];
48 unsigned char two[4] = {
'A',
'B',
'A',
'B'};
53 for (i = 0; i < 256; i++)
54 uni[i] = (
unsigned char)i;
60 memset(same,
'A',
sizeof(same));
68 memset(z, 0x00,
sizeof(z));
69 memset(f, 0xFF,
sizeof(f));
70 memset(half, 0x0F,
sizeof(half));
89 static unsigned char toks[64][4];
90 const unsigned char* ptrs[64];
94 unsigned int seed = 12345u;
95 for (t = 0; t < 64; t++) {
96 seed = seed * 1103515245u + 12345u;
97 toks[t][0] = (
unsigned char)(seed >> 16);
98 seed = seed * 1103515245u + 12345u;
99 toks[t][1] = (
unsigned char)(seed >> 16);
101 toks[t][3] = (
unsigned char)((t % 2) ?
'a' :
'b');
110 if (pos[2].distinct != 1) {
111 n_log(
LOG_ERR,
"position 2 should have a single value, got %zu", pos[2].distinct);
114 approx(
"stuck position entropy", pos[2].shannon, 0.0, 0.0001);
116 if (pos[3].distinct != 2) {
117 n_log(
LOG_ERR,
"position 3 should have two values, got %zu", pos[3].distinct);
120 approx(
"two-value position entropy", pos[3].shannon, 1.0, 0.0001);
122 if (pos[0].distinct < 30 || pos[0].shannon < 4.0) {
123 n_log(
LOG_ERR,
"position 0 should look random: %zu values, %.2f bits", pos[0].distinct, pos[0].shannon);
134 if (bits[16].ones != 0 || bits[17].ones != 64) {
135 n_log(
LOG_ERR,
"stuck bits misreported: %zu / %zu", bits[16].ones, bits[17].ones);
138 if (bits[17].p_value > 0.01) {
139 n_log(
LOG_ERR,
"a stuck bit should be significant, p=%.4f", bits[17].p_value);
149 if (p_mid < 0.3 || p_mid > 0.7) {
150 n_log(
LOG_ERR,
"chi p(10,10) should be mid-range, got %.4f", p_mid);
154 n_log(
LOG_ERR,
"chi p(200,10) should be tiny, got %.6f", p_big);
167 n_log(
LOG_ERR,
"runs test should reject a blocky stream, p=%.4f", p_runs);
175 n_log(
LOG_ERR,
"all-ones longest run should span the sample");
184 const unsigned char* one[1];
static void approx(const char *label, double got, double want, double tol)
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
#define LOG_ERR
error conditions
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL ).
#define LOG_NOTICE
normal but significant condition
size_t n_entropy_positions(const unsigned char *const *samples, size_t count, size_t sample_len, N_ENTROPY_POS *out, size_t max_out)
Per-POSITION analysis of a set of equal-length samples.
size_t n_entropy_bits(const unsigned char *const *samples, size_t count, size_t sample_len, N_ENTROPY_BIT *out, size_t max_out)
Per-BIT analysis of a set of equal-length samples.
size_t n_entropy_longest_run(const unsigned char *data, size_t len)
Length of the longest run of identical bits in the sample.
double n_entropy_shannon(const unsigned char *data, size_t len)
Shannon entropy of the byte sample, in bits per byte (0.0 .
double n_entropy_monobit(const unsigned char *data, size_t len)
Fraction of set bits in the sample (0.0 .
double n_entropy_chi_square(const unsigned char *data, size_t len)
Chi-square statistic of the byte histogram against a uniform distribution over 256 values.
double n_entropy_chi_square_p(double chi, size_t df)
Upper-tail p-value of a chi-square statistic (Wilson-Hilferty).
double n_entropy_runs_p(const unsigned char *data, size_t len)
Runs test over the sample's bit stream (NIST SP 800-22 style).
per-bit statistics across a set of equal-length samples
per-position statistics across a set of equal-length samples
Randomness/entropy metrics for byte samples (token-randomness analysis).