乱数生成に問題があると、なぜビットコインを盗まれるのか

前の記事では、Coldcard が5年間、シードをハードウェア乱数ではなくソフトウェアの擬似乱数で作っていたこと、その結果として実効エントロピーが Mk3 で約40ビット、Mk4 世代で約72ビットまで落ちていたことを見ました。 ここではその続きとして、エントロピーが低い状態が、どうやって資金の流出につながるのかを追います。

鍵を守っている二つの条件

ビットコインの秘密鍵は、実質 256 ビットの乱数です。 公開鍵やアドレスは秘密鍵から一方向に導出され、逆算はできません。 では何が鍵を守っているかというと、条件は二つあります。 誰にも漏れていないことと、誰にも当てられないことです。

前者は前提で、シードを盗み見られた時点で終わりです。 フィッシングもマルウェアも、狙っているのはこちらです。 見落とされやすいのは後者で、こちらを支えているのは総当たりの物理的な不可能性です。 2²⁵⁶ という数は宇宙の原子数より桁違いに大きく、地球上の全計算資源を使っても永遠に終わりません。

今回の事件で崩れたのは、後者だけです。 秘密鍵を誰にも見せず、フレーズも漏らさず、フィッシングにも引っかからなくても、攻撃者が探索範囲を現実的なサイズまで絞り込めれば、それだけで鍵は割れます。 ユーザーは何も間違えていないのに盗まれました。

鍵のパターン数を決めるエントロピー

エントロピーは、鍵が実際に何通りありうるかを対数で測った量です。 128 ビットなら 2¹²⁸ 通り、40 ビットなら 2⁴⁰ 通り。 鍵の見た目の長さ(256 ビット)ではなく、生成過程で本当に入った不確実性の量でパターン数が決まります。 Coldcard の場合、狙いは 128 ビットで、実際に入っていたのは Mk3 で約40ビット、Mk4 / Mk5 / Q で約72ビットでした(Coinkite の技術背景)。

この差が総当たりの現実味をどう変えるかは、桁で並べると見えます。

エントロピー 取りうる鍵の数 総当たりの現実性
256 ビット(24語シードの正常値) 天文学的 不可能
128 ビット(安全性の目標値) 3.4×10³⁸ 不可能
72 ビット(Mk4/Mk5/Q) 4.7×10²¹ 国家級でも困難
40 ビット(Mk3) 1.1×10¹² 資金のある攻撃者なら現実的
32 ビット(攻撃者が多くを掴んでいた場合の最悪値) 4.3×10⁹ GPU を数枚並べれば数時間

この桁に落ちたことの意味は「一瞬で割れる」ではありません。 候補を1つ試すたびに鍵導出と楕円曲線の計算が要るので、ノートPCで片手間に終わる規模ではありません。 それでも GPU やクラウドを並べれば、数時間から数週間で終わります。 「不可能」だったものが「予算と時間の問題」に変わった、というのがこの桁の意味です。

具体的な攻撃手順(今回実際に起きたこと)

攻撃者は次の流れで鍵を「再現」します。 SHA256 のハッシュを何段かけても、入力の種類が2⁴⁰通りしかなければ出力も高々2⁴⁰通りにしかならない点がミソです。 ハッシュは値を撹拌するだけで、種類を増やせません。

  1. 照合用の手がかり(オラクル)を得る ブロックチェーンは公開台帳なので、狙ったウォレットのアドレスや公開鍵は誰でも見られます。 攻撃者はこれを「正解チェック用の鍵穴」として使います。

  2. 探索空間を絞る バグった生成器の初期値は、チップID、起動タイミング、乱数の呼び出し回数といった限られた要素で決まります。 攻撃者はこれらの取りうる範囲を列挙します(Mk3 で約2⁴⁰通り、Mk4 世代でも上限が約2⁷²通り。攻撃者の持つ情報次第ではさらに狭まります)。

  3. 候補を片っ端から回す 壊れていたのは乱数そのものではなく、それを作る生成器です。 生成器は決定論的なアルゴリズムなので、初期値が1つ決まれば、そこから出る値の列も、そこから導かれるシードもアドレスも、最後まで確定します。 だから攻撃者は、候補の初期値ごとに実機とまったく同じ計算を手元で再現し、手順1で得た本物のアドレスと一致するか照合できます。 被害者の端末に触れる必要は一切ありません。オフラインで、攻撃者のマシンだけで完結します。

  4. 一致したら全額移動 一致するシードが見つかれば、そのウォレットの全アドレスの秘密鍵が芋づる式に手に入ります。 あとは送金トランザクションを組んで掃き出すだけです。

しかも手順3の照合はハッシュテーブルを引くだけなので、候補1件あたりのコストはほぼ変わりません。 つまり攻撃者は特定の誰かを狙う必要がない。 候補を全部展開して、資金のあるアドレス全体と突き合わせれば、同じバグを踏んだ全ユーザーが一度に引っかかります。

今回は 2026年7月31日の 01:31〜01:56 UTC のわずか25分間で、約500個のシングルシグ・ウォレットから 594 BTC(約3,800万ドル) が抜かれました。

ただし、この25分は探索にかかった時間ではありません。 取引の特徴(おつりの出力が無く、手数料が高値で固定された自動化された動き)から、攻撃者はあらかじめ用意した秘密鍵のリストを持っていたと見られています。 割る作業はもっと前に終わっていて、25分という短さが物語るのは探索の軽さではなく、警告が行き渡る前に一斉に掃き出したという運用の側です。

なぜ気づけず、防げないのか

このクラスの脆弱性が特に厄介な理由を整理すると:

  • ユーザー側に落ち度が全く要らない。鍵の漏洩もフィッシングもマルウェアも不要で、生成した瞬間に運命が決まっています。
  • 無症状で潜伏する。2021年3月のライブラリ移行で混入し、約5年間バレませんでした。弱い鍵は普通の鍵と見た目が完全に同じで、テストでも「乱数はランダムに見える」ため検出しにくいのです。統計的にランダムに見えることと、予測不可能であることは別物です。
  • 公開台帳が攻撃を助ける。銀行と違い、照合に使うアドレスと残高が最初から全世界に公開されています。攻撃者は「どのウォレットに一番残高があるか」を見て、費用対効果の高いものから狙えます。
  • 後追いが効かない。一度弱いシードで資金を置いたら、鍵を作り直して新しいアドレスへ移すしかありません。過去に受け取った時点で既に露出しています。

では、この構造を踏まえて利用者は何をすればいいのか。 次の記事で対策を扱います。


Sources: