Frontier research · work it out yourself

How Claude traced the NIST curve seeds in half an hour

The Duowenwen team · Updated

What happened

In 2000, the US National Institute of Standards and Technology (NIST) published a set of standard elliptic curves. Each curve came with a 160-bit "seed," and nobody explained where the seeds came from.

In October 2026, an internal Anthropic research model found the source in under half an hour: the seeds came from lrand48, an old random number generator in the C library, started from the clock in 1997.

This is not a break. People who use these curves don't need to do anything. It makes the idea of a hidden backdoor in the curves harder to believe.

A few words first

Elliptic curve signature
A way to sign data digitally. It uses a public curve and a number only you know to produce a value anyone can check but no one can forge. ECDSA is one such scheme.
Seed
A 160-bit (20-byte) number. In the standard procedure, the seed is hashed with SHA-1, and the result sets the coefficient b in the curve's equation. Fix the seed and you fix the curve.
Pseudorandom number generator
A program that computes numbers one step at a time from a fixed formula. Its output looks scrambled, but start it from the same value and you get exactly the same sequence.
lrand48
A pseudorandom number generator that ships with the C library. It keeps a 48-bit internal state. Each call updates the state with a formula and returns its top 31 bits.
Lattice problems and LLL
A well-established mathematical tool for working back from truncated outputs to the internal state that produced them. LLL is the classic algorithm for it.

Why cryptographers wondered for 26 years

The seeds were supplied by the US National Security Agency (NSA). The standard never said how they were chosen.

That left an open question. Did the designers try many seeds and keep a curve with some hidden property? Koblitz and Menezes discussed it in their 2015 paper "A Riddle Wrapped in an Enigma." Bernstein and Lange described a possible technique for shopping around for weak curves.

In 2015, NSA cryptographer Jerry Solinas recalled that the seeds might have been a joke phrase, such as "Give Bob and Jerry a raise," hashed together with a counter. He died in 2023, and his records were never found.

Cryptographer Filippo Valsorda offered a $12,288 bounty for the seeds' origin, tripled to $36,864 if donated to charity.

Several Anthropic employees first followed the joke-phrase lead and came up empty. That lead turned out to be a faulty memory.

How Claude found it

Here is the answer first. The program called srand48(timestamp) to set its starting point, then called lrand48 over and over. Each call kept only the top 8 bits of the output (lrand48() >> 23) as one byte. Every 20 bytes made one candidate seed. The program checked each candidate with the ANSI X9.62 procedure, and if it didn't yield a valid curve, it moved on to the next one. P-256 is candidate number 1842.

The explainer below runs exactly this rule in your browser. Press Next to see one call. Press "Jump to candidate 1842" to compare the result with the published P-256 seed, bit for bit.

lrand48 · a 48-bit linear congruential generator · Computed in your browser

state ← (0x5DEECE66D × state + 0xB) mod 2⁴⁸

Each call keeps

The prime-curve rule: keep only the top 8 bits of each call, 20 bytes per candidate.

Internal state (48 bits)srand48

0x33F507E2330E

  • 8 bits kept
  • 23 bits dropped by >>23
  • 17 bits never returned

Low 16 bits = 0x330E: the pattern srand48 leaves
Top 32 bits = 871696354 = 1997-08-16 01:52:34 UTC

No calls yet. Press Next.

Candidate0 / 20

As five 32-bit words

········································

