Part II ยท Entropy Chapter 6

Where Randomness Comes From

โ–ถ The Story

Here is a question that sounds like a riddle. Your laptop is a deterministic machine โ€” the same program run twice does the same thing twice; that is the entire point of a computer. Yet tonight, when you generate a Bitcoin wallet, that machine will produce a number no one in the universe can predict. Where does a perfectly predictable machine find unpredictability?

The short answer: it doesn't find it inside the program โ€” it collects it from the world. This chapter follows the supply chain of randomness: the physical sources, the operating system's reservoir, the pretenders (software that stretches randomness without creating any), and the handful of rules that keep you on the right side of the difference. This is where Chapter 2's promise โ€” equally likely โ€” finally gets cashed in.

6.1The Physical Question

Every tool so far assumed a fair process: fair coins, fair dice, a thief facing the full space. Chapters 4 and 5 then priced unfairness. But they left a hole in the argument: what makes a process fair? Not the arithmetic โ€” arithmetic only describes the raffle once the tickets are mixed. The mixing is physical.

That reframing matters because it relocates the trust. When you generate a key, you are not trusting mathematics; you are trusting a physical process to be unpredictable and a chain of software to deliver that unpredictability intact. Meet the chain, link by link.

6.2True Randomness

The oldest fair process is the die. A properly thrown die lands each face with chance \(1/6\), not because anyone proved it but because the tumbling is chaotic: tiny differences in the throw โ€” a hair's difference in angle, a whisper of air โ€” grow into different faces. The unpredictability is manufactured by physics, fresh, with every throw.

Dice are not folklore; they are a serious way to make a key by hand. Chapter 4 measured a die at the flip-count of 6, about \(2.585\) bits per roll. A 256-bit key therefore needs

\[ 256 \;/\; 2.585 \;\approx\; 99 \text{ rolls} \]

โ€” and rolls come whole: 99 rolls supply only 255.9 bits, a hair short, so round up โ€” call it a hundred, an afternoon's honest work with pen and paper. (What to do with the hundred numbers once rolled is a Chapter 11 question; the point here is the supply.) Coins work too, at one bit per flip: 256 flips. Slow, physical, and exactly as fair as your thumb.

Hardware does the same job faster. Modern chips carry circuits that harvest physical noise โ€” thermal jitter, the timing of electrons โ€” and serve it up as random bits. Cloudflare, which terminates a sizable share of the world's web traffic, famously keeps a wall of lava lamps in its San Francisco lobby and films them: the wax never rises the same way twice, and the camera turns that chaos into seed material. The principle across all of these is one: the world is the only generator that cannot be predicted from its own source code.

โšก LIVE โ€” The Accountingโ†— share this demo

Pick a physical source and a target. Chapter 4's bits, this chapter's ledger: rolls needed = target รท bits-per-roll, rounded up.

6.3The Computer's Well

Your operating system keeps a reservoir of exactly this kind of physical unpredictability, gathered continuously: the precise timing of keystrokes and disk reads, network packet arrivals, hardware noise where the chip provides it. Programmers draw from the well through interfaces like Linux's /dev/urandom or the getrandom call โ€” no lava lamp required.

This design โ€” collect physical jitter from many sources, pool it, serve it to programs โ€” is as old as Bitcoin itself โ€” and the OS version is older still. Satoshi described the original client's version of it on the BitcoinTalk forum in 2010:

Satoshi, on the seed

"The random seed is very thorough. On Windows, it uses all the performance monitor data that measures every bit of disk performance, network card metrics, cpu time, paging etc. since your computer started. Linux has a built-in entropy collector. Adding to that, every time you move your mouse inside the Bitcoin window you're generating entropy, and entropy is captured from the timing of disk ops."

Read the care in that list: many small unpredictable streams, none of them trustworthy alone, pooled so that no single dry source empties the well. Sixteen-plus years later the architecture is unchanged in spirit โ€” your phone is doing the same quiet collecting right now. When the collection fails, or is skipped, or is replaced by something thinner, the failure lands exactly where Chapter 9 begins.

