リカバリーフレーズはどれほど推測しにくいのか?ColdCardはそれを簡単にした

キーストーン
• 欠陥のあるColdCardのファームウェアアップデートにより、ハードウェア乱数生成器からソフトウェアの疑似乱数生成器へサイレントにフォールバックしました
• これにより、Mk2/Mk3では可能なリカバリーフレーズのプールが2^256から約2^40(約1兆1,000億)に縮小し、Mk4/Mk5/Qでは約2^72になりました
• 攻撃者はデバイスをハッキングしたのではなく、もはや推測が難しくなくなったリカバリーフレーズを単純に総当たりで当てました
• 正しく生成された24単語のBIP-39フレーズは、次の1秒間に地球がガンマ線バーストで絶滅する確率の約5×10^60倍もの衝突困難性を誇ります
• 真の乱数生成器は物理的なノイズを利用するため、デバイスのモデル、シリアル番号、起動時間、完全なソースコードが分かっても、攻撃者は何も解読できません
This article is written as a plain-language explainer. To keep things easy to follow, some technical details have been simplified or turned into analogies, and may differ from how things actually work under the hood. If you need to make decisions about securing real assets, please go by the official announcements and consult a professional.
2026年7月30日、ビットコインチェーン上で異様な出来事が発生しました。わずか15分ほどの間に、500個のアドレスから約 594.48 BTC(約 3,800万米ドル)が単一のアドレスへと送金されたのです。その直後、そのうち約 562 BTC が別のアドレスへと移動されました。これが通常の送金活動でないことは明らかで、後にハッカーが盗んだ資金を移動させたものであることが確認されました。オンチェーン記録
500 source addresses → one consolidation address (~594.48 BTC / ~$38M) → a second address (~562 BTC)
被害者が次々と名乗り出る中で、共通の事実が浮かび上がりました。全員が Coldcard ハードウェアウォレットを使用していたのです。同日、Coldcard の製造元である Coinkite はセキュリティ警告を発出し、公式調査および独立した技術解析の両方により、ColdCard ウォレットに何らかの不具合があったことが確認されました。問題は乱数の生成方法にあり、攻撃者は Coldcard を物理的にハッキングする必要すらなかったのです。ユーザーのリカバリーフレーズを推測するだけで、資金を抜き取ることが可能でした。
では、実際には何が起きたのでしょうか?
この事件全体は、リカバリーフレーズの生成という特定のステップでつまずいていました。
例え話をしましょう。通常、ハードウェアウォレットがリカバリーフレーズを生成するとき、それはまるでほぼ無限にある鍵の保管庫に手を突っ込み、そこからランダムに1つを取り出してあなたに手渡し、その鍵があなただけの金庫を開けるようなものです。しかし、ColdCard のソフトウェアにはバグがあり、鍵を取り出す範囲がその巨大な保管庫全体から、1つの小さな引き出しへと縮小してしまいました。この引き出しの中にある鍵を1つずつ試していき、開いた金庫の中身を空にするだけでよかったのです。
もちろん、この例え話は正確ではありませんが、原則はその通りです。より正確に言うなら、ColdCard のファームウェアチームによる不具合のあるアップデートにより、リカバリーフレーズを生成する際にウォレットがより安全なハードウェア乱数生成器を呼び出せず、代わりに「疑似乱数」のソフトウェア乱数生成器を使用してしまうという事態が発生しました。生成された「パスワード」、つまりリカバリーフレーズは単純に十分な安全性を備えておらず、それが今回の事件につながったのです。
ここで、なぜ自分のリカバリーフレーズが乱数と関係があるのか、ハッカーはどうやって金庫のパスワードを見つけ出したのか、そして乱数生成器とは一体何なのかと疑問に思われるかもしれません。お待ちください。順を追って説明しましょう。
リカバリーフレーズの本当の正体とは?
なぜリカバリーフレーズが自分の資産であることの証明になるのか?
リカバリーフレーズがどこから来るのかを見ていく前に、まずはっきりさせておかなべきことがあります。それは、資産、ウォレット、そしてリカバリーフレーズの関係性です。
実は、リカバリーフレーズは金庫の鍵のようなものではありません。ブロックチェーンの基盤設計において、あなたの資産は銀行にある現金のように、最初からチェーン上に堂々と存在しています。現金そのものには所有者の名前が印刷されているわけではなく、誰もが見ることができ、理論上は誰でもそれを使って何らかの操作を行う権利を持っています。しかし、当然ながら誰もが無制限に引き出せるわけではありません。なぜなら、何かを転送する前に、チェーンはあなたがこれらの資産を保有しており、あなたのものであるという「証明」を提示することを求め、その「証明」こそがリカバリーフレーズだからです。
言い換えれば、チェーン上でリカバリーフレーズを入力したのが誰であれ、たとえ操作しているのがあなた自身でなくても、それが指し示す資産はその人のものとなります。チェーンに見えているのは、誰かが有効な所有権の証明を提出したという事実だけだからです。
Someone initiates a transfer → the chain asks for proof → a signature derived from the recovery phrase → verified, the assets can move
チェーンが信頼するのは人間ではなく、証明です。
したがって、リカバリーフレーズの本質は、権利書や「特別な番号」が刻印された公印に近いものです。印影そのものは簡単に偽造できますが、実際に改ざん不能にしているのはそれが持つ特別な「番号」であり、設計上、その番号を他の誰かが推測することは実質的に不可能です。
つまり、すべての問題はこの「番号」の文字列に行き着きます。それはどこから来るのでしょうか?そして、どのようにしてあなたの資産を守っているのでしょうか?
リカバリーフレーズはどのようにして数字から単語に変換されるのか?
ご存知の通り、コンピューターは2進数で動作します。テキスト、画像、パスワードなどは、一度コンピューター内に入ると、すべて0と1の文字列に変換されます。リカバリーフレーズも例外ではありません。
例えば、コンピューター内では次のような見た目をしています:
010101000010
しかし、こう疑問に思うかもしれません。「リカバリーフレーズは英語の単語の集まりであって、数字ではない。一体どうやってあの0と1の文字列から生まれてくるのか?」と。
仕組みはそれほど複雑ではありません。まず、どのビットの塊がどの単語に対応するのかを定義した「辞書」を用意します。分かりやすくするために、わずか16語の小さな辞書を作ってみましょう:
次に、このコードの文字列を3つに分割します:
0101 | 0100 | 0010
そして、これら3つの塊を辞書で引き当てます:
0101 → squirrel
0100 → coffee
0010 → moon
そうして、ほとんど読み取れなかったバイナリの文字列が、簡単に書き留められる3つの単語に変換されます。
squirrel coffee moon
これがリカバリーフレーズの根底にある原則です。それはどこからともなく現れた単語の集まりではなく、1つの長い数値を多くの小さなチャンクに分割し、固定された単語リストを使用して各チャンクを単語に翻訳したものです。
もちろん、実際のリカバリーフレーズはこの例よりも少し複雑です。単語リストは大きく、数値は長く、チェックサム情報が追加されます。しかし、核心となるロジックは変わりません。リカバリーフレーズとは、あの数値の文字列を、人間が書き留め、保管し、復元しやすいように別の方法で表現しただけのものです。
24単語を推測することは一体どれほど難しいのでしょうか?
前置きはさておき、ついに実際のリカバリーフレーズについて話すことができます。現在、それらを生成するための規格はいくつか存在しており、簡単に言えば「多くの異なる辞書」が存在すると考えることができます。最も広く使用されているBIP-39を取り上げ、リカバリーフレーズのセキュリティが実際にはどこから来るのかについて説明しましょう。
BIP-39の辞書には合計2,048語が収録されており、私たちの例で使用したものよりもはるかに多いですが、基本的に仕組みは同じです。これもまた、非常に長い1つのバイナリコードの文字列から切り出されています。具体的には、264ビットの文字列からなり、11ビットごとに1つの単語を表し、各単語には2^11、つまり2,048通りの可能性があり、辞書の2,048語と正確に一致します。
しかし、コンピューターはバイナリで動作するため、生成される乱数は2の倍数でしか表現できません。そのため、264ビットの乱数を直接生成することはできません。そこで、まず256ビットの乱数を生成させ、最初の8桁を末尾に移動させるという方法をとります。これで264ビットとなり、24単語のリカバリーフレーズに必要な長さが確保されます。
先ほど確認した内容を覚えていますか? リカバリーフレーズ(私たちの「公印」)のセキュリティは、1つの特別な数値の文字列に由来しており、その数値こそがフレーズの背後にある乱数なのです。また、印章が安全である正確な理由は、誰もその印章にどのような数値が刻まれているかを推測できないからだと述べました。間違った数字を推測して他人の資産を奪うことなど、当然ながらできません。では、その数値を推測するのはどれほど難しいのでしょうか? それは乱数の長さに依存します。256ビットの乱数には、なんと2^256通りの可能性があり、つまり2^256通りのリカバリーフレーズ、あるいは2^256通りのウォレットアドレスが存在することになります。
その数はどれほど大きいのでしょうか? 観測可能な宇宙に存在する素粒子の数は通常約10^80個と言われていますが、2^256 ≈ 10^77です。言い換えれば、宇宙に存在するほぼすべての観測可能な素粒子に1つずつウォレットアドレスを割り当てることができるほどの数です。また、全人類の人口は約2^33にすぎないため、一人あたり約2^223個のアドレスを受け取ることができ、それは1の後に0が67個続く数字になります。
10,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
したがって、ハッカーがあなたのリカバリーフレーズを推測しようとすることは、それらすべての住所の中から残高のある1つの住所を当てようとするようなものです。それは途方もなく困難です。
しかし、この時点で「コンピューターが誤って2つの同一のウォレットアドレスを生成してしまうことはないのか? そうなれば、後から作った人が最初の人の資産を持ち逃げできるのではないか?」と疑問に思う人もいるかもしれません。もっともな疑問であり、その可能性は技術的には存在します。しかし、現実世界において、それが起こることはありません。独立して正しく生成された2つの24単語のBIP-39リカバリーフレーズが同一になる確率は、1 / 2^256 ≈ 8.6 × 10^-78 です。
比較として、信頼できる論文によると、今後1秒以内に地球が大量絶滅を引き起こすほどのガンマ線バーストに直撃される確率は約 4.4 × 10^-17 と見積もられています。つまり、リカバリーフレーズの衝突は、大量絶滅イベントよりもおよそ 5 × 10^60 倍も起こりそうにないということです。
これにより、リカバリーフレーズを推測することがどれほど困難であるかがお分かりいただけるでしょう。
ColdCardはいったい何をやらかしたのか?
2^256から2^40への転落
リカバリーフレーズの背後にある本当の仕組みを理解すれば、ColdCardのどこに問題があったのかも簡単に理解できます。
ColdCardチームによる1つの欠陥のあるアップデートにより、リカバリーフレーズを生成する際、本来であれば2^256通りであるはずの可能なフレーズがわずか2^40通りになってしまいました。これは圧倒的なスケールの乖離です。40ビットの乱数からどうやって24単語が生成されるのかと疑問に思うかもしれませんが、そこにこだわる必要はありません。ここで知っておくべきなのは、このバグにより、ColdCardで生成されたウォレットアドレスが推測される確率が劇的に高まったということです。
影響の範囲について正確に述べておくと、モデルによって影響の度合いは異なります。ここで議論されている約40ビットは主にMk2およびMk3に当てはまり、Mk4、Mk5、Qの推定値は約72ビットとなっています。
両者を並べてみると、その答えは一目瞭然です。ColdCardから生成されたリカバリーフレーズの総数は、世界でわずか1,099,511,627,776通りしかなかったのです。ハッカーにとって必要なのは、高性能マシンでそれらを1つずつ総当たりで検証することだけであり、資金を持ち逃げされる現実的なリスクがありました。依然として困難な作業ではありますが、もはや人類が手を出せないほどの規模ではありません。
その時点でも、事態はまだ壊滅的な状況というわけではありませんでした。1,099,511,627,776は依然としてかなり大きな数字であり、ネットワークの遅延も加われば、ハッカーが残高のあるアドレスに行き着くまでには何年もの試行が必要だったかもしれません。
しかし不運なことに、ColdCardのミスは、それらの取りうる値を生成する手法自体も追跡可能であることを意味しており、それが解読の難易度を劇的に引き下げてしまったのです。
なぜソフトウェア生成の乱数は推測されてしまうのか?
それは、ColdCardがリカバリーフレーズに使用した乱数が「ソフトウェア乱数生成器」によるものであり、厳密に言えば、そうした生成器はすべて「擬似乱数」であり、そのアルゴリズムは追跡可能だからです。なぜそう言えるのでしょうか?
まず、ランダム性とは実際には何であるかを考えてみましょう。コイン投げをしているとします。通常、表と裏が出る確率はそれぞれ50%ずつであり、ランダムに出現すると言います。なぜなら、コインが空中で回転する際、その軌道はさまざまな要因によって形作られるからです:どれくらいの強さで弾いたか、地球の重力、部屋の中のエアコンの風の強さと向き、コリオリの力、さらには地殻変動によるわずかな振動に至るまで、私たちが思いつく要因も思いつかない要因もたくさんあります。これらが積み重なることで、コインの空中の軌道を計算することが不可能になり、結果を予測できなくなるため、私たちはコイン投げを「ランダム」として受け入れているのです。
しかし、「ソフトウェア乱数生成器」は固定されたアルゴリズムで動作します。一般的に言って、それは少数の初期条件を取り、固定されたアルゴリズムに通すことで、固定された乱数を生成します。言い換えれば、それらのわずかな初期条件さえ分かっていれば、どのような乱数が生成されるか、したがってリカバリーフレーズがどうなるかも分かってしまうのです。
そして運悪く、人々がよく使用する初期条件とは、生成時のタイムスタンプ、デバイスが起動した時のタイムスタンプ、デバイスのシリアル番号などです。つまり、ハッカーはそれらの数値について妥当な推測を行い、ColdCardが生成したリカバリーフレーズを解読するためのアルゴリズムを設計するだけでよいのです。言い換えれば、フレーズが生成される方法自体に最初からパターンがあるため、ハッカーはまったく手当たり次第に推測する必要がありません。
ハードウェア乱数生成器は、実際どのようにして安全性を保っているのか?
この問題の根本は、ColdCardが「真の乱数生成器」、つまりセキュアエレメントチップ内部のハードウェア乱数生成器を使用していなかった点にあります。上記で述べたように、通常のソフトウェアPRNGは決定論的な数式です。
device ID + time + algorithm → random number
攻撃者がデバイスIDとタイミングを列挙できれば、すべての結果を再計算できてしまいます。
一方で、真の乱数生成器は、以下のような物理現象を利用します。
- 回路の熱雑音
- オシレータのジッター
- トランジスタのメタステーラビリティ(不安定状態)
- アバランシェ雑音
- 一部のデバイスにおける量子雑音
- 宇宙線によって引き起こされるランダムなメモリの誤り
などを用いてリカバリーフレーズを生成します。これはコイン投げに似ており、多くの干渉要因は人間の予測を完全に超越しています。プロセスはこのようになります。
unpredictable physical noise → sample and digitize → condition and hash → seed a cryptographically secure PRNG → generate the recovery phrase
攻撃者がデバイスのモデル、シリアル番号、起動時間、およびソースコードのすべてを知っていたとしても、その瞬間の回路ノイズの正確な波形を逆算することは不可能です。それこそが、真に信頼できるランダム性というものです。
エントロピー:ランダム性の尺度
エントロピーとは何か?
「エントロピー」と聞くと難しそうに聞こえますが、シンプルに「結果が判明するまでに、何通りの可能性が存在するか」と考えることができます。
普通のコインには、表と裏という2つの可能な結果があります。1回投げると、2^1 = 2 であるため1ビットのエントロピーが生じます。2回投げると、表-表、表-裏、裏-表、裏-裏という4つの可能性があり、2^2 = 4 であるため2ビットのエントロピーとなります。このように続けていくと、256回投げることで 2^256 通りの異なる結果が得られ、これは256ビットのランダム性に相当します。
しかし、エントロピーの鍵は、単に結果が複雑に見えることではありません。より重要なのは、誰も事前に結果を知ることができないという点です。コインに細工がされていて常に表が出るようになっていれば、256回投げたところで結果は最初から予測可能なため、エントロピーはゼロのままです。
真の乱数生成器すら信用できない場合は?
ハードウェアウォレット内部の真の乱数生成器すら信用できない場合、よりプリミティブな選択肢があります。それは、コインを投げて自分の手でランダム性を生み出すことです。
表を0、裏を1として記録し、256回コインを投げてすべての結果を書き留めます。これにより、256ビットの二進数が得られます。次に、完全にオフラインの環境で、BIP-39標準に従ってその数値のチェックサムを計算し、24個の英単語に変換します。これが完全なリカバリーフレーズになります。
flip a coin 256 times → record heads and tails → a 256-bit binary number → compute the BIP-39 checksum → 24 recovery words → import into a hardware wallet
ここで1つ注意点があります。コイン投げは「乱数を生成する」ステップの代わりになるだけで、ハードウェアウォレット自体の代わりにはなりません。ウォレットの保管、アドレスの導出、およびトランザクションの署名は、引き続きハードウェアウォレットの隔離された環境内で行う必要があります。接続されたデバイスはトランザクションの監視とブロードキャストのみを行い、リカバリーフレーズに触れさせてはなりません。
実際のコイン投げの結果をウェブページに入力したり、「ランダムそうだから」という理由で0と1の文字列を適当に自作したりしないでください。すべての結果が真に予測不可能なコイン投げから得られたものである場合にのみ、その数字の列は本物のランダム性を持つことになります。
よくある質問
いいえ。デバイス自体が侵入されたわけではありません。ファームウェアのバグにより、リカバリーフレーズがはるかに小さな値のプールから生成されたため、攻撃者はハードウェアを攻撃する代わりに総当たりで推測することができました。
影響はモデルによって異なります。ここで議論されている約40ビットの乱数は主にMk2およびMk3に適用され、Mk4、Mk5、Qの推定値は約72ビットです。正確な範囲については、Coinkiteの公式発表をご確認ください。
ソフトウェア生成器は、タイムスタンプやシリアル番号などの初期条件を与えられた固定アルゴリズムであるため、それらの入力を推測できる者なら誰でも出力を再計算できます。一方、ハードウェア生成器は回路の熱ノイズや発振器のジッタといった予測不可能な物理ノイズをサンプリングするため、公開情報から再計算することはできません。
24単語のBIP-39フレーズは256ビットの乱数に裏付けられており、2^256通り(約10^77、観測可能な宇宙にある素子の数に近い)の可能性を持ちます。
はい。表を0、裏を1として256回コインを投げ、オフラインでBIP-39のチェックサムを計算して24単語に変換します。コイン投げは乱数生成のステップを置き換えるだけであり、ウォレットの保管やトランザクションの署名は引き続きハードウェアウォレット内で行うべきであり、結果をオンラインのウェブページに入力しては絶対にいけません。






