I always wanted to build a true random number generator, tried a few approaches over the years, and never got far. This time I got somewhere — and then spent considerably longer *measuring* the thing than building it.

The noise source is eight ring oscillators, each three inverters in a loop. A ring like that free-runs at whatever its gate delays dictate (90–130 MHz here) and its phase wanders unpredictably from thermal and flicker noise in the transistors. That wander is the entropy. Everything else — latching, health checks, SHA-256 — is just packaging.

Two 74HC174 latches capture all eight rings simultaneously, an STM32G431 reads the whole sample in one GPIO read, and the output goes out over USB CDC as a plain serial port. Single-character commands change the sampling rate, compression, and which rings are enabled, and print a status report.

Where it ended up: 3.12 bit of measured min-entropy per 8-bit sample at 300 kHz, which is 937 kbit/s of entropy, delivered as 50 kB/s of SHA-256 output with a 2.34× margin. Rev-1 (six rings) managed 8.3 kB/s at 1.13×, so this is about six times better — and the reason isn't the extra two rings, it's better supply filtering and one inverter package per ring instead of two rings sharing a die.

Two things I did not expect.

Three ring pairs turned out to be correlated, and it looked like a PCB layout problem — until the two *closest* pairs on the board turned out to be the uncoupled ones. The culprit was adjacent bit positions inside the latch chip. Not distance. Silicon. It costs 0.38% of the entropy budget, so it stays.

Then someone suggested a particular four-ring subset removed almost all the crosstalk, and the numbers agreed beautifully — cleanest of all 70 subsets. So I split the capture in half, picked the winner on one half, and checked its rank on the other. Rank 8. Then 5, then 4. The "best subset" was just whichever one won that particular coin toss. There's now a script whose only job is to catch that mistake.

What's in the repo: KiCad schematic and PCB, firmware, prebuilt .bin so you can flash it without a toolchain, and the host tools I used for all the measurements — a rate sweep, crosstalk analysis, and the NIST SP 800-90B assessments. A full sweep takes about fifteen minutes with the board plugged in, so every number here is reproducible.

What it isn't: certified. One board, room temperature, no restart tests. The READMEs list exactly which gaps would need closing, because I'd rather say that than pretend otherwise.

I'm a programmer, not an electronics engineer, so the PCB is probably far from optimal. Pull requests and criticism both welcome.