โšก LIVE โ€” The Collector (real randomness: your browser's crypto well)โ†— share this demo

Each press rolls the source selected above for real, using crypto.getRandomValues() โ€” your machine's Chapter-6 well. Bits accumulate below. For the dice sources the final trim is a hair off uniform โ€” five or six preimages per output; the clean fix is Chapter 11's machinery.

6.4Pseudorandom Is Not Random

Now the pretender. A pseudorandom number generator โ€” PRNG โ€” is a deterministic machine for stretching: feed it a short seed, and it grinds out an endless stream of numbers that pass every casual test for randomness. No physical noise involved; same seed, same stream, forever.

Stretching is not creating. The entire stream's unpredictability lives in the seed: a PRNG seeded with 32 bits can produce at most \(2^{32}\) different streams โ€” about 4.3 billion. That sounds like plenty until you price it with Chapter 3's arithmetic: at a million streams checked per second, a thief enumerates every stream the generator can ever produce in

\[ 2^{32} \;/\; 1{,}000{,}000 \;\approx\; 4{,}295 \text{ seconds} \]

โ€” about 72 minutes. The numbers looked random to a human; to an attacker with the seed space, the generator is a vending machine with 4.3 billion buttons and all the time in the world.

Math.random() is not for keys

Every programming environment ships a convenience PRNG โ€” Math.random() in the browser, random.random() in Python, rand() in C. These are built for simulations and games: fast, well-shaped, and seeded with almost nothing. They are not sources of entropy and must never touch a key, a nonce (Chapter 10's subject), or a seed phrase. The cryptographic draw โ€” crypto.getRandomValues(), Python's secrets module, the OS well of ยง6.3 โ€” is the only kind allowed near money.

The Idea in Code: A 256-bit draw, the right way
>>> import secrets
>>> k = secrets.randbits(256)     # from the OS well
>>> k.bit_length() <= 256         # always true
True
>>> hex(k)                        # your number, your output
0x... (64 hex digits, almost always โ€” fewer only when the
leading digits happen to be zeros)

Run it twice and the outputs differ; run it on any machine and no one can say what will print. That is the difference between secrets and random: one draws from the world's noise, the other from a seed a thief could enumerate.

6.5Inside Bitcoin Core's Well

Satoshi's 2010 list described a client that stirred whatever the operating system offered into OpenSSL's generator. Today's Bitcoin Core keeps a well of its own โ€” since version 0.18 it no longer relies on OpenSSL's generator โ€” and its design is written down in a comment at the top of the source file random.h. It reads like this chapter, in code.

Core holds a single 256-bit secret state: the water already in its well. Whenever the wallet needs key material it calls a function named GetStrongRandBytes, and that call stirs fresh inputs into the state before anything comes out:

All of it goes into one hash, SHA-512 โ€” treat it here as a blender whose 64-byte output looks unrelated to its input, however small the change in that input (the blender's insides are On Hashing's subject). Core then cuts the 64 bytes in two. The first 32 are handed out as the random bytes the wallet asked for; the last 32 become the new state. What you are given and what is kept are different halves of one blended output, so holding a handed-out value tells you nothing about the state that will produce the next one.

Two more habits finish the design. On first use, Core adds 256 bits from the chip's slower RDSEED instruction where available, plus facts about the machine โ€” clocks, resource usage, system details, the modern form of Satoshi's performance counters โ€” and then strengthens: it hashes and re-hashes for 100 milliseconds. Anyone trying to re-create that startup from guessed inputs must pay those 100 milliseconds of hashing again for every guess. And once a minute Core repeats a smaller stir with 10 milliseconds of strengthening, so the state keeps taking in fresh water even when nobody is drawing from it.

In the Codebase: Bitcoin Core v31.0, src/random.h
 * When mixing in new entropy, H = SHA512(entropy || old_rng_state) is computed, and
 * (up to) the first 32 bytes of H are produced as output, while the last 32 bytes
 * become the new RNG state.

The source comment's || means "followed by": the fresh inputs and the old state go into the blender together. The same comment block lists every source above and the two strengthening times, and says of the slow sources that they are "designed to make sure the RNG state contains fresh data that is unpredictable to attackers."

Read this against the third rule in ยง6.6. Core does not brew its own randomness instead of the operating system's well; it pools that well with other streams, so a faulty chip instruction, a frozen clock, or a cloned virtual machine has to fail together with everything else before the output becomes guessable. That is the pooling property Exercise 6.5 asks about, built into the software that guards the most bitcoin. Chapter 7 follows 32 of these bytes out of the well and into a key.

6.6The Rules

The chapter compresses to four rules, in order of how much money rides on them:

  1. Use the cryptographic draw only: Python's secrets, the browser's crypto.getRandomValues(), Linux's getrandom โ€” or a hardware wallet's certified generator, never a convenience PRNG.
  2. Never seed by hand anything that matters. A human-picked seed is a human-picked key โ€” Chapter 5 measured what those are worth.
  3. More stages multiply trust, not safety. Ten weak sources pooled the wrong way stay weak; the well's job is to pool them so no single dry source matters. That pooling is engineering, not improvisation โ€” use the OS's, don't brew your own.
  4. When the stakes are highest, add physics you can see. Dice and a pencil are slow, old, and beyond remote attack. Chapter 12 returns to when that is worth doing.

6.7Looking Ahead

You now hold the whole supply chain: physics makes the unpredictability, the OS pools it, the cryptographic draw serves it, and a proper key is 256 honest bits of it. Part III finally meets the number itself โ€” what a 256-bit key is, what the space it hides in actually costs to search, and why the arithmetic you now own says the search will never happen.

Key Takeaways

Exercises

Exercise 6.1 โ˜…   The hundred rolls. A fair die supplies about \(2.585\) bits per roll. How many rolls supply at least 256 bits? You should get \(100\) rolls at minimum โ€” the quotient is \(99.03\ldots\), rolls come whole, and 99 rolls give only 255.9 bits, so round up.

Exercise 6.2 โ˜…   The pretender's price. A PRNG is seeded with 32 bits. At a million candidate streams checked per second, about how long does enumerating every stream take? You should get about \(4{,}295\) seconds โ€” roughly 72 minutes.

Exercise 6.3 โ˜…โ˜…   Draw your own. Run ยง6.4's code box as printed. Confirm k.bit_length() <= 256 is True, count your hex digits (usually 64), and run it a second time to confirm the draw changes.

Exercise 6.4 โ˜…โ˜…   The wrong tool. Run import random; random.seed(42); [random.random() for _ in range(3)] twice, re-seeding each time. Confirm the two streams are identical, digit for digit. In one sentence: why does that reproducibility disqualify random from key generation?

Exercise 6.5 โ˜…โ˜…โ˜…   Satoshi's list โ€” performance counters, mouse timing, disk timing, the OS collector โ€” pools many mediocre sources rather than trusting one good one. Using Chapter 5's metric, explain the defensive logic: what does pooling buy when an attacker might know or influence some of the streams, and what property must the pool have for that logic to hold?

Exercise 6.6 โ˜…โ˜…โ˜…   The two halves. ยง6.5's generator blends its inputs into 64 bytes, hands out the first 32, and keeps the last 32 as its new state. A thief steals one handed-out value. Explain why it does not let him compute the next value the generator will hand out. Then suppose a careless redesign handed out all 64 bytes: what would the thief learn, and what would still protect the next draw?

Solution Sketches

Sketches, not model answers โ€” enough to check your reasoning against. The computational exercises embed their expected outputs in the exercise text.

Exercise 6.4. Identical seed, identical stream: the generator's output is fully determined by 42, so anyone who learns or guesses the seed owns the whole stream โ€” past and future. A key drawn from it is not a draw from the world's noise but from the seed's small space, and small spaces get enumerated. (For random, the seed space and predictability are documented features, not bugs โ€” it was built for simulations, where reproducibility is the point.)

Exercise 6.5. Pooling is min-entropy insurance. If an attacker knows some streams, then any single stream's unpredictability might be zero for him โ€” its best guess certain. But a pool that mixes the streams so the joint output stays unpredictable whenever any one input was unpredictable keeps the attacker's best guess at the chance of the strongest unknown stream. The property that must hold: the mixing must not let a known or influenced stream cancel the others โ€” the unknown one must still flow through. That is engineering with proofs attached, which is exactly why the rules say to use the OS's well rather than brewing your own.

Exercise 6.6. The handed-out half and the kept half are different pieces of one SHA-512 output, and a good hash gives no way to get from one half to the other โ€” so the stolen value says nothing about the state, and the next value is computed from that unknown state. Hand out all 64 bytes and the thief holds the new state itself: everything the generator would produce next is predictable to him until fresh inputs are stirred in. What still protects the next strong draw is exactly the pooling โ€” each GetStrongRandBytes call mixes in fresh OS bytes, timestamps, and events the thief does not know. Keeping half the output secret is a second line of defense on top of that, so that one leak is not a gift.