Commit 13a6d71e authored by Evan Hunt's avatar Evan Hunt
Browse files

convert random_test

(cherry picked from commit 6ad7acd7)
parent 15f7486d
......@@ -19,7 +19,7 @@ tap_test_program{name='pool_test'}
atf_test_program{name='print_test'}
tap_test_program{name='queue_test'}
tap_test_program{name='radix_test'}
atf_test_program{name='random_test'}
tap_test_program{name='random_test'}
atf_test_program{name='regex_test'}
tap_test_program{name='result_test'}
tap_test_program{name='safe_test'}
......
......@@ -140,8 +140,9 @@ radix_test@EXEEXT@: radix_test.@O@ isctest.@O@ ${ISCDEPLIBS}
${ISCLIBS} ${LIBS} ${CMOCKA_LIBS}
random_test@EXEEXT@: random_test.@O@ isctest.@O@ ${ISCDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
random_test.@O@ isctest.@O@ ${ISCLIBS} ${LIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${CMOCKA_CFLAGS} \
${LDFLAGS} -o $@ random_test.@O@ isctest.@O@ \
${ISCLIBS} ${LIBS} ${CMOCKA_LIBS}
regex_test@EXEEXT@: regex_test.@O@ ${ISCDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
......
......@@ -18,20 +18,28 @@
#include <config.h>
#if HAVE_CMOCKA
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <inttypes.h>
#include <math.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <isc/random.h>
#include <isc/result.h>
#define UNIT_TESTING
#include <cmocka.h>
#include <isc/commandline.h>
#include <isc/mem.h>
#include <isc/print.h>
#include <isc/random.h>
#include <isc/result.h>
#include <isc/util.h>
#include <atf-c.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#define REPS 25000
typedef double (pvalue_func_t)(isc_mem_t *mctx,
......@@ -55,6 +63,17 @@ static double biginv = 2.22044604925031308085e-16;
static double igamc(double a, double x);
static double igam(double a, double x);
static bool verbose = false;
typedef enum {
ISC_RANDOM8,
ISC_RANDOM16,
ISC_RANDOM32,
ISC_RANDOM_BYTES,
ISC_RANDOM_UNIFORM,
ISC_NONCE_BYTES
} isc_random_func;
static double
igamc(double a, double x) {
double ans, ax, c, yc, r, t, y, z;
......@@ -68,7 +87,7 @@ igamc(double a, double x) {
ax = a * log(x) - x - lgamma(a);
if (ax < -MAXLOG) {
fprintf(stderr, "igamc: UNDERFLOW, ax=%f\n", ax);
print_error("# igamc: UNDERFLOW, ax=%f\n", ax);
return (0.0);
}
ax = exp(ax);
......@@ -125,8 +144,8 @@ igam(double a, double x) {
/* Compute x**a * exp(-x) / md_gamma(a) */
ax = a * log(x) - x - lgamma(a);
if( ax < -MAXLOG ) {
fprintf(stderr, "igam: UNDERFLOW, ax=%f\n", ax);
if (ax < -MAXLOG ) {
print_error("# igam: UNDERFLOW, ax=%f\n", ax);
return (0.0);
}
ax = exp(ax);
......@@ -270,11 +289,11 @@ random_test(pvalue_func_t *func, bool word_sized) {
tables_init();
result = isc_mem_create(0, 0, &mctx);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
rng = NULL;
result = isc_rng_create(mctx, NULL, &rng);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
assert_int_equal(result, ISC_R_SUCCESS);
m = 1000;
passed = 0;
......@@ -298,8 +317,7 @@ random_test(pvalue_func_t *func, bool word_sized) {
passed++;
}
ATF_REQUIRE(p_value >= 0.0);
ATF_REQUIRE(p_value <= 1.0);
assert_in_range(p_value, 0.0, 1.0);
i = (int) floor(p_value * 10);
histogram[i]++;
......@@ -317,13 +335,14 @@ random_test(pvalue_func_t *func, bool word_sized) {
lower_confidence = p_hat - (3.0 * sqrt((p_hat * (1.0 - p_hat)) / m));
higher_confidence = p_hat + (3.0 * sqrt((p_hat * (1.0 - p_hat)) / m));
/* Debug message, not displayed when running via atf-run */
printf("passed=%u/1000\n", passed);
printf("higher_confidence=%f, lower_confidence=%f, proportion=%f\n",
higher_confidence, lower_confidence, proportion);
if (verbose) {
print_message("# passed=%u/1000\n", passed);
print_message("# higher_confidence=%f, lower_confidence=%f, "
"proportion=%f\n",
higher_confidence, lower_confidence, proportion);
}
ATF_REQUIRE(proportion >= lower_confidence);
ATF_REQUIRE(proportion <= higher_confidence);
assert_in_range(proportion, lower_confidence, higher_confidence);
/*
* Check uniform distribution of p-values (see section 4.2.2 in
......@@ -337,15 +356,20 @@ random_test(pvalue_func_t *func, bool word_sized) {
histogram[10] = 0;
/* Pre-requisite that at least 55 sequences are processed. */
ATF_REQUIRE(m >= 55);
assert_true(m >= 55);
if (verbose) {
print_message("# ");
}
chi_square = 0.0;
for (j = 0; j < 10; j++) {
double numer;
double denom;
/* Debug message, not displayed when running via atf-run */
printf("hist%u=%u ", j, histogram[j]);
if (verbose) {
print_message("hist%u=%u ", j, histogram[j]);
}
numer = (histogram[j] - (m / 10.0)) *
(histogram[j] - (m / 10.0));
......@@ -353,11 +377,13 @@ random_test(pvalue_func_t *func, bool word_sized) {
chi_square += numer / denom;
}
printf("\n");
if (verbose) {
print_message("\n");
}
p_value_t = igamc(9 / 2.0, chi_square / 2.0);
ATF_REQUIRE(p_value_t >= 0.0001);
assert_true(p_value_t >= 0.0001);
}
/*
......@@ -381,10 +407,11 @@ monobit(isc_mem_t *mctx, uint16_t *values, size_t length) {
scount += scounts_table[values[i]];
/* Preconditions (section 2.1.7 in NIST SP 800-22) */
ATF_REQUIRE(numbits >= 100);
assert_true(numbits >= 100);
/* Debug message, not displayed when running via atf-run */
printf("numbits=%u, scount=%d\n", numbits, scount);
if (verbose) {
print_message("# numbits=%u, scount=%d\n", numbits, scount);
}
s_obs = abs(scount) / sqrt(numbits);
p_value = erfc(s_obs / sqrt(2.0));
......@@ -419,14 +446,15 @@ runs(isc_mem_t *mctx, uint16_t *values, size_t length) {
for (i = 0; i < REPS; i++)
bcount += bitcounts_table[values[i]];
/* Debug message, not displayed when running via atf-run */
printf("numbits=%u, bcount=%u\n", numbits, bcount);
if (verbose) {
print_message("# numbits=%u, bcount=%u\n", numbits, bcount);
}
pi = (double) bcount / (double) numbits;
tau = 2.0 / sqrt(numbits);
/* Preconditions (section 2.3.7 in NIST SP 800-22) */
ATF_REQUIRE(numbits >= 100);
assert_true(numbits >= 100);
/*
* Pre-condition implied from the monobit test. This can fail
......@@ -487,18 +515,19 @@ blockfrequency(isc_mem_t *mctx, uint16_t *values, size_t length) {
mwords = mbits / 16;
numblocks = numbits / mbits;
/* Debug message, not displayed when running via atf-run */
printf("numblocks=%u\n", numblocks);
if (verbose) {
print_message("# numblocks=%u\n", numblocks);
}
/* Preconditions (section 2.2.7 in NIST SP 800-22) */
ATF_REQUIRE(numbits >= 100);
ATF_REQUIRE(mbits >= 20);
ATF_REQUIRE((double) mbits > (0.01 * numbits));
ATF_REQUIRE(numblocks < 100);
ATF_REQUIRE(numbits >= (mbits * numblocks));
assert_true(numbits >= 100);
assert_true(mbits >= 20);
assert_true((double) mbits > (0.01 * numbits));
assert_true(numblocks < 100);
assert_true(numbits >= (mbits * numblocks));
pi = isc_mem_get(mctx, numblocks * sizeof(double));
ATF_REQUIRE(pi != NULL);
assert_non_null(pi);
for (i = 0; i < numblocks; i++) {
uint32_t j;
......@@ -521,8 +550,9 @@ blockfrequency(isc_mem_t *mctx, uint16_t *values, size_t length) {
isc_mem_put(mctx, pi, numblocks * sizeof(double));
/* Debug message, not displayed when running via atf-run */
printf("chi_square=%f\n", chi_square);
if (verbose) {
print_message("# chi_square=%f\n", chi_square);
}
p_value = igamc(numblocks * 0.5, chi_square * 0.5);
......@@ -557,9 +587,9 @@ binarymatrixrank(isc_mem_t *mctx, uint16_t *values, size_t length) {
numbits = num_matrices * matrix_m * matrix_q;
/* Preconditions (section 2.5.7 in NIST SP 800-22) */
ATF_REQUIRE(matrix_m == 32);
ATF_REQUIRE(matrix_q == 32);
ATF_REQUIRE(numbits >= (38 * matrix_m * matrix_q));
assert_int_equal(matrix_m, 32);
assert_int_equal(matrix_q, 32);
assert_true(numbits >= (38 * matrix_m * matrix_q));
fm_0 = 0;
fm_1 = 0;
......@@ -606,123 +636,123 @@ binarymatrixrank(isc_mem_t *mctx, uint16_t *values, size_t length) {
chi_square = term1 + term2 + term3;
/* Debug message, not displayed when running via atf-run */
printf("fm_0=%u, fm_1=%u, fm_rest=%u, chi_square=%f\n",
fm_0, fm_1, fm_rest, chi_square);
if (verbose) {
print_message("# fm_0=%u, fm_1=%u, fm_rest=%u, chi_square=%f\n",
fm_0, fm_1, fm_rest, chi_square);
}
p_value = exp(-chi_square * 0.5);
return (p_value);
}
ATF_TC(isc_rng_monobit_16);
ATF_TC_HEAD(isc_rng_monobit_16, tc) {
atf_tc_set_md_var(tc, "descr", "Monobit test for the RNG");
}
ATF_TC_BODY(isc_rng_monobit_16, tc) {
UNUSED(tc);
/* Monobit test for the RNG */
static void
isc_rng_monobit_16(void **state) {
UNUSED(state);
random_test(monobit, true);
}
ATF_TC(isc_rng_runs_16);
ATF_TC_HEAD(isc_rng_runs_16, tc) {
atf_tc_set_md_var(tc, "descr", "Runs test for the RNG");
}
ATF_TC_BODY(isc_rng_runs_16, tc) {
UNUSED(tc);
/* Runs test for the RNG */
static void
isc_rng_runs_16(void **state) {
UNUSED(state);
random_test(runs, true);
}
ATF_TC(isc_rng_blockfrequency_16);
ATF_TC_HEAD(isc_rng_blockfrequency_16, tc) {
atf_tc_set_md_var(tc, "descr", "Block frequency test for the RNG");
}
ATF_TC_BODY(isc_rng_blockfrequency_16, tc) {
UNUSED(tc);
/* Block frequency test for the RNG */
static void
isc_rng_blockfrequency_16(void **state) {
UNUSED(state);
random_test(blockfrequency, true);
}
ATF_TC(isc_rng_binarymatrixrank_16);
ATF_TC_HEAD(isc_rng_binarymatrixrank_16, tc) {
atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RNG");
}
/*
* Binary matrix rank test for the RNG.
* This is the binary matrix rank test taken from the NIST SP 800-22 RNG
* test suite.
*/
ATF_TC_BODY(isc_rng_binarymatrixrank_16, tc) {
UNUSED(tc);
static void
isc_rng_binarymatrixrank_16(void **state) {
UNUSED(state);
random_test(binarymatrixrank, true);
}
ATF_TC(isc_rng_monobit_bytes);
ATF_TC_HEAD(isc_rng_monobit_bytes, tc) {
atf_tc_set_md_var(tc, "descr", "Monobit test for the RNG");
}
ATF_TC_BODY(isc_rng_monobit_bytes, tc) {
UNUSED(tc);
/* Monobit test for the RNG */
static void
isc_rng_monobit_bytes(void **state) {
UNUSED(state);
random_test(monobit, false);
}
ATF_TC(isc_rng_runs_bytes);
ATF_TC_HEAD(isc_rng_runs_bytes, tc) {
atf_tc_set_md_var(tc, "descr", "Runs test for the RNG");
}
ATF_TC_BODY(isc_rng_runs_bytes, tc) {
UNUSED(tc);
/* Runs test for the RNG */
static void
isc_rng_runs_bytes(void **state) {
UNUSED(state);
random_test(runs, false);
}
ATF_TC(isc_rng_blockfrequency_bytes);
ATF_TC_HEAD(isc_rng_blockfrequency_bytes, tc) {
atf_tc_set_md_var(tc, "descr", "Block frequency test for the RNG");
}
ATF_TC_BODY(isc_rng_blockfrequency_bytes, tc) {
UNUSED(tc);
/* Block frequncy test for the RNG */
static void
isc_rng_blockfrequency_bytes(void **state) {
UNUSED(state);
random_test(blockfrequency, false);
}
ATF_TC(isc_rng_binarymatrixrank_bytes);
ATF_TC_HEAD(isc_rng_binarymatrixrank_bytes, tc) {
atf_tc_set_md_var(tc, "descr", "Binary matrix rank test for the RNG");
}
/*
* Binary matrix rank test for the RNG
* This is the binary matrix rank test taken from the NIST SP 800-22 RNG
* test suite.
*/
ATF_TC_BODY(isc_rng_binarymatrixrank_bytes, tc) {
UNUSED(tc);
static void
isc_rng_binarymatrixrank_bytes(void **state) {
UNUSED(state);
random_test(binarymatrixrank, false);
}
/*
* Main
*/
ATF_TP_ADD_TCS(tp) {
ATF_TP_ADD_TC(tp, isc_rng_monobit_16);
ATF_TP_ADD_TC(tp, isc_rng_runs_16);
ATF_TP_ADD_TC(tp, isc_rng_blockfrequency_16);
ATF_TP_ADD_TC(tp, isc_rng_binarymatrixrank_16);
ATF_TP_ADD_TC(tp, isc_rng_monobit_bytes);
ATF_TP_ADD_TC(tp, isc_rng_runs_bytes);
ATF_TP_ADD_TC(tp, isc_rng_blockfrequency_bytes);
ATF_TP_ADD_TC(tp, isc_rng_binarymatrixrank_bytes);
return (atf_no_error());
int
main(int argc, char **argv) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(isc_rng_monobit_16),
cmocka_unit_test(isc_rng_runs_16),
cmocka_unit_test(isc_rng_blockfrequency_16),
cmocka_unit_test(isc_rng_binarymatrixrank_16),
cmocka_unit_test(isc_rng_monobit_bytes),
cmocka_unit_test(isc_rng_runs_bytes),
cmocka_unit_test(isc_rng_blockfrequency_bytes),
cmocka_unit_test(isc_rng_binarymatrixrank_bytes),
};
int c;
while ((c = isc_commandline_parse(argc, argv, "v")) != -1) {
switch (c) {
case 'v':
verbose = true;
break;
default:
break;
}
}
return (cmocka_run_group_tests(tests, NULL, NULL));
}
#else /* HAVE_CMOCKA */
#include <stdio.h>
int
main(void) {
printf("1..0 # Skipped: cmocka not available\n");
return (0);
}
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment