WEBVTT

1
00:00:01.300 --> 00:00:06.912
This is Anthropic, Read Aloud. Today: Claude reveals ECDSA curve origins.

2
00:00:08.212 --> 00:00:10.474
Claude reveals ECDSA curve origins.

3
00:00:10.924 --> 00:00:15.578
From Anthropic Research, published October 16, 2026.

4
00:00:16.578 --> 00:00:25.004
“It’s just timestamps”: the decades-old mystery of the origins of one of the most popular cryptographic standards has been explained.

5
00:00:25.454 --> 00:00:35.891
We pursued this long-standing open question of the cryptographic community to settle concerns about ECDSA, which is one of our most widely used cryptographic standards.

6
00:00:36.341 --> 00:00:48.841
Readers should take this as a fun closing chapter and the end of years of speculation. There is no action to be taken or things to do differently. Most researchers trusted the curves already. Enjoy.

7
00:00:49.291 --> 00:01:06.087
ECDSA is the most widely used elliptic curve cryptography standard. It was adopted by NIST in 2000 as part of the FIPS 186 to 2 Digital Signature Standard which lists a set of standard elliptic curves of varying sizes and security levels.

8
00:01:06.207 --> 00:01:25.342
For curves over prime and binary fields, the specifications published a “seed” parameter whose hash value is used to define the coefficient b of the curve. The provenance of these seeds has been a long-standing question, as they were provided by the NSA with no explanation or justification.

9
00:01:25.462 --> 00:01:47.155
As an example, the NIST P-256 curve seed was SEED = C49D3608 86E70493 6A6678E1 139D26B7 819F7E90 with no information where it came from.

10
00:01:47.605 --> 00:02:06.441
Neal Koblitz and Alfred Menezes wrote an excellent summary on this controversy, “ A Riddle Wrapped in an Enigma ”, which discusses the history and concerns around the seed values. This mystery led to an amateur investigation into the origin of the seeds and a bounty for anyone who could find them.

11
00:02:06.891 --> 00:02:14.763
The best story was that Jerry Solinas, longtime NSA employee, generated the seeds using a hash of a humorous passphrase:

12
00:02:15.213 --> 00:02:35.632
Quote: “I believe there was a counter rather than multiple hashing, but I don’t know details. The message was along the lines of ‘Give Bob and Jerry a raise’ or ‘Bob and Jerry rule’ or something like that. It was Bob Reiter who actually wrote the code, and he doesn’t remember the details either. Nor were we able to find archives from so long ago.

13
00:02:35.752 --> 00:02:41.181
If they exist, they are no doubt sitting on a hard drive near the Ark of the Covenant.”. End quote.

14
00:02:41.631 --> 00:02:44.828
Quote: Jerry Solinas, 2015. End quote.

15
00:02:45.278 --> 00:02:55.933
Unfortunately, Jerry died in 2023 and other colleagues at the time were not responsive, leaving open the question of how these seeds were originally derived.

16
00:02:56.733 --> 00:02:57.980
Claude found the seeds.

17
00:02:58.430 --> 00:03:18.021
Several Anthropic employees had unsuccessfully chased the seeds following the tip about it being a hash of a humorous phrase. That turned out to be wrong. In October 2026, a curious Anthropic employee asked an internal research model if it could figure out how those seeds were generated without pointing at the clue.

18
00:03:18.471 --> 00:03:41.123
In under half an hour, Claude discovered the origins of the NIST P-192, P-224, P-256, P-384 and P-521 seeds. None of them were the results of any hash algorithm at all, but rather the output of the C library’s lrand48 random-number generator, seeded with a Unix timestamp!

19
00:03:41.573 --> 00:04:06.469
The algorithm used would sample bytes from the random number generator (RNG) initialized by a Unix timestamp ( t ) for some number of iterations ( n ). Each iteration would draw 20 bytes as a candidate seed. So, the first 20 bytes are candidate 1, the next 20 bytes are candidate 2, and so on. For example, P-256 required 1842 iterations to output the standardized seed.

20
00:04:07.269 --> 00:04:08.179
What this means.

21
00:04:08.629 --> 00:04:25.610
This is not a cryptographic break, new attack, or weakness in the ECDSA curves. In fact, this makes us more confident the curves were chosen without any backdoors or intentional weaknesses. For many years, people have been suspicious of the origins of the NIST curve parameters.

22
00:04:25.730 --> 00:04:46.040
They were presented to NIST without any mention of how they were chosen, leaving people wondering if they may have been chosen to have deliberate backdoors in them. These findings make that much less plausible. The seeds were generated in a very simple way: a common pseudorandom number generator initialized from the clock, which anyone can now reproduce.