Published P-256 seed: C49D3608 86E70493 6A6678E1 139D26B7 819F7E90

  1. Change the questionStop guessing the passphrase. Ask instead what random numbers someone writing a curve generator in 1997 would have used. The likeliest answer is a weak generator built into the C library, and those leave statistical fingerprints in their output.
  2. Write a scannerSlide across every published seed one bit at a time, checking whether neighboring chunks look like consecutive outputs of some 1990s generator. In all, it tried 34 combinations of generator and output truncation.
  3. Spot the fingerprintWrite each seed as five 32-bit words. In 4 of the 10 seeds, all 20 of those words have a top bit of 0. The chance of that happening at random is about 1 in 5,810. It is exactly what lrand48 leaves behind: it returns only the top 31 bits of its 48-bit state, so in a 32-bit word the top bit is always 0. Switch the explainer to "all 31 bits" to see it.
  4. Brute forceFor those 4 seeds, take the first 32-bit word. It is missing the 17 hidden bits that lrand48 throws away, which leaves 2^17 possibilities. Try each one and check whether the next four words follow. All 4 seeds matched.
  5. Bring in latticesThe prime-curve seeds keep fewer bits: shifting right by 23 leaves only 8. Recovering the state of a linear congruential generator from truncated output is a classic lattice problem, solved with the LLL algorithm. With no way of knowing which bits were kept, it ran every possible bit window.
  6. Run it backwardA linear congruential generator can run forward or backward. From each recovered state, step back until you hit the pattern srand48 leaves: the low 16 bits equal 0x330E. That pattern turns up by chance about once every 65,536 steps, so on its own it proves nothing. "Rewind to the start" in the explainer does this step.
  7. The clincherEvery one of the 10 prime-curve seeds traced back to a starting value that reads as a Unix timestamp. They fall between May 1997 and April 1998, matching when NIST was doing this work. Each recovered 48-bit state regenerates all 160 bits of its seed exactly.
  8. Doubting itselfIn its reasoning, Claude first wondered whether it was inside a test environment. Then it asked why a clue this obvious had gone unnoticed for 25 years. It settled the question this way: a 32-bit starting value plus a small index matching a 160-bit seed exactly, ten times over, cannot be a coincidence.
  9. A bonus findThe base point G of P-192 and five ANSI curves came from the random number generator in FreeLIP, a big-integer library. The starting values were 20000, 20420, 20507, 20509, 20512 and 20517. The program discarded the first 7 outputs, then drew 26-bit candidate x-coordinates until one landed on the curve. No NIST curve's base point had ever been explained before.

Eleven months, more than a dozen curves

Each dot is the start time (UTC) of one run, and the number next to a curve is the candidate it ended up using. Tap a prime curve and the explainer starts from that timestamp and jumps to that candidate. For the binary curves (the ones starting with B), the clock value reads as February 1984 taken at face value. Doubled, it is April 17, 1998, two weeks after P-224, so the program may have divided the clock by 2.

1997-0508111998-02051234567
  1. 1

    1997-05-15 15:49:03 UTC

  2. 2

    1997-05-18 14:45:34 UTC

  3. 3

    1997-08-08 01:12:04 UTC

  4. 4

    1997-08-16 01:52:34 UTC

  5. 5

    1997-08-30 14:50:08 UTC

  6. 6

    1998-04-03 12:52:07 UTC

  7. 7

    1998-04-17 (clock value ×2)

    B-233 #155B-283 #32B-409 #60B-571 #73

What it means

  • It is not a break. In Anthropic's words: "not a cryptographic break, new attack, or weakness in the ECDSA curves." Users don't need to do anything. ECDSA and P-256 are as safe as they were.
  • A backdoor is now harder to believe. The seeds came from a simple process anyone can rerun, a timestamp and a weak generator, not from someone picking values by hand. Anthropic says this makes a backdoor less plausible. Valsorda goes further: it lets us "completely rule out the technique described by Bernstein and Lange." The whole process has only about 30 bits of freedom, too few to pick out a small class of weak curves.
  • Bitcoin is not involved. Bitcoin uses the curve secp256k1, which is not a NIST curve.
  • A timestamp plus lrand48 is a weak source of randomness. Here, though, it only produced public parameters. It never protected a private key.

What's still unexplained

  • Skipped candidates. In the P-256 run, candidate 876 would also have produced a valid curve, yet the program used candidate 1842. The P-224 run skipped 3, and the two ANSI runs skipped 7. Valsorda counts roughly twice as many valid seeds as were published. He found one unstated rule (the bit length of the order n may not exceed that of the field p); a second rule is still missing. The checks may themselves have consumed random numbers, or the program may have had a bug. Anthropic notes that too few candidates were skipped to support deliberate shopping for weak curves.
  • Where the B-163 seed came from is still unknown.
  • Where the base points G of P-224, P-256, P-384, P-521 and the binary curves came from is still unknown.

Try it yourself

  • Anthropic released its reproduction code into the public domain (CC0). The link is in Anthropic's write-up below.
  • Valsorda reproduced the result independently in Go and published his code. The link is in his post below.
  • The explainer on this page compares only P-256 against its published seed. Other curves are computed with the same rule; to check them, use the two code releases above.
  • The $36,864 bounty went to the Internet Security Research Group, the nonprofit behind Let's Encrypt.

Sources

More frontier: the Kakeya needle, and how little room it takes to turn a needle around

AI-designed quantum circuits: how Claude rebuilt eight circuits without keeping its scratch work

Try one question