Live · Entropy Tester

Don't just build a good entropy source. Keep checking it.

Entropy Tester runs the statistical tests NIST SP 800-90B specifies — continuously, across your entire server fleet — so a source that was valid at certification time doesn't quietly degrade afterward. Each host runs the assessment against a live sample, signs the result, and ships it to a central dashboard.

How SP 800-90B Evaluates a Source

Two stages: pick the right analytical track, then estimate and continuously verify.

Min-entropy — not Shannon entropy — is the metric that matters cryptographically, because it bounds an adversary's best case for guessing the single most likely output: H(X) = −log2(maxx Pr[X=x]).

Stage 1

A large sample is run through the IID permutation test. If reordering the sample doesn't change how its test statistics behave, the source is treated as independent and identically distributed, and a single simple estimator suffices. If any statistic shows the original ordering to be a significant outlier, the source is treated as non-IID, and a much larger battery of ten min-entropy estimators is applied instead — since a non-IID source could be weak in any of several unrelated ways.

Stage 2

Min-entropy is estimated for whichever track applies, then validated operationally with two online health tests that run continuously against live output, and optionally a restart test that checks the estimate isn't an artifact of one long run.

Section 4.4 · Online Health Tests

Catching a catastrophic failure in a source that was already validated.

These two tests run continuously against live output — not once, offline — designed to catch a source that's become stuck, biased, or otherwise degraded after certification.

Repetition Count Test cutoff:   C = 1 + ⌈ −log2(α) / H ⌉
Tracks the length of the current run of identical values; a run reaching C is treated as evidence of failure. Implemented exactly as specified.
Adaptive Proportion Test cutoff:   smallest C such that Pr[count ≤ C] ≥ 1 − α,   p = 2−H
Unlike RCT, the spec gives no closed form — the original codebase approximated the cutoff as a fixed ~0.5×window size, independent of the assumed entropy H. This implementation replaces that with the actual binomial-tail computation via a numerically stable recurrence, so the cutoff correctly tightens as H increases and loosens as H decreases.
Section 5.1 · The IID Permutation Test

Does the order of this sample carry information — or would any shuffle look just as plausible?

If reordering doesn't change how a statistic behaves, the source's structure — if any — isn't order-dependent, which is consistent with IID sampling.

01

Compute T₀ = T(original sample) for each test statistic.

02

Generate N independent random shuffles and compute Tᵢ for each.

03

Count how many shuffled values fall above and below the original.

04

Reject IID for that statistic if the original sits in either extreme tail of the shuffled distribution. The source is judged IID only if every tested statistic passes.

The full spec defines eleven statistics; this implementation covers six, chosen to span the categories of structure the full set is designed to catch.

StatisticWhat It Catches
ExcursionLong-range drift away from the sample mean
Number of directional runsSerial correlation — runs of increases/decreases
Longest directional runStrong local trends
Number of increases/decreasesAsymmetry between rising and falling steps
Average collision distanceLocal repetition, low local diversity
Mean log₂ gap (compression proxy)Predictability from prior occurrences

A defect found and fixed during implementation

An early version of the compression statistic used post-zlib-compression size. For genuinely random data, that statistic is essentially invariant under permutation — with no repeated substrings to exploit, compressed size depends only on input length, not order. Every shuffle produced the same value as the original, collapsing the test's discriminating power to zero and causing it to reject the IID hypothesis on every run, including genuinely IID input.

It was replaced with a statistic explicitly built around position — the mean of log₂(gap since this value was last seen) — which is directly sensitive to the order permutation destroys.

The spec's extreme-tail threshold of 5 is calibrated for exactly N = 10,000 permutations. This implementation defaults to N = 1,000 for practical per-host runtime, so the threshold is scaled proportionally — max(1, round(5 × N / 10,000)) — keeping the per-statistic false-rejection rate roughly constant as N varies.

Section 6.3 · Non-IID Min-Entropy Estimators

Ten estimators. The minimum across all of them is the assessment.