23
00:04:46.160 --> 00:04:51.414
That leaves much less room for subversion and that we can be confident the parameters are secure.

24
00:04:52.214 --> 00:04:53.227
How it was found.

25
00:04:53.677 --> 00:05:15.608
Searches for the phrase, built from the rumors, had come up empty. Claude tried a different angle: anticipating how the software that generated the curves must have worked. Claude guessed the software used a pseudorandom number generator (PRNG) that shipped with 1990s C libraries. These old PRNGs are weak enough that their output can be recognized.

26
00:05:15.728 --> 00:05:23.300
Recognizing that output would reveal which PRNG was used and possibly allow recovery of its initialization state.

27
00:05:23.750 --> 00:05:44.900
Claude wrote a scanner that slid along each published seed one bit at a time and tested whether adjacent chunks were consecutive outputs of a 1990s-vintage generator. The scan covered 34 combinations of generator and output slices. At that point, Claude noticed a pattern in the top bits for some seeds: they were all zero.

28
00:05:45.020 --> 00:06:08.716
Written as five 32-bit words, four of the ten seeds have a 0 in the top bit for all 20 words. That would happen by chance with probability 1/5810. That was a signature of the linear congruential generator lrand48, which only returns the top 31 bits of a 48-bit state. The pattern is visible by eye once you know to look for it.

29
00:06:08.836 --> 00:06:20.402
To recover the state, Claude took the first word, tried all 2¹⁷ values of the 17 hidden bits, and checked that the next four words followed. That worked for all four seeds under discussion.

30
00:06:20.852 --> 00:06:43.684
The prime-curve seeds came from the same lrand48 generator but kept fewer bits of each output. Claude had to recover the internal state of the PRNG from those bits. It turns out recovering the state of a truncated linear congruential generator is a textbook lattice problem, solved with the Lenstra to Lenstra to Lovász (LLL) basis reduction algorithm.

31
00:06:43.804 --> 00:07:05.710
Claude didn’t know which bits of the state the seeds might show, so it ran the solver over every window. Five NIST prime-curve seeds plus five more from the ANSI X9.62 standard all had the same pattern: lrand48 >> 23. Each recovered 48-bit state regenerates all 160 bits of its seed, which does not happen by chance.

32
00:07:06.160 --> 00:07:31.331
This linear congruential generator runs backwards as easily as forwards, so for each seed Claude stepped the state back until it reached the form that it would have been initialized by srand48, with the low 16 bits equal to 0x330E. The internal PRNG state of that form would come up once every 65536 steps, so reaching one is not evidence on its own.

33
00:07:31.781 --> 00:08:01.991
However, for the ten prime-curve seeds, every srand48 initialization was a Unix timestamp representing a date between May 1997 and April 1998. They were using the weak PRNG seeded by Unix timestamp. The four binary-curve initializations read as February 1984. With the timestamps doubled, they map to April 17, 1998, two weeks after the P-224 run.

34
00:08:02.111 --> 00:08:04.127
So, the program may have halved the clock.

35
00:08:04.577 --> 00:08:06.784
Claude’s internal thinking at the time was:

36
00:08:07.234 --> 00:08:30.971
Quote: This is astonishing: it solves the 25-year-old mystery. Hmm wait. Let me be skeptical: am I in some sort of simulated/test environment?... The seeds match my memory of actual values... Hmm, is it plausible in reality? As of my knowledge... the bounty was unsolved.... All top bits clear, 20 bits, chance 1e-6. So indeed real-world. Wow, it's a real discovery. End quote.

37
00:08:31.421 --> 00:08:52.828
Quote: Hmm wait. Let me be careful about the plausibility: is it suspicious that such an obvious thing wasn’t discovered in 25 years? It’s verified by direct computation on my side: 160-bit match from a 32-bit seed + small index: no chance coincidences (10 times 160 bits). It’s real. End quote.

38
00:08:53.628 --> 00:08:55.341
Claude found some base points too.

39
00:08:55.791 --> 00:09:11.080
But wait, there’s more... Each curve also comes with a base point, G, the fixed point that every ECDSA public key is a multiple of. The seed found above does not determine this G, and so another question arises: how were these base points generated?

40
00:09:11.530 --> 00:09:39.577
While checking the seeds, Claude also found where some of the base points came from. The base points of the six curves generated in May 1997 (P-192 and the five ANSI X9.62 example curves prime192v2, prime192v3 and prime239v1 to v3) come from the random number generator in FreeLIP, Arjen Lenstra 's long-integer arithmetic package.

