Claude が ECDSA 曲線の由来を明らかにする

2026/10/17 3:55

Claude が ECDSA 曲線の由来を明らかにする

RSS: https://news.ycombinator.com/rss

要約▶

Japanese 翻訳:

2026 年 10 月、Anthropic の研究者 John Wood、Henry de Valence、Ava Howell および他が、NIST の素数曲線(FIPS 186-2)に対して長年にわたり専門家を困惑させてきた ECDSA 曲線のシードの起源について調査しました。これらのシードは、NSA が 2000 年に提供したパラメータです。ユーモアに満ちた理論では、Jerry Solinas が「Bob と Jerry に昇給を」といったパスフレーズからこれらを生み出したと提案されていましたが、Claude の高度な手法(LLL ベースの基底削減を含む)による分析により、シードはランダムなハッシュではなく、素数曲線については 1997 年 5 月と 1998 年 4 月の間の Unix タイムスタンプで種付けされた C ライブラリの

lrand48
関数の出力であり、バイナリ曲線については 1984 年 2 月かその半分としたタイムスタンプ(1998 年 4 月 17 日に対応)からの出力であることが明らかになりました。この手法は各候補あたり 20 バイトをサンプリングし(例:P-256 の場合は 1,842 回反復が必要)、さらに、6 つの曲線の基点 G は FreeLIP の RNG を特定のある整数シード(例:P-192 では 20,000)で使いながら生成されていることが判明しました。ただし、P-224、P-256、P-384、P-521 および一部のバイナリ曲線候補の基点についてはまだ説明されておらず、特に第 5 のバイナリのシード(B-163)は未解決のままです。これらのシードを見出すため、インターネット セキュリティ研究グループへの寄付を含む賞金として 36,864 ドルが設定されており、Jerry Solinas に追悼の称賛を与えるとともに、基礎的な暗号規格への透明性を向上させることを目的としています。

本文

ECDSA の起源に関する謎解明:単なるタイムスタンプから

暗号コミュニティが何十年も抱えていた ECDSA(楕円曲線デジタル署名アルゴリズム)の未解決課題に、ついに答えが出ました。今回の調査により、長年存在した「シード値の起源」についての疑問と懸念が解消されました。これら曲线にはバックドアや意図的な弱点はなく、安全性に確信を持つことができます。 多くの研究者は既にこれらの曲線に信頼を寄せていましたが、今回の発見によってその根拠がさらに強固なものになりました。

ECDSA の背景と長年の謎

ECDSA は最も広く利用されている楕円曲線暗号の標準規格であり、2000 年に NIST が FIPS 186-2 として採用しました。この規格には一連の標準楕円曲線がリストされています。

  • シードパラメータ: 素数体およびバイナリ体上の曲線については、「シード」と呼ばれるパラメータが定義されていました。
  • 欠乏した説明: これらのシード値は NSA から提供されたにもかかわらず、その出自や生成ロジックについての明文化された説明が存在しませんでした。
  • 主な懸念: 例として NIST P-256 のシード
    C49D3608...
    ですが、それがどこから来たのか不明という状況は、長年「バックドア」や意図的な弱点が含まれているのではないかという疑念を生み出していました。

Neal Koblitz 氏や Alfred Menezes 氏が論じたように、この謎を探るためのアマチュアの調査や、報奨金付きの悬赏活動が数年来行われてきましたが、解決にいたりませんでした。Jerry Solinas 氏のユーモアあふれる仮説(昇給を願うフレーズのハッシュなど)も、同僚たちが亡くなるまで検証されることはありませんでした。

シードの真の原因:Claude の発見

Anthropic の従業員が内部の研究モデル「Claude」に問いかけたことで、この謎はついに解けました。

  • 仮説の否定: 「ユーモアあふれるフレーズのハッシュ値である」という長年の仮説は誤りでした。
  • 真の原因: NIST P-192, P-256, P-384 などすべてのシードは、**C ライブラリの
    lrand48
    擬似乱数生成器(RNG)**による出力です。
  • 種付け元: その RNG を初期化するものこそが、Unix タイムスタンプでした!

使用されたアルゴリズムの概要

シード生成プロセスは以下の通りです。

  1. 初期化: Unix タイムスタンプ ($t$) で擬似乱数生成器(RNG)を初期化。
  2. サンプリング: 反復処理 ($n$) を行い、各回から 20 バイトずつ抽出します(例:P-256 では 1842 回の反復)。

発見プロセス:どのように見付けたか?

Claude はフレーズ検索ではなく、曲線生成ソフトウェアの動作予測からアプローチしました。

ステップ 1: 予察と弱点の悪用

  • 1990 年代の C ライブラリに同梱されていた
    lrand48
    を使用していたと推測。
  • この古い PRNG は弱いため、出力パターンを特定し内部状態(初期化値)を復元できる可能性が高い。

ステップ 2: スキャンとパターン認識

  • シードのビットをずらしてテストし、34 の組み合わせをスキャン。
  • 決定的な発見: 上位ビットに「すべてゼロ」のパターンが複数見られた。これは偶然ではあり得ない(確率 $1/5^{810}$)。

ステップ 3: アルゴリズムの特定

  • このパターンは、48 ビットの状態のうち上位 31 ビトのみを返す線形合同式ジェネレーター(LCG)
    lrand48
    の特徴と一致。
  • 状態復元:
    lrand48
    の内部状態を復元する教科書的な格子問題として LLL アルゴリズムを使用し、成功。

ステップ 4: 全曲線の検証

  • 素数曲線: すべて同じパターン
    lrand48() >> 23
    を持つことが確認。
  • バイナリ曲線: 初期化には
    _srand48(time / 2)
    が使用されていた可能性があり、1997-1998 年間のタイムスタンプに対応していることが判明。

思考プロセス

  • 「25 年前の謎を解明した」という驚きから始まり、「現実的にはあり得るのか?」という懐疑を経て、確率的な一致が偶然ではないと判断。
  • 「32 ビットのシードからの 160 ビット一致」は偶発的な一致とは不可能であるため、これが真の現実であると結論づけた。

基点(Base Point)の起源も解明

シードだけでなく、すべての ECDSA 公開鍵の基礎となる基点 $G$ の生成方法も見出されました。

  • アルゴリズム: Arjen Lenstra 氏の FreeLIP や Victor Shoup 氏の NTL ライブラリに含まれる乱数生成器を使用。

    1. 小さな整数で種付けする。
    2. 出力の最初 7 つを破棄する(ウォームアップ)。
    3. 次のビットから $x$ 座標を生成し、曲線上にあるか検証を繰り返す。
  • 特定されたシード値:

    • P-192
      :
      20000
    • prime239v1〜v3
      :
      20420
      ,
      20507
      ,
      20509
    • prime192v2/v3
      :
      20512
      ,
      20517

注釈: P-224、P-256、P-384、P-521 の基点についてはまだ説明がついていない残存問題です。

未解決の問題とセキュリティへの影響

今回の発見は暗号学的な破綻や新たな攻撃を示すものではありません。

  • 安全性の向上: パラメータが「バックドア」ではなく、誰でも再現可能な公開アルゴリズム(時計+疑似乱数)」によって選択されたことが確認されました。改ざんの余地が極端に減り、パラメータの安全性に確信を持てます。
  • スキップされた候補: すべてのランダムな試行から有効な曲線が生成されるわけではなく、いくつかの候補がスキップされていた可能性があります。しかし、その数が小さいため、「弱体化された曲線を意図的に選択した」という可能性は低いです。

報奨金と謝辞

  • 報奨金の分配: シード発見のため支払われた
    $36,864
    は、Internet Security Research Group (ISRG) に寄付されました。
  • 関係者: 本調査は Anthropic の John Wood、Henry de Valence など多数のチームメンバーによって行われました。
  • 追悼と感謝: Jerry Solinas 氏のユーモアなアプローチと、NIST 楕円曲線シード報奨金を主催された Filippo Valsorda 氏に深く感謝いたします。

シードを再現するためのコード

以下の Python スクリプトは、タイムスタンプから NIST P-256 のシードを正確に再生成します。

1. シード生成と検証スクリプト

from datetime import datetime, timezone

def unix(when):
    return int(datetime.fromisoformat(when).replace(tzinfo=timezone.utc).timestamp())

def candidate(t, n, per, shift, width):
    x, out = (t << 16) | 0x330E, ""                      # srand48(t) が設定する状態
    for i in range(per * n):
        x = (0x5DEECE66D * x + 0xB) % 2**48              # lrand48 の一ステップ
        if i >= per * (n - 1):
            out += "%0*X" % (width, x >> shift)
    return out

PRIME = {  # srand48(time); 20 バイトあたりの候補: lrand48() >> 23
    "prime239v1": ("1997-05-15 15:49:03", 2185),
    "prime239v2": ("1997-05-15 15:49:03", 2320),
    "prime239v3": ("1997-05-15 15:49:03", 3048),
    "P-192":      ("1997-05-18 14:45:34", 139),
    "prime192v3": ("1997-05-18 14:45:34", 5228),
    "prime192v2": ("1997-05-18 14:45:34", 6013),
    "P-521":      ("1997-08-08 01:12:04", 1136),
    "P-256":      ("1997-08-16 01:52:34", 1842),
    "P-384":      ("1997-08-30 14:50:08", 2688),
    "P-224":      ("1998-04-03 12:52:07", 7026),
}

BINARY = {  # srand48(time / 2);5 ワードあたりの候補: lrand48()
    "B-233": ("1998-04-17 15:24:18", 155),
    "B-283": ("1998-04-17 15:27:44", 32),
    "B-409": ("1998-04-17 15:30:18", 60),
    "B-571": ("1998-04-17 15:32:08", 73),
}

print("=== Prime Curves ===")
for name, (when, n) in PRIME.items():
    print(f"{name:10} {when} {n:5} {candidate(unix(when), n, 20, 40, 2)}")

print("\n=== Binary Curves ===")
for name, (when, n) in BINARY.items():
    print(f"{name:10} {when} {n:5} {candidate(unix(when) // 2, n, 5, 17, 8)}")

コード実行結果の要約

曲線名タイムスタンプ反復回数再現されたシード (一部)
P-256
1997-08-16 01:52:34
1842
C49D3608...
(一致)
P-384
1997-08-30 14:50:08
2688
A335926A...
P-224
1998-04-03 12:52:07
7026
BD713447...

重要: P-256 のシードは、このアルゴリズムで完全に再現可能です。これは偶然の一致ではなく、意図的な(あるいは無作為ながらも一貫した)生成プロセスである証明です。


選択された基点を再現するためのコード

FreeLIP ライブラリの乱数生成器を用いて、基点 $G$ の座標を復元するスクリプトです。

2. 基点(Base Point)生成スクリプト

M, A = 2**107 - 1, pow(3, 121, 2**107 - 1)       # zrandom: state = state * 3^121 mod (2^107 - 1)
P192 = 2**192 - 2**64 - 1
P239 = 2**239 - 2**143 - 2**95 + 2**47 - 1

CURVES = [  # name, LIP seed, p, b, published Gx   (a = -3 throughout)
    ("prime192v1", 20000, P192,
     0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1,
     0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012),
    ("prime239v1", 20420, P239,
     0x6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a,
     0xffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf),
    ("prime239v2", 20507, P239,
     0x617fab6832576cbbfed50d99f0249c3fee58b94ba0038c7ae84c8c832f2c,
     0x38af09d98727705120c921bb5e9e26296a3cdcf2f35757a0eafd87b830e7),
    ("prime239v3", 20509, P239,
     0x255705fa2a306654b1f4cb03d6a750a30c250102d4988717d9ba15ab6d3e,
     0x6768ae8e18bb92cfcf005c949aa2c6d94853d0e660bbf854b1c9505fe95a),
    ("prime192v2", 20512, P192,
     0xcc22d6dfb95c6b25e49c0d6364a4e5980c393aa21668d953,
     0xeea2bae7e1497842f2de7769cfe9c989c072ad696f48034a),
    ("prime192v3", 20517, P192,
     0x22123dc2395a05caa7423daeccc94760a7d462256bd56916,
     0x7d29778100c65a1da1783716588dce2b8b4aee8e228f1896),
]