When the IID test rejects, the source might be weak in any of several unrelated ways — so all ten run, and a source is only as strong as its single worst property. Every estimator uses the same confidence-bound pattern: an observed probability estimate, then a one-sided 99% upper confidence bound, so sampling noise can never make a source look better than it is.

EstimatorWhat It Measures
Most Common ValueUpper bound on the single most frequent symbol's probability
CollisionMean samples before a value repeats, inverted via the birthday-problem approximation
MarkovHighest-probability path through a first-order transition matrix — short-range serial correlation
CompressionMaurer's universal statistical test — short, predictable gaps indicate low entropy
t-Tuple / LRSLargest repeating tuple length / longest repeated substring anywhere in the sample
MultiMCW / Lag / MultiMMC / LZ78Y PredictionFour predictors — trailing-window mode, best-lag periodicity, adaptive Markov, LZ78-style dictionary

The four prediction-based estimators each produce a global bound from overall accuracy and a local bound from the single longest correct-guess streak r. The reference algorithm solves the local bound numerically; this implementation uses the closed-form approximation plocal ≈ 2−1/r — the same starting point the reference tool itself uses before refinement, within a fraction of a bit for realistic sample sizes.

Section 3.1.4.3 · Restart Test

Making sure the estimate isn't an artifact of one long run.

Many independent short sequences are arranged into a matrix — restarts as rows, position within a restart as columns — and RCT/APT are re-applied row-wise and column-wise against the assessed min-entropy. An assessment is judged inconsistent if the observed failure rate is far above what the assumed entropy predicts, with a 1% failure-rate tolerance. The full spec calls for ≥1,000 restarts of ≥1,000 samples each; smaller matrices are accepted and reported explicitly as below full statistical power, since a directional signal is still useful for routine monitoring.

Validation

Tested against both a clean source and a deliberately broken one.

0%

False-rejection rate across ten independent 2,048-byte os.urandom() samples at N=2,000 permutations, after the compression-statistic fix and threshold scaling — down from a ~37.5% false-rejection rate on the same data beforehand.

~0.03

Bits/symbol assigned to a synthetic "stuck" source (one symbol heavily overrepresented in a 4-symbol set) — correctly rejected by the IID test, correctly scored near-zero by the Most Common Value and Markov estimators, correctly triggering health-check alerts end to end.

Known Limitations

What this trades off to be genuinely useful for continuous fleet monitoring.

Coverage trade-offs

  • Partial IID statistic coverageSix of the spec's eleven Section 5.1 statistics are implemented. Periodicity and covariance at lags 1/2/8/16/32, and the companion collision-test statistics, are not yet covered.
  • Reduced default permutation/restart counts1,000 permutations and far fewer than 1,000 restarts by default, for practical per-host runtime in an agent that runs repeatedly — both configurable up to the spec's full 10,000/1,000 scale at the cost of runtime.

Approximation trade-offs

  • Closed-form approximations in three estimatorsThe Collision estimator's birthday-problem inversion and the four prediction estimators' local bound use standard closed-form approximations rather than the reference tool's exact numerical root-finding.
  • Not a certified validation toolSuitable for continuous operational monitoring — catching regressions, misconfigurations, and outright failures over time — but not a substitute for a CMVP-recognized entropy source validation using NIST's reference implementation for compliance purposes.
Where It Fits

Entropy Source builds the noise source. Entropy Tester watches it stay honest.

Certification is a snapshot. Fleets change every day.

Entropy Source is the noise source itself — engineered toward NIST SP 800-90B conformance and an issued ESV certificate, a one-time (if recurring) certification event.

Entropy Tester is what runs after that certificate is issued — and works against any entropy source, not just ours. Virtualization artifacts, hardware faults, and configuration drift can degrade a source long after it passed validation, on some subset of hosts and not others. Continuous testing is how you'd actually find that, instead of assuming the certificate still describes reality a year later.

Get Started

Certification tells you a source was good once. This tells you it still is.

Fleet-monitoring integration details, the signed-report format, and the dashboard aggregation layer are documented separately — ask us for the full methodology report.