For twenty-six years the NIST P-256 curve has carried a 160-bit number that nobody could account for: C49D3608 86E70493 6A6678E1 139D26B7 819F7E90. Hash it with SHA-1 by the procedure in ANSI X9.62 and you get one of the curve’s coefficients. The procedure was the point. If a curve’s parameters come out of a hash, the designer supposedly cannot have picked them to be weak. That argument only works if you also know where the input came from, and nobody did. The National Security Agency supplied the seeds and gave no explanation (NIST SP 800-186, the current curve standard, still prints the same P-256 value).
On 16 October Anthropic’s Frontier Red Team published the answer (Anthropic, 2026). The seeds are not hashes of anything. They are raw output from lrand48, the old POSIX pseudorandom generator in the C library, started with the Unix clock. For P-256 the clock read 16 August 1997, 01:52:34 UTC, and the published seed is the 1,842nd 20-byte block the generator produced. Filippo Valsorda, who ran a public bounty for the seeds, reimplemented the method in Go, confirmed it, and declared the bounty claimed (Valsorda, 2026).
I ran the published reproduction code too. It is a short Python script, and it regenerates all five NIST prime-curve seeds byte for byte. Then I took the regenerated P-256 seed and pushed it through the X9.62 SHA-1 derivation, and it yields the published coefficient \(b\) for P-256. So the chain from a wall clock in 1997 to a coefficient in today’s standard is now fully mechanical and anyone can check it. That part is settled, and it closes a question cryptographers have argued over for more than a decade.
What it closes is narrower than the headlines suggest, though. “Where did the seed come from” and “why this seed” were always two questions. The first now has an answer. The second has a smaller one.
The story everyone had
The lore was specific and wrong. Jerry Solinas, the NSA mathematician who produced the seeds, recalled in 2015 that they were probably SHA-1 hashes of a humorous sentence, possibly with a counter, in code written by a colleague named Bob Reiter. Neither of them remembered the details. The records, Solinas wrote, were probably “sitting on a hard drive near the Ark of the Covenant” (quoted in Anthropic’s write-up). Solinas died in 2023. Steve Weis, who collected that history in a long post (Weis, 2023, updated 2026), is one of the ten Anthropic authors who claimed the bounty.
The bounty was built around the lore. Valsorda announced it on 5 October 2023 at $12,288, tripled to $36,864 if paid to charity, for “the pre-seeds, the inputs to the hash that generated the seeds” (Valsorda, 2023). He pitched it to password crackers. As it turned out, there were no pre-seeds, because the seeds were never hashed from anything. Nobody seems to mind that the claim answered a different question than the one posed. The team donated the prize to ISRG, which runs Let’s Encrypt.
The useful part of the lore’s failure is the method that replaced it. Several people at Anthropic had chased the hash-of-a-phrase theory and found nothing, according to the write-up. The model they then asked was not given the clue. It guessed instead at what 1990s software would have used for randomness, and tested the seeds for the fingerprints of period generators. One fingerprint is visible by eye once you know it exists. lrand48 keeps a 48-bit state and returns only the top 31 bits, so every 32-bit word it emits starts with a zero. In four of the ten seeds Anthropic examined, all five 32-bit words start with zero. Anthropic puts the chance of that happening by luck at about 1 in 5,810.
A constant in the POSIX specification did the rest. srand48 puts its 32-bit argument in the top of the state and fills the bottom 16 bits with the fixed value 330E in hex (The Open Group, srand48). The generator is a linear congruential one, so it runs backwards as easily as forwards. Anthropic stepped each recovered state back until the low bits read 330E. Such states turn up about once every 65,536 steps, which by itself proves nothing. What made it convincing was that every prime-curve seed rewound to a top half that reads as a Unix timestamp between May 1997 and April 1998. That window contains the autumn of 1997, when Alfred Menezes, primary author of X9.62, says Solinas gave him the seeds (“sometime in Fall 1997”, as quoted by Weis). A recovered 48-bit state that regenerates all 160 bits of a seed is a strong match, and ten of them landing in a 1997–98 window is not plausibly a coincidence.
What a timestamp buys you
The worry about the NIST curves was never that the seeds were mysterious for their own sake. It was that a mystery seed leaves room to search. Daniel Bernstein and colleagues showed in 2014 that a designer who knows of a rare class of weak curves can keep drawing “random” seeds until one lands in it, and the output still looks verifiably random (Bernstein et al., 2015). Valsorda’s post recounts a 2017 version of the argument, reported in a later revision of Koblitz and Menezes’s “A Riddle Wrapped in an Enigma” (Koblitz and Menezes, 2016): with about 70 bits of freedom in the choice of seed, one could aim at a hypothetical class of \(2^{61}\) weak prime-order curves.
A seed that is the output of a clock-seeded generator has far less freedom than that. Valsorda’s estimate is generous on purpose. Let the designer pick any second in 1997 or 1998 and any of the first 16 acceptable candidates from that run. Two years is about 63 million seconds, roughly \(2^{26}\), and 16 more choices make about \(2^{30}\). (That is my arithmetic. His post says “barely 30 bits.”) Valsorda concludes that this is not enough to target a small class of weak curves, and that the finding “completely rule[s] out” the Bernstein–Lange technique. He now says he would personally recommend the NIST curves over Curve25519, which is his own opinion, not a NIST position.
I find the freedom argument persuasive. It is, though, an argument about how much choice the designer had. The seeds’ origin does not prove anything about the choice itself.
The part that is still missing
Valsorda’s reimplementation turned up the loose end. Running each recovered timestamp forward and applying the X9.62 acceptance checks, plus one undocumented rule he could infer (reject a candidate if the curve’s order has more bits than its field), leaves “roughly twice as many valid seeds as were published.” His post lists them. The P-256 run accepted candidate 876 and then candidate 1,842, and only the second became the standard. The P-224 run accepted candidates 777, 1,485 and 5,736 before it reached the published 7,026. The two May 1997 runs behind the ANSI example curves skipped seven more. That makes ten published and eleven passed over. Anthropic’s own write-up says plainly, “We do not know what criteria may have been used, or whether this was an unintentional artifact.”
That gap is small, and Valsorda’s 30 bits already allows for it: the “first 16 candidates” in his bound is there to absorb exactly these unexplained skips. Valsorda offers two innocent explanations. The validation code may have drawn on the same generator, eating outputs. Or a bug in one of the algorithms may have returned the wrong result half the time, which he notes is believable because these calculations were still state of the art in 1997. He also says he explored a number of explanations and “found no good fit”, and that the gaps are not regular.
Anthropic adds a caveat of its own that matters more for the governance question than the security one: “Nothing in the numbers shows how many runs there were.” The timestamps tell you when the runs we can see were started. They cannot tell you how many other runs happened and were thrown away. Anthropic’s answer is about motive, not evidence. It grants that a search over timestamps is “still conceivable”, but says you would only need one “if you were going to disclose the timestamp”, and as far as anyone knows the timestamps were never disclosed. That seems right to me, and it is still an argument about intent.
There is also plain unfinished work. The base point \(G\) is a separate parameter that the seed does not determine. Anthropic reproduced the base points of P-192 and the five ANSI example curves from the random-number generator in Arjen Lenstra’s FreeLIP library, seeded with small integers like 20000. It could not explain the base points of P-224, P-256, P-384 or P-521, or of the binary curves. One binary seed, B-163, fits nothing tried so far. (Valsorda’s postscript says the B-curve seeds were figured out. Anthropic’s write-up says four of five were, and I would go with the primary account.)
None of these open items is a practical concern for anyone using P-256 today. On a prime-order curve the choice of base point is generally understood not to change how hard the underlying problem is, so it is not the kind of weakness the seed debate was about. I mention them because “the mystery is solved” will be the summary, and it is more accurate to say the main mystery is solved and three smaller ones are now precisely stated.
Verifiable, eventually
The episode shows something uncomfortable about the phrase “verifiably random.” In 1997 the X9.62 procedure let anyone verify that the coefficient followed from the seed. It gave nobody a way to verify the seed. Verification of the full chain had to wait until someone guessed the generator, and the guess was possible because the generator was weak enough to leave fingerprints in its output. The curves look more trustworthy today partly because the person who made them used a poor random-number generator and a clock.
The alternative that gained ground after the 2013 controversies, in curves such as Curve25519, is “rigidity”: every constant forced by a short public rule rather than drawn from a seed. Valsorda’s own 2023 bounty notice granted that even an English preimage “is not a complete guarantee of rigidity.” What the October result gives the NIST curves is something rigidity would have given them from the start: a short, public procedure that reproduces the numbers. It still lacks one piece, the rule that picked among acceptable outputs.
This is close kin to a problem I wrote about earlier this month: a machine-checked proof verifies only the statement it was given. Here, too, a reproduction verifies the step it reproduces. The clock-and-generator chain is checked. The selection step is not, and an honest summary keeps them separate.
The answer arrived through the same process that made the seeds hard to trust: a large, cheap search through possibilities. Recovering a truncated generator’s state is a textbook lattice problem, solved with the Lenstra–Lenstra–Lovász reduction. Anthropic says its model wrote the scanner and found the pattern in under half an hour. That claim is the company’s own account of its internal model, and the people credited are Anthropic staff. What can be checked independently is the result. Valsorda has checked it, and so has anyone who runs the script. NIST had not, as far as I could find by 17 October, said anything at all. Anthropic’s write-up says no action is needed, and on the evidence I agree. P-192, the oldest of the five, is already marked “for legacy-use only” in SP 800-186, and Valsorda’s closing line is that the curves have been rehabilitated “just in time” to be retired in favor of post-quantum signatures.
References
- Anthropic Frontier Red Team (2026). Claude reveals ECDSA curve origins. 16 October 2026. Reproduction code released under CC0.
- Valsorda, F. (2026). The NIST Elliptic Curves Seeds Bounty Has Been Claimed. 16 October 2026.
- Valsorda, F. (2023). Announcing the $12k NIST Elliptic Curves Seeds Bounty. 5 October 2023.
- Weis, S. (2023, updated 2026). How were the NIST ECDSA curve parameters generated?.
- Chen, L., Moody, D., Randall, K., Regenscheid, A. and Robinson, A. (2023). Recommendations for Discrete Logarithm-based Cryptography: Elliptic Curve Domain Parameters. NIST SP 800-186, February 2023.
- NIST (2023). Digital Signature Standard (DSS). FIPS 186-5, 3 February 2023.
- Bernstein, D. J., Chou, T., Chuengsatiansup, C., Hülsing, A., Lange, T., Niederhagen, R. and van Vredendaal, C. (2015). How to manipulate curve standards: a white paper for the black hat. SSR 2015, LNCS; IACR ePrint 2014/571.
- Koblitz, N. and Menezes, A. (2016). A Riddle Wrapped in an Enigma. IEEE Security & Privacy 14(6); IACR ePrint 2015/1018.
- The Open Group (2018). srand48 — seed the uniformly distributed double-precision pseudo-random number generator. Base Specifications Issue 7.