Electrumのシードフレーズ導出方法とBIP39を批判する理由
シードフレーズと言えば一般的に12単語ないし24単語で表現される単語列で、ウォレットのバックアップとして利用されます。その仕様を定めているのがBIP39です。
BIP39はSatoshiLabsが中心となり提案されたもので、現在では多くのウォレットがBIP39に従い、ウォレットのバックアップを視認性のあるシードフレーズに変換しています。
一方で、この規格に反して独自路線でシードフレーズを導出しているElectrumというウォレットが存在するのをご存知でしょうか。

Electrumは2011年11月5日にThomas Voegtlin氏によって発表されたソフトウェアウォレットで、Linux、Windows、macOS、Androidで起動することが可能です。
ブロックチェーンを全て同期せずに使える「軽量クライアント」であることが特徴で、Electrumサーバーから必要な情報を受け取りブロックヘッダーと照合して取引の検証を行います。
Electrumは他のウォレットとの互換性を捨てた部分が多々ある独自の設計思想を持っており、古参ビットコイナーから根強い人気を誇ります。
本稿ではElectrumがなぜBIP39を批判して独自規格のシードフレーズを導出しているのか。その理由と導出方法について解説します。
なお本稿はElectrumの独自規格とBIP39の優劣をつけるものではなく、両者の設計思想の違いに焦点を当てたものです。
Electrumの開発者がBIP39を批判する理由
まず誤解がないよう時系列をご説明するとElectrumのシードフレーズの導出はBIP39が作成される約2年前から実装されています。つまり、Electrumの方が先にシードフレーズの導出を規格化していました。その後、BIP39の草案作成においてElectrumの実装が参考にされています。
一方で、BIP39にはElectrumの初期のバージョンと同様の欠点を抱えていることをElectrumの開発者であるThomas氏が指摘しましたが改善されることはありませんでした。
そのためElectrumはBIP39とは互換性のない独自路線のシードフレーズを導出しているという事です。Thomas氏が指摘した欠点とは何だったのか。BIP39を批判する詳しい理由を2つに分けて解説します。
理由1:「ワードリスト非依存」が中途半端にしか実現されていない
前提:ワードリストの説明
まずはワードリストについて簡単に説明します。既にご存知の方は次のセクションまで読み飛ばしていただいて構いません。また詳しい解説は規新さんの記事をご覧ください。

ビットコインでは人間やウォレットが作成する乱数(エントロピー)を基にして公開鍵や秘密鍵、アドレスを導出しています。つまりこの乱数(エントロピー)を無くしてしまうとビットコインのデータが失われてしまうため大事に保管する必要があります。
しかし乱数(エントロピー)は128~256ビットの2進数で表現されるため、人間が管理するには扱いづらい性質があります。そこで乱数を11ビットに区切り、数字と文字に対応関係を付けたものが「ワードリスト」です。

128ビットの乱数(エントロピー)の場合は12単語、256ビットの乱数(エントロピー)の場合は24単語に変換することができます。
ワードリストに対するElectrumの思想とBIP39の実装について

初期のElectrum(v2.0より前)はシードフレーズと秘密鍵の間に双方向のエンコーディングで結びつけていたため、特定のワードリストに強く依存する設計となっていました。
ワードリストに依存している場合、特定のワードリストをウォレット等が永久に保存する必要があります。例えばファームウェアアップデートなどでワードリストが変更されてしまうと「残高0」と表示されてしまうという問題が存在します。
Electrumはこの反省から鍵やアドレスの導出をワードリストに依存しない形にすべきと推奨を行い、BIP39でもその推奨に従い実装がされました。
Electrumの主張は、シードフレーズ使用時にワードリストを参照しない設計にすることで、ワードリストの変更や喪失が問題にならないということです。

Electrumの推奨に従いBIP39ではシードフレーズを「単語インデックス番号」ではなく「文字列(String)」として関数に使用し、512ビットのシード(鍵)を生成します。そのため、「solution truth expose ・・・」という12〜24単語の文字列はもちろん「abcdefg」というデタラメな文字列も利用できます。結果的に、シード生成のタイミングではワードリストが不要です。
しかしながら、BIP39はチェックサムの検証にワードリストが必要となります。具体的にはワードリストを用いてエントロピーのバイナリ値を逆算することでチェックサムの検証を行っています。つまり、シードフレーズで復元する際に、毎回生成時のワードリストが必要となります。
これは、推奨内容と明らかに矛盾をしており、ワードリスト非依存という目的そのものを台無しにしているとしてThomas氏は指摘をしています。
Electrumでも有効なシードフレーズかを検証する機能はありますが、12単語の文字列をハッシュ化(HMAC-SHA512)し、ハッシュ値の先頭2〜3文字(16進数、8〜12ビット)を確認することで検証できます。そのため、検証時にワードリストは使用しません。具体的な内容については後述の「理由2:バージョン番号が含まれていない点」でも触れます。
またBIP39は言語ごとに個別のワードリストを用意する仕様になっているため、ワードリストに依存する問題は一層深刻化します。
例えば英語のワードリストしか保存していないウォレットには、日本語やイタリア語などのシードフレーズのチェックサム検証ができず、対応するには日本語やイタリア語のワードリストの保存が必要です。一方で、Electrumであれば英語のワードリストしか保存していないウォレットでも、多言語の入力UIさえあれば複数言語のシードフレーズの復元が可能です。
加えて、シードフレーズから言語を自動判定する仕組みがある場合、英語とフランス語の重複単語(100個)だけで偶然構成されると判定を誤り、チェックサムに失敗するおそれがあります。他にも、新しい言語リストが追加されるたびに、既存の全ウォレットが未対応になる問題も指摘されます。
そのため、シードフレーズから鍵を導出するのにワードリストを非依存の設計にしたのであれば、中途半端に実装をせず、復元時のチェックサム検証もワードリストを非依存にしないと意味がないのではないか。という主張です。
理由2:バージョン番号が含まれていない点
Electrumはv2.0以降、シードフレーズにどの方式でアドレスを導出すべきかを示す「バージョン番号」を含める設計にしています。

