5 #include "sw/device/lib/testing/randomness_quality.h"
7 #include "sw/device/lib/base/status.h"
8 #include "sw/device/lib/testing/test_framework/check.h"
18 kMonobitFivePercentThresholdNumerator = 38415,
19 kMonobitFivePercentThresholdDenominator = 10000,
27 kMonobitOnePercentThresholdNumerator = 66349,
28 kMonobitOnePercentThresholdDenominator = 10000,
38 static uint64_t diff_squared(uint64_t a, uint64_t b) {
40 return (b - a) * (b - a);
42 return (a - b) * (a - b);
45 status_t randomness_quality_monobit_test(
46 uint8_t *data,
size_t len, randomness_quality_significance_t significance) {
48 TRY_CHECK(len <= UINT32_MAX);
51 uint32_t num_ones = 0;
52 uint32_t num_zeroes = 0;
53 for (
size_t i = 0; i < len; i++) {
54 uint8_t
byte = data[i];
55 for (
size_t j = 0; j < 8; j++) {
57 num_zeroes += (
byte ^ 1) & 1;
63 uint64_t numerator = diff_squared(num_ones, num_zeroes);
64 uint64_t denominator = len * 8;
67 uint64_t threshold_numerator = 0;
68 uint64_t threshold_denominator = 1;
69 switch (significance) {
70 case kRandomnessQualitySignificanceFivePercent: {
71 threshold_numerator = kMonobitFivePercentThresholdNumerator;
72 threshold_denominator = kMonobitFivePercentThresholdDenominator;
75 case kRandomnessQualitySignificanceOnePercent: {
76 threshold_numerator = kMonobitOnePercentThresholdNumerator;
77 threshold_denominator = kMonobitOnePercentThresholdDenominator;
81 return INVALID_ARGUMENT();
85 uint64_t lhs = (numerator * threshold_denominator);
86 uint64_t rhs = (threshold_numerator * denominator);
87 TRY_CHECK(lhs <= rhs);