The Case of the Mystery Seeds · Chapter 8

The reveal

We have the exact internal state of the generator at the moment it produced P-256's seed. Now we rewind it to the second someone pressed Enter, and then, going the other way, we run their program ourselves.

Nib says: Everything on this page is computed live from the published seeds: the lattice from Chapter 7, then a rewind of tens of thousands of turns. No answers are stored. If the story were wrong, these toys would say so.

Rewind to the start

Rewinding is easy. Knowing where to stop is the subtle part. As you saw in Chapter 5, the srand48 fingerprint (330E in the bottom 16 bits) comes round exactly once every 65,536 turns, and each time the top bits decode to a different "seed". So we rewind through the first few fingerprints and put each one to two tests:

1. Does it decode to a sensible date? (The seed is read as a Unix timestamp.) The standard was written in 1997 and 1998.
2. Does it land on a candidate boundary? The program read seeds 20 bytes at a time, so the published seed must start exactly at a multiple of 20 turns after the start (plus the first turn).

Rewind a curve's generator

Press the button. We recover the state with the lattice from Chapter 7, then rewind 200,000 turns, noting every fingerprint.

For every curve, exactly one fingerprint passes both tests, and it lands in 1997 or 1998. For P-256, that's 01:52:34 UTC on Saturday, August 16, 1997. The program was started at that second, and P-256 was the 1,842nd batch of 20 bytes it drew. Take P-224 if you want to see the decoys earn their name: its true start, April 3, 1998, comes only after a fingerprint in 2080 and another in March 2000.

Run the 1997 program

Now the other direction, the proof any skeptic can repeat. Here's what the program evidently did, pieced together by Anthropic's team and checked independently by Filippo Valsorda: call srand48 with the current time; draw bytes one at a time; take each 20 bytes as a candidate seed; turn it into a curve with the X9.62 recipe from Chapter 3; throw it away if the curve isn't suitable; keep going. Some runs kept going after the first good curve and produced several.

Below are all six runs that made the NIST prime curves and the ANSI X9.62 example curves, plus the binary-curve run from Chapter 6. Tap one. Your browser will seed lrand48 with that timestamp and draw candidates until it reaches the published seeds.

The 1997–98 time machine

Green dots: prime-curve runs. Gold: the binary-curve runs (their clock value was halved before seeding). Pick a run.

Tap a run.

Look at the runs with several entries. Some candidates produced perfectly valid curves that were never published, marked "not published". Valsorda found that the published curves pass the ANSI X9.62 rules plus one extra rule (the curve's group order can't need more bits than its clock size), but even then roughly twice as many seeds pass as were used. Why some were skipped is still unexplained. It's one of the open cases in Chapter 10.

What really happened

Put it together and the mystery dissolves into something touchingly ordinary. Between May 1997 and April 1998, someone ran a program that used the standard C library's random number generator seeded with the clock. It drew random-looking bytes until it found curves that passed the checks. The seeds were simply what came out.

Jerry Solinas, decades later, remembered a joke phrase being hashed. Perhaps a phrase was used for something else, or perhaps memory blended two things together; Valsorda's kind summary is that memory can play tricks on everyone. Either way, the hunt for the phrase was a hunt for something that was never there.

There's a bonus. The seed doesn't fix a curve's starting point G, and Anthropic's team also traced the base points of P-192 and five ANSI example curves to the random number generator in FreeLIP, Arjen Lenstra's long-integer library (yes, one of the L's in LLL), seeded with small round numbers like 20000. The base points of P-224, P-256, P-384 and P-521 still aren't explained.

And the speed: according to Anthropic, Claude went from the question to the answer for the five NIST prime curves in under half an hour, working from a fresh hypothesis rather than the phrase story. The people around it spent their time where people are most needed: checking. The bounty-setter reimplemented the method himself before paying out.

Nib says: Pause on that last part, because it's the real lesson of the case. The answer was accepted not because an AI said so, but because anyone, including you, just now, can rerun it and get the published numbers bit for bit. Good science, from people or machines, hands you the means to check it.

Words in this chapter

Tap any word with a dotted gold underline to see what it means. Here they all are in one place.

Three things to keep

Check yourself

Why do the decoy fingerprints come exactly 65,536 turns apart?

The bottom 16 bits of an LCG on a power-of-two clock depend only on the bottom 16 bits before them, and here they cycle through all 65,536 values. So 330E recurs on a fixed schedule; each recurrence just has different top bits.

P-256 is candidate 1,842 in its run, but candidate 876 also made a valid curve. What does that tell us?

That the program (or whoever ran it) used some selection rule beyond the published ones. Nobody yet knows what it was, though the tiny amount of freedom involved is the subject of Chapter 9.

What would it take for a skeptic to check this result?

About ten lines of code: seed lrand48 with 871696354, draw 36,840 bytes, and look at the last 20. They're P-256's seed.

Go deeper