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

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
The three instruments of the health tests on an example noise source: the longest run, the count in each window and the min-entropyOn 8,192 samples of an example source, the longest run of one value is 2 against a cutoff of 5. The first value of each of 16 windows of 512 samples appears at most 6 times in its window against a cutoff of 25. The most common value estimate gives 6.99 bits of min-entropy in a sample of 8 bits, against a claim of 6. A tag says that the parameters are prescribed.REPETITION COUNTLONGEST RUN 2 OF 512345ADAPTIVE PROPORTIONHIGHEST 6 OF 25CUTOFF 2516 WINDOWS OF 512MIN-ENTROPY PER SAMPLEOF 8 BITSCLAIMED6ESTIMATED6.9902468PRESCRIBEDENGINEENTROPY VALIDATION V2.1SET BYNISTDATASAMPLERECEIPT511de476 The three instruments of the health tests on an example noise source: the longest run, the count in each window and the min-entropyOn 8,192 samples of an example source, the longest run of one value is 2 against a cutoff of 5. The first value of each of 16 windows of 512 samples appears at most 6 times in its window against a cutoff of 25. The most common value estimate gives 6.99 bits of min-entropy in a sample of 8 bits, against a claim of 6. A tag says that the parameters are prescribed.REPETITIONLONGEST RUN 2 OF 512345PROPORTIONHIGHEST 6 OF 25CUTOFF 2516 WINDOWS OF 512MIN-ENTROPYOF 8 BITSCLAIMED6ESTIMATED6.9902468PRESCRIBEDENGINEV2.1DATASAMPLERECEIPT511de476

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

bits a sample
Both cutoffs come from this number.

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

bits a sample
Eight bits is a fair byte, with every value equally likely. Less means one value comes up more often than the rest.

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

010203012345678910111213141516cutoff 25
Each bar is one window of 512 samples. Its height is how many times the first value of the window occurs in it. Select a window to see its samples.

Window 11 of 16 samples 5,121 to 5,632

01282555,1215,632
Each dot is one sample, in the order produced. Height is its value from 0 to 255. Same value as the first sample

The first sample is 0x8E. It occurs 6 times in this window, against a cutoff of 25. This is the busiest window.

The two continuous health tests, their cutoffs and what they found
TestCutoffWorst seenResult
Repetition count5Longest run 2Passes
Adaptive proportion25Busiest window 6Passes
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.

Receipt511de476 dfbeb7c5 … 09544b5c

Change the source. The engine runs in this page and nothing leaves it.

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.

Rules of the regulation, the code that carries each one and the statements that check it
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. healthRun src/kernel/entropy.ts 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. rctCutoff src/kernel/entropy.ts 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. repetitionCountTest src/kernel/entropy.ts 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. aptCutoff src/kernel/entropy.ts 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. adaptiveProportionWindows src/kernel/entropy.ts 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. mostCommonValue src/kernel/entropy.ts 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

Read the verification statement

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.

Call
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));
Returns
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.

  1. NIST Consultation

    Draft revision of SP 800-90B on restart tests and conditioning components

    Tracking. No release yet

Open the full feed

The next step

Bring us
one book

A scoping call, a sample book and a parallel run on your data. Most teams have the first reconciled number inside two weeks, and a receipt for it on the day.

Book a demo Work out a price