41
00:09:39.697 --> 00:09:44.001
Early versions of Victor Shoup 's NTL library shipped the same code.

42
00:09:44.451 --> 00:09:45.965
The recipe here is simple:

43
00:09:46.415 --> 00:09:49.047
1. Seed the generator with a small integer.

44
00:09:49.287 --> 00:09:51.169
2. Throw away seven outputs.

45
00:09:51.409 --> 00:09:56.748
3. Generate candidate x-coordinates from 26-bit outputs reduced mod p.

46
00:09:56.988 --> 00:10:00.015
4. Repeat step 3 until x is on the curve.

47
00:10:00.465 --> 00:10:23.104
Claude found the generator seeds are 20000 for P-192, 20420, 20507 and 20509 for prime239v1 to v3, and 20512 and 20517 for prime192v2 and v3.

48
00:10:23.554 --> 00:10:39.863
As far as we know, no NIST base point has been explained before. The base points of P-224, P-256, P-384 and P-521 don’t fit this recipe; we weren’t able to explain how they were selected.

49
00:10:40.663 --> 00:10:41.765
Open questions.

50
00:10:42.215 --> 00:11:05.657
Not every 20-byte candidate seed could generate a viable curve and we observed that some potentially viable curves were skipped. For P-256, the published seed is candidate 1842, but candidate 876 of the same run also gives a prime-order curve of the right size and with parameters chosen the same way as on the published curve.

51
00:11:05.777 --> 00:11:22.500
P-224's run passed over three such curves, and the two runs behind the ANSI X9.62 example curves passed over seven more (see figure). We do not know what criteria may have been used, or whether this was an unintentional artifact.

52
00:11:22.950 --> 00:11:42.362
Because the number of skipped candidates is small, we do not believe it is plausible that weakened curves were selected. That would imply that weakened curves are common and easy to find. It is still conceivable that these curves were selected to have a specific property in principle by searching over timestamps to the random number generator.

53
00:11:42.482 --> 00:11:53.831
However, you would only need to do that if you were going to disclose the timestamp as some evidence that the seed was innocuously generated. Nothing in the numbers shows how many runs there were.

54
00:11:54.281 --> 00:12:16.700
There is also one seed we were unable to recover. The fifth binary seed, B-163, fits nothing Claude has tried and remains unexplained. Finally, we don’t know how the base points for P-224, P-256, P-384, and P-521 were generated. The same goes for the NIST binary curves.

55
00:12:17.500 --> 00:12:18.294
The bounty.

56
00:12:18.744 --> 00:12:26.622
The 36864 dollarsfor finding the seeds will be donated to the Internet Security Research Group.

57
00:12:27.422 --> 00:12:28.174
Who we are.

58
00:12:28.624 --> 00:12:40.955
This work was conducted at Anthropic by John Wood, Henry de Valence, Ava Howell, Zack Voase, Lucy Sweet, Amir Omidi, Paul Crowley, Iain McGinniss, Nicholas Carlini, and Steve Weis.

59
00:12:41.755 --> 00:12:42.731
Acknowledgements.

60
00:12:43.181 --> 00:12:59.256
We would like to posthumously recognize Jerry Solinas who took being labeled an “ evil Internet meme ” and the “ Yo La Tengo of NSA bogeymen ” with good humor. Also thanks to Filippo Valsorda for organizing the NIST Elliptic Curves Seeds Bounty.

61
00:13:00.056 --> 00:13:01.616
Code to reproduce the seeds.

62
00:13:02.066 --> 00:13:06.550
A code block of 32 lines appears here; see the original post for the code.

63
00:13:07.000 --> 00:13:08.360
The output of this code:

64
00:13:08.810 --> 00:13:13.294
A code block of 14 lines appears here; see the original post for the code.

65
00:13:14.094 --> 00:13:16.309
Code to reproduce selected base points.

66
00:13:16.759 --> 00:13:21.381
A code block of 44 lines appears here; see the original post for the code.

67
00:13:21.831 --> 00:13:23.190
The output of this code:

68
00:13:23.640 --> 00:13:27.915
A code block of 6 lines appears here; see the original post for the code.

69
00:13:28.715 --> 00:13:29.489
License.

70
00:13:29.939 --> 00:13:45.021
To the extent possible under law, the authors have waived all copyright and related or neighboring rights to the code on this page, dedicating it to the public domain under CC0 1.0 Universal (creativecommons dot org

71
00:13:46.021 --> 00:14:03.429
That was Claude reveals ECDSA curve origins, from Anthropic Research, published October 16, 2026. Read the original at anthropic dot com. This unofficial audio edition was generated automatically for the podcast Anthropic, Read Aloud.