具体的にはシードフレーズ(12単語)の文字列をハッシュ化し、プレフィックス(先頭の値)を確認することで検証可能です。同時にシードフレーズ自体の整合性チェック(正しいシードフレーズであれば登録済みのバージョン番号を生成するというチェックサムの役割)としても機能します。
以下はバージョン番号の対応表です。
| バージョン番号 | タイプ | 説明 |
|---|---|---|
| 0x01 | Standard | P2PKHおよびマルチシグP2SHウォレット |
| 0x100 | Segwit | SegWit: P2WPKHおよびP2WSHウォレット |
| 0x101 | 2FA | 二段階認証ウォレット |
バージョン番号が特定の値になるようにシードフレーズを操作しているのであれば、エントロピーが小さくなることを懸念している方もいると思います。
公式の説明によると
バージョン番号を利用することで攻撃者が候補のシードフレーズを検証する際、そのシードフレーズが無効であればコストの高い鍵導出を省略して即座に棄却できてしまうというデメリットが存在することを認めています。しかし何度もハッシュ関数を適用する「鍵伸長」という操作をすることで約11ビット分の強度が上乗せされるそうです。
つまり、Electrumの標準的な12単語のシードフレーズは132ビット相当のエントロピーを持ち、2048回の鍵伸長により11ビット強化されます。例えバージョン番号分(Segwit)のエントロピー12ビットを差し引いたとしても実行的な強度は131ビットとなります。
また、バージョン番号を知ったところでシードフレーズの探索空間は縮小するわけではないため、セキュリティが下がるといった心配はありません。
一方でBIP39にはシードフレーズにバージョン番号を含みません。(含まれる情報はエントロピー+チェックサム)
バージョン番号が含まれない場合、シードフレーズからどのように鍵とアドレスを生成すべきかをソフトウェア側は判断することができないため、復元する際に全てのアドレス形式を探索する必要があり非効率だというのがElectrum側の指摘です。
また仮に古いアドレス形式の実装を取り辞めた新規ウォレットの場合は、シードフレーズを入力しても実装されていないため「残高0」と表示されるリスクが残ります。
バージョン番号がある場合は、実装を取り辞めていたとしてもバージョン番号が一致しないことをソフトウェアが認識できるため、「残高0」ではなく「対応しないウォレット」と表示されます。結果として、ユーザーが残高0の表示を見て資金を失ったと誤解し、パニックに陥るリスクを減らせるとされます。
この問題は後にBIP380によりシードフレーズとは別にアドレスの種類を判別する文字列(ディスクリプタ)を保存することで解決を図っており、BIP380のmediawikiによるとバージョン番号の導入はレイヤー違反(鍵の導出とスクリプトの判別は分離されるべき)ではないかとElectrumの実装を批判する文章が掲載されていました。
思想の違いにより袂を分かつ実装になっている事が読み取れます。
まとめ
ElectrumはBIP39に先立ってシードフレーズ方式を実装しており、その経験から開発者Thomas氏はBIP39に対して2つの点を批判しています。
1つ目は、「ワードリスト非依存」を掲げながらも、チェックサム検証には結局ワードリストを用いてしまっている点。2つ目は、シードフレーズにバージョン番号を含まないため、復元時に非効率が生じたり、「残高0」といった誤表示でユーザーを混乱させかねない点です。
こうした批判などから、ElectrumとBIP39は同じ「シードフレーズ」を扱いながらも、異なる設計思想に基づいて実装されていることが垣間見れたと思います。
普及率という面でいえばBIP39の方がリードしている印象ですが、こうした思想の違いを踏まえた上で、ユーザー自身の好きなウォレットを使えば良いと私は思います。
また、最近のColdCardの事件からもわかるように1つのウォレットに集中させず、様々なウォレットに分散して資金を管理することをお勧めします。
関連記事
最新記事
読者になる
ビットコイン研究所の新着記事をお届けします。


ディスカッション