0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NIST P-256の“謎のシード”は笑い話ではなかった——30分で見えた乱数の正体

0
Last updated at Posted at 2026-10-17

30年間、空白だった場所

画像: eprint.iacr.org より
画像: eprint.iacr.org より
ECDSA の NIST 曲線は、現代の公開鍵暗号のど真ん中にある。P-256 は特に使われ方が広く、Web の証明書まわりでも頻出だ。その一方で、曲線パラメータの一部には seed が付いていて、そこから曲線係数を導く仕組みになっていた。問題は、その seed がどう作られたのか誰もはっきり説明できなかったことだ。

画像: www.anthropic.com より
画像: www.anthropic.com より

たとえば P-256 の seed は C49D3608 86E70493 6A6678E1 139D26B7 819F7E90 という 160 ビットの値として公開されている。見た目はただの16進数列だが、背景にはずっと不穏な空白があった。NSA が持ち込んだが、選び方は説明されていない。だから長年、「意図的に弱い曲線を入れたのではないか」という疑いが消えなかった。暗号の世界では、こういう空白はそれだけで疑念を育てる。

この疑問に対して、これまでの有力な説は「英語の一文を SHA-1 でハッシュしたものではないか」だった。実際、Jerry Solinas がそんな趣旨のことを話したという証言も出ていた。たとえば「Jerry deserves a raise」や「Bob and Jerry rule」のような、ちょっとした洒落をハッシュにしたのではないか、という話だ。Bounty まで用意され、パスフレーズ当てのような探索が始まった。

みんなが追っていた“ハッシュ説”

ただ、この説は妙に手触りがいいぶん、逆に怪しかった。もし本当に英語の文なら、カウンタの有無、句読点、改行、大小文字まで候補が無数にある。P-256 のような seed 1 個を狙うだけでも、当時の記憶違いに引きずられる余地が大きすぎる。Stephen A. Weis の整理でも、Jerry Solinas は seed を提供した本人としてはかなり確からしいが、肝心の生成法は本人の記憶からも消えていた可能性が高かった。

そこで 2023 年、秘密の文を総当たりする代わりに、別方向の賞金付き探索が始まる。焦点は「何を入力したか」ではなく、「どういうソフトで seed が出たのか」だった。これが重要だった。曲線の seed は、いきなり神秘的な文字列として現れたわけではないかもしれない。1990年代の C ライブラリが持つ疑似乱数生成器の出力なら、むしろ機械的な痕跡が残るはずだ。

この時点で狙いはかなり絞られていた。もし 1990年代の典型的な PRNG なら、今見れば出力の癖がある。出力の一部が切り詰められていたり、上位ビットに偏りが出たりする。つまり、seed の並びを「人間の文」として読むのではなく、「古い乱数生成器の断片」として読むわけだ。

乱数っぽさには、癖が出る

Anthropic の報告で面白いのは、Claude が最初から正解を知っていたのではなく、古い PRNG の“出力らしさ”を探る形で進んだ点だ。公開された seed の断片を 1 ビットずつずらしながら、1990年代のジェネレータの連続出力として整合するかを試したという。34 通りの組み合わせを確認し、そこで奇妙な規則性が見えた。

その一つが、binary 曲線用の 4 本の seed に含まれる 32 ビット語、計 20 個のすべてで最上位ビットが 0 だったことだ。これが偶然で起きる確率は 1/5,810 とされている。暗号の値としては小さい話に見えるが、こういう偏りは「ハッシュされた文」ではなく「疑似乱数生成器の出力」を疑うには十分だった。さらに、これは 48 ビット状態から上位 31 ビットだけを返す lrand48 の癖と一致する。つまり、seed が雑に作られたのではなく、ある種の古い乱数生成器の丸見えの跡かもしれない、ということになる。

ここから先の入り口も、英語の一文を探すのとはだいぶ違う。binary 曲線の seed なら、最初の 32 ビット語について隠れている 17 ビットを全部試し、次の語が続くかを見ればよい。P-256 を含む prime 曲線の seed は 1 出力あたり上位 8 ビットしか使っていないので、総当たりではなく別の道具が要る。それでも最終的には、P-256 は時刻で初期化した 1 回の実行の中で作られた 1,842 番目の曲線候補だった、という形で再現されたとされる。しかも他の曲線でも似たパターンが出た。単発の偶然ではなく、複数の seed に同じ癖が出たわけだ。

ここで疑問が変わる

もし seed が lrand48 の出力なら、次に気になるのは「いつ、何で初期化されたのか」になる。ここが本丸だ。srand48 の初期状態は低 16 ビットが 0x330E になる形をとるが、それだけなら 65,536 回に 1 回はたまたま一致しうる。だから“それっぽい”だけでは弱い。しかし、十個の prime-curve seed についてたどると、初期化時刻が 1997 年 5 月から 1998 年 4 月にきれいに収まった、というのが Anthropic の報告だ。binary-curve 側は 1984 年 2 月に対応し、二倍にすると 1998 年 4 月 17 日に合うものもあったという。

このへんで、話は単なる昔話ではなくなる。P-256 の seed が「何か面白い文章のハッシュ」ではなく、「Unix 時刻で初期化した古い PRNG の出力」だったとしたら、長年の疑いの形そのものが変わるからだ。しかもその時点で、seed の起源を理解するために必要なのは、ハッシュの元文探しではなく、1990年代の C ライブラリの挙動、出力の切り詰め、ビットの偏り、そして初期化時刻の復元になる。

ただし、ここから先はまだ話が終わっていない。seed の正体が見えたとしても、曲線にはもう一つ別の“固定点”がある。ベースポイント G だ。seed とは別に、これがどう作られたかも同じくらい気になる。Anthropic の報告では、P-192 と ANSI X9.62 のいくつかの曲線について、FreeLIP 由来の乱数生成器を使った生成元まで追えたとされる一方、P-224、P-256、P-384、P-521 のベースポイントは説明しきれていない。

seed が lrand48() の出力なら、何回まわして、どの時刻から始めれば P-256 の値に届くのか。その「1,842 番目」という数字が何を意味するのか。上位ビットの偏りと時刻復元が、どこまで確実で、どこから推測なのか。そこを見ないと、この発見の重みはまだ半分しか見えていない。

👉 続き(核心はここから)は PaPoo で読めます: https://papoo.work/doc/cc2a84257f7091ea

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?