Products Cryptographic assurance
Entropy validation
Entropy source validation
Evidence that a noise source is as random as you claim.
Cryptographic modules need a certified entropy source, and NIST SP 800-90B defines how to test one. GraphAtlas runs the estimators and the continuous health tests on raw samples, derives the cutoffs from the claimed entropy, and writes the evidence package a validation lab expects.
Try the calculation Request a walkthrough
- Verification
- 7 statements. 2 proved, 0 certified, 5 tested.
- Regime
- NIST SP 800-90B
- Set by
-
- National Institute of Standards and Technology
- Built for
-
- Hardware security engineers
- Cryptographic module vendors
- Validation laboratories
- Version
- 2.1
Try it
Run it on sample data
Say how much entropy the maker claims and how much the source really has. Then freeze it, or let it weaken, and see which test notices and when.
Fig. 1 Health tests and entropy estimate for an illustrative noise source, 8,192 samples of eight bits
Verifying receipt
The claim
Both cutoffs follow from the claim and from an alarm rate of one in 2²⁰ samples, the rate that SP 800-90B uses in its own calculations.
The source
The most common value, 0x5A, makes up 0.39% of the samples.
The source behaves the same way for the whole stream.
Health tests
Pass
Neither test fails in 8,192 samples. The longest run is 2 against a cutoff of 5. The busiest window is 6 against 25.
Entropy estimate
6.99 bits
Above the claim of 6.0 bits. These samples are consistent with it.
The windows of the adaptive proportion test
Window 11 of 16 samples 5,121 to 5,632
The first sample is 0x8E. It occurs 6 times in this window, against a cutoff of 25. This is the busiest window.
| Test | Cutoff | Worst seen | Result |
|---|---|---|---|
| Repetition count | 5 | Longest run 2 | Passes |
| Adaptive proportion | 25 | Busiest window 6 | Passes |
- Repetition count
- 1 + ⌈20 ÷ 6⌉ = 5
- Adaptive proportion
- 1 + CRITBINOM(512, 2^−6, 1 − 2^−20) = 25
- Most common value
- 0.574%
- Upper bound, 99%
- 0.789%
- Min-entropy estimate
- 6.986 bits
SP 800-90B asks for a million samples to validate a source. This stream has 8,192, so the bound is wide and the estimate sits below the true entropy even for a fair source.
Inputs and outputs
What goes in. What comes out
The plate runs a slice of the engine. This is the whole shape of it.
What goes in
- Raw samples
- The output of the noise source before any conditioning, in the order it was produced, one number for each sample.
- The claim
- The min-entropy per sample that the maker says the source has. Both cutoffs are set from it.
- The alarm rate
- How often a healthy source may trip a test, as a power of two. The default is one in 2²⁰ samples.
What comes out
- Cutoffs
- The repetition count cutoff and the adaptive proportion cutoff, as whole numbers, each with the rule that gave it.
- Test results
- The longest run, the count in every window, and the sample at which each test first fails, if it does.
- Entropy estimate
- The most common value estimate of min-entropy, with the upper bound on the share of the most common value that it comes from.
- Alarm
- The first sample at which a module would stop its output.
- Receipt
- A hash of the samples, the claim, the rule parameters and every result. Anyone can recompute it.
What the plate covers
In the plate above
- Both approved continuous health tests, with cutoffs set from the claim.
- The count in every window of the adaptive proportion test, and any window as a plot of its samples.
- The most common value estimate from the same samples.
- A source with less entropy than claimed, one that freezes and one that weakens.
In the licensed engine, not the plate
- The other estimators of section 6.3, the restart tests and the IID track.
- An estimator that looks at order. A counter that steps through every byte in turn passes both health tests and scores more than seven bits on the estimate, so a pass in the plate is not a proof of entropy.
- The conditioning component and its entropy accounting.
- A million samples. The plate runs 8,192.
- A real noise source. The samples here are simulated.
- Later revisions of the publication.
Clause map
Every rule has an address
Each row names the clause, the function that carries it and the statements that check it. A test opens each file and confirms the function exists.
| Reference | Rule | Carried by | Checked by |
|---|---|---|---|
| Section 4.3 | A module that fails a health test must tell the application, and for a persistent failure it must stop its output. A run reports the first sample at which that would happen. | health src/ | Tested EN-06 |
| Section 4.4.1 | The repetition count cutoff is one more than the alarm exponent divided by the claimed entropy, rounded up. | rct src/ | Proved EN-01 Proved EN-02 |
| Section 4.4.1 | The repetition count test fails when a sample repeats the cutoff number of times in a row. | repetition src/ | Tested EN-07 |
| Section 4.4.2 and Table 2 | The adaptive proportion cutoff is 1 + CRITBINOM(W, 2^−H, 1 − α). The window is 512 samples, or 1,024 for a binary source. | apt src/ | Tested EN-03 |
| Section 4.4.2 | In each window the test counts how often the first sample occurs, itself included, and fails when the count reaches the cutoff. | adaptive src/ | Tested EN-05 |
| Section 6.3.1 | The most common value estimate is minus the base 2 logarithm of an upper bound, at 99 per cent, on the share of the most common value. | most src/ | Tested EN-04 |
Verification
What we claim, and how it is checked
Every statement is registered, and each says which level of assurance it has earned. The ladder is explained on the verification page.
Proved
True for every input.
- EN-01
The repetition count cutoff is the smallest integer C for which H times (C − 1) reaches the false positive exponent.
2 checks, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 2 broken variants are refuted. proofs/smt2/EN-01.smt2
- EN-02
The repetition count cutoff never rises when the claimed min-entropy rises.
1 check, decided by Z3 5.3.3.0 (WebAssembly) and rerun from the emitted file by Z3 5.3.3 (native) and cvc5 1.4.2 (native, nl-cov). 1 broken variant is refuted. proofs/smt2/EN-02.smt2
Tested
True on every input we tried.
- EN-03
The adaptive proportion cutoffs reproduce every entry of Table 2 in SP 800-90B. They match exact big integer arithmetic for whole bit claims of one to eight bits, except at an exact tie with the false positive rate, where rounding can put a cutoff one above.
tests/kernel/entropy.test.ts
- EN-04
The most common value estimate reproduces the worked example in SP 800-90B section 6.3.1 and matches the closed form for a biased stream.
tests/kernel/entropy.test.ts
- EN-05
Each adaptive proportion window counts its first sample as often as it occurs in the window, and the test fails at the first sample that brings a window to the cutoff.
tests/kernel/entropy.test.ts
Show the other 2 Show fewer
- EN-06
A health run reports what each test and the estimate report on their own, and puts its alarm at the earlier of the two failures.
tests/kernel/entropy.test.ts
- EN-07
The repetition count test fails at the sample that completes a run of the cutoff length and never when every run is shorter, and it reports where the longest run ended.
tests/kernel/entropy.test.ts
Use it
The same call, anywhere
This sample is written from the input the plate starts with, so the code and the numbers cannot drift apart.
import { entropyReceiptPayload, healthRun } from '@graphatlas/kernel/entropy';
import { receipt } from '@graphatlas/kernel/receipt';
import { readFileSync } from 'node:fs';
// One byte for each sample, as the noise source produced them, before any conditioning.
const samples = new Uint8Array(readFileSync('raw-samples.bin'));
// The claim is 6 bits a sample. The alarm rate is one in 2^20, with windows of 512.
const run = healthRun(samples, 6);
const hash = await receipt(entropyReceiptPayload(samples, run)); const out = {
rctCutoff: 5,
aptCutoff: 25,
longestRun: 2,
busiestWindow: 6,
alarm: null,
minEntropy: 6.9863,
receipt: '511de476dfbeb7c5a037f306c555112f45b081181401921a8d87f3df09544b5c',
}; The call and the numbers come from the engine that built this page, run on the same input as the plate above. The numbers are for the 8,192 bytes in the plate. A file of your own gives its own. Values are rounded to four places for display. The receipt hashes the unrounded numbers.
Runs on
- Browser
- Edge
- Node.js
- Python
- JVM
- .NET
- Excel
- Command line
- Container
Green surfaces are measured on every build of this site. Each must return the same receipt, bit for bit. The others are packaged targets that the build does not measure. How the platform works
Changes
When the rule moves, so does the engine
Publications that touch this regime, and the release that answered each.
-
Draft revision of SP 800-90B on restart tests and conditioning components
Tracking. No release yet