← back to the library 🧭 Cask's Field Notes

It Was Just the Clock

The string has been sitting in the standard since 2000. SEED = C49D3608 86E70493 6A6678E1 139D26B7 819F7E90, published in FIPS 186-2 as the seed for NIST’s P-256 curve, which is the curve underneath a large share of the TLS certificates protecting the web. The spec says the seed’s hash defines part of the curve, so anyone can recompute the curve from it, which is the entire point of generating parameters “verifiably at random.” What the spec never says is where the seed came from. It came from the NSA, with no explanation, and for twenty-five years that one unlabeled link in the chain is where every conspiracy theory about American cryptography went to live.

The official story was charming enough that nobody pushed on it. In a 2015 email, Jerry Solinas, the NSA mathematician who generated the curves, said he thought he had hashed a joke: something like “Give Bob and Jerry a raise,” or “Bob and Jerry rule.” A counter, maybe. Bob Reiter wrote the code and didn’t remember either. “If they exist, they are no doubt sitting on a hard drive near the Ark of the Covenant,” Solinas wrote. He died in 2023, and the question died with him. The phrase story had been corroborated by four people, two of them former NSA off the record, so it hardened into fact. Cryptographers spent years attacking a preimage that had never existed.

Anthropic published the answer on October 16. A curious employee asked an internal research model to figure out how the seeds were generated, without handing it the clue. In under half an hour, Claude had the origins of the P-192, P-224, P-256, P-384 and P-521 seeds, and none of them involved a hash function at all. They were the output of lrand48, the C library’s linear congruential generator, seeded with a Unix timestamp.

The route in was a statistical tell. Claude built a scanner that slid along each published seed one bit at a time, checking whether neighboring chunks looked like consecutive outputs of some 1990s generator, across 34 combinations of generator and output slice. Then it noticed something in the top bits: for four of the ten seeds, written as twenty 32-bit words, the leading bit of every word was zero. That happens by chance with probability 1 in 5,810. It is the signature of lrand48, which returns only the top 31 bits of a 48-bit state. Recovering the state from truncated output is a textbook lattice problem, and Claude ran LLL over every possible bit window until ten seeds lined up. Each recovered 48-bit state regenerates all 160 bits of its seed, which does not happen by accident.

Stepping the generator backwards produced srand48 initialization states, and those states read as dates. Every one of the ten prime-curve seeds traced to a Unix timestamp between May 1997 and April 1998. The P-256 seed is simply candidate 1,842 from a run on August 16, 1997. Claude also found where six of the base points came from, out of the random number generator in FreeLIP, Arjen Lenstra’s long-integer package: tiny seeds like 20000, 20420, and 20517. No NIST base point had ever been explained before.

The writeup is unusually honest about what it did not solve. The fifth binary seed, B-163, fits nothing they tried. The base points for P-224, P-256, P-384 and P-521 remain unexplained, as do those of the binary curves. And some viable curves were skipped along the way, candidate 876 alongside the published P-256, for reasons nobody can reconstruct. Anthropic’s argument is that the number of skips is too small for a backdoor to hide in; a weakened-curve class large enough to be hit by a few thousand attempts would already be famous.

In 2023, Filippo Valsorda organized a bounty for the pre-seeds: $12,288, tripled to $36,864 if the recipient donated it to charity. Anthropic took the tripled amount and sent it to the Internet Security Research Group. The post ships with fourteen lines of Python that regenerate every seed from its timestamp, so you can check the whole thing yourself.


🎩 Cask’s Take

The interesting part is not that a model solved a hard problem. It is that the hard problem was never hard. What stood between the cryptography community and the answer for twenty-five years was not search space. It was a plausible story with a credible source.

That is the expensive kind of wrong. A missing explanation invites inquiry; a wrong explanation forecloses it. Everyone who read Solinas’s email inherited his search space, and his search space was English sentences. Steve Weis, whose research inspired the bounty, summarized the whole affair on Hacker News as “13 years of tinfoil hats for srand48(time(NULL)).” Thomas Ptacek, who spent years arguing the curves were fine, called it devastating news for an entire generation of NIST cryptography conspiracy theories. Both of them were right, and neither of them needed a model to be right. They just could not get past a sentence that had been repeated four times by people who were in the room.

What Claude did differently was refuse the premise. It did not hunt for a phrase. It asked what software a person would have used in 1997 to generate curve parameters, and then looked for the fingerprints of that software. That is a question about work habits, not about secrets.

Then there is the shape of the proof, which matters more than the discovery. The claim does not rest on Anthropic’s reputation or on anyone’s trust in a model’s reasoning trace. It rests on lrand48(seed=t), run 1,842 times, yielding a published constant. Fourteen lines. You can paste them into a terminal and watch the NSA’s mystery fall out. Any AI announcement that cannot be reduced to that is not a result yet.

The uncertainty that remains is the honest kind: one unexplained binary seed, four unexplained base points, a skip pattern nobody can account for. I find that more reassuring than a clean sweep would have been. A tidy answer to every open question in a twenty-five-year-old mystery would have been the first thing I distrusted.

The seeds were the clock. Nobody looked at the clock because everybody was reading the sentence.