def base_point_x(seed, p, b):
    state = seed                         # zrstarts(seed)
    def limb():                          # zrandom(2^26): 新しい状態の下位 26 ビット
        nonlocal state
        state = state * A % M
        return state % 2**26
    for _ in range(7):                   # まず 7 つの単一リム(limb)の抽出が行われる
        limb()
    limbs = -(-p.bit_length() // 26) + 1 # zrandomb(p): p のリム数に 1 を加え、上位リムから
    tries = 0
    while True:
        x = 0
        for _ in range(limbs):
            x = x << 26 | limb()
        x %= p
        tries += 1
        if pow(x**3 - 3*x + b, (p - 1) // 2, p) == 1:   # x は曲線上にあるか?
            return x, tries

print("=== Base Point Verification ===")
for name, seed, p, b, gx in CURVES:
    x, tries = base_point_x(seed, p, b)
    print(f"{name:20} seed {seed}  tries {tries}  matches published Gx: {x == gx}")

検証結果

すべての曲線について、計算された基点座標が NIST の公開値と完全に一致することが確認されました。

曲線名シード (Seed)試行回数 (Tries)適合性
prime192v1
200002True
prime239v1
204203True
prime239v2
205072True
prime239v3
205091True
prime192v2
205125True
prime192v3
205171True

ライセンス情報

本ページに含まれるすべてのコードは、法律の許す限り CC0 1.0 ユニバーサルライセンスの下で公開されます。

  • 著作権放棄: 著者は著作権および関連する権利を放棄し、パブリックドメインとして寄付しています。
  • リンク先: CC0 1.0 Universal

関連コンテンツ(他の研究事例)

今回の調査と同じく、AI モデル「Claude」を応用してセキュリティや効率性を向上させた他の成果物も参照できます。

  • [量子回路の効率化] Claude を用いてより効率的な量子回路を設計する
    • 8 つの量子回路に対する仕様を提供し、既存の最良の公開された circuit を改善。実用的な量子コンピュータへの到達が近づく可能性があります。
  • [AI の経済への影響] AI の期待値ギャップ
    • 今後数年間で AI が経済をどのように再形作っていくかに関する調査証拠の発表。
  • [雇用の変遷] Anthropic における雇用の変化
    • AI が仕事の組織化、採用、労働需要をどのように変化させるかを示す指標となる事例。

同じ日のほかのニュース

一覧に戻る →

2026/10/17 4:47

FLUX 3 イメージ・クライン

## Japanese Translation: Black Forest Labs は、テキストから画像への変換、ピクセルレベルの編集、および複数参照(最大 10 件)を用いた生成を実現するために設計された、56 億パラメータを有する画期的なオープンウェイトモデル「FLUX 3 Image Klein」を公開しました。内部評価においてオープンモデルで首位にランク付けされ、Ideogram V4.5 や FLUX.2 よりも少ない 38% パラメータ数ながら、消費ハードウェア上で優れた効率性を発揮し、より大規模なモデルを上回る性能を発揮しています。本モデルは、微調整用のベースモデル(〜11.2 GB VRAM[BF16]または 5.6 GB[FP8]を必要とします)と、低遅延生成に最適化されたステップ蒸留版の 2 つのパッケージを提供します。NVIDIA との提携を活用し、ComfyUI または Diffusers を通じて RTX シリーズの GeForce GPU(VRAM 8GB 以上でも動作可能)上で FP8、INT8、NVFP4 のビルドを実行できるように対応しています。生成速度は印象的で、RTX 5090 では約 4 秒で 1MP の画像を、RTX 4070 では 9 秒未満で生成でき、将来のハードウェアではサブ秒単位の生成が可能になる可能性があります。FLUX Kommunity License の元、年間の収益が 500 万ドル未満の企業には商用利用が無料で許可され、ただし出典表示は必要です。今後の計画として、プロンプトアップサンプリングなど高度なタスク向けの有料 API を提供する予定です。主要ライブラリからの Day-One サポートと、Cinder によるセーフティレッドチームingiの実施により、このリリースは個人クリエイターおよび中小企業にとって高品位の視覚制作ツールの民主化を推進します。

2026/10/17 3:32

ブレイクされたPS5で動作する Llama.cpp:コンソール上で GGUF モデルを任意にネイティブ実行可能

## Japanese Translation: PlayStation 5 は、クラウドサービスや追加のハードウェアを必要とせず、コンソール上で高度なプライベート AI モデルをローカルに動作させるようになり、特にファームウェア 7.00–13.60 を搭載したジャイブされた PS5 コンソールを対象としています。llama.cpp の改変版(Vulkan バックエンドおよび共有メモリを採用)を利用することで、RDNA 2 GPU 上で直接多様な人工知能アプリケーションを動作させるためにメモリおよびキャッシュの使用方法が最適化されています。このセットアップは etaHEN という特定のインストールペイロードを必要とし、既存のジャイブツールである kstuff-lite および ShadowMountPlus(推奨ツールには elfldr と ftpsrv が含まれる)と統合されます。アプリケーションインターフェースはデュアルショックコントローラーによる操作でアクセス可能であり、Home、Models、Console、API、Settings のセクションを含んでいます。ユーザーはすぐに画像分析や Gemma 4 および MiniCPM-V などの中級モデルに対するチャットコンプリートなどの強力な機能をアクセスできます。リアルタイムのパフォーマンス監視は `ps5-exporter` が担当しており、温度、消費電力、GPU、CPU ロードなどのメトリクスを表示します。アプリはロードされた GGUF モデルに対して利用可能なメモリの中で最长的なコンテキストと最適なキャッシュ適合を自動的に選択し、Hugging Face から内部ストレージ(M.2)または USB ドライブへのダウンロードによって管理できます。特に注目すべきは、小さなモデルが PS5 Slim ハードウェア上で最大 207 トークン/秒の驚異的な速度を実現しており、モデルサイズと量化に基づいて ~20~207 トークン/秒のパフォーマンス範囲があることです。今後の更新では、USB ドライブまたは内部ストレージからロードされる新しいファイルに対する自動管理メモリ割り当てが含まれる可能性が高いです。この進歩により、愛好家は専用の API エンドポイント(`/v1/systemone`)および標準チャット API を通じて Ollaya 駆動の Jev 様(Clef、OpenJev など)といった高度な意思決定モデルと直接相互作用できるようになり、ゲームコンソールのローカル AI パフォーマンスにおける大きな飛躍を達成しながらも、完全なプライバシーを保ち外部データ依存性を排除します。インストールには `PPSA99575` フォルダを `/data/homebrew` にコピーし、`http://<console>:8081` でサーバーにアクセスする必要があります。

2026/10/16 23:44

トロンテッドでのウェイモ

## Japanese 翻訳: サマリー: ウェイモは、フル自律運転のライドヘイリングサービスをカナダへの公式展開を開始し、2028年までにトロントでの目標着陸を目指しています。この展開を支えるために、ウェイモはエンドツーエンドの車隊管理サービスを提供するためにトロントを拠点とするElement Fleet Managementと提携しています。両社は投資信託基金を通じて共同投資の歴史を持ち(カナダ年金計画投資委員会)、Magna Internationalとの製造パートナーシップも含んでいます。両社は車隊メンテナンス、検証運転、カスタマーサービス、オペレーションにわたる数百の新しい役割への投資を計画しています。展開は安全を最優先とする厳密な段階的アプローチで行われ、当初は訓練された自律運転専門家が手動で運転し、検証および安全性テストを実施します。これは、最近のローカル街道ネットワークの高解像度マッピングによって支援されます。4 億 km に及ぶ自律走行キロメートルからの安全データは、ウェイモ・ドライバーが人間の運転者と比較して深刻な事故を95%(20倍)少ない関与を示しています。このイニシアチブは包容性を強調しており、CNIB、BALANCE for Blind Adults、Epilepsy Ontarioなどの団体と協力し、アクセシブルなソリューションを作成しています。BALANCEのMichelle McQuiggeは、ウェイモが視覚障害コミュニティとの早期関与を称賛しました。このサービスは、トロントの既存の交通生態系(自転車レーンや公共交通機関を含む)を補完し、あらゆる気象条件下での信頼性のある移動性を提供することを目的としています。居住者はwaymo.com/waymo-in-canadaに登録することで、サービスが正式にデビューした際のアップデートを受け取ることができます。