用語集 / アドレスと鍵
チェーンコード
- チェーンコードとは?
- チェーンコードとは、HDウォレットの各鍵に付随する32バイトの追加エントロピーのことで、子鍵の導出のたびに混ぜ込まれるため、鍵を兄弟鍵から推測することはできません。
BIP-32で規定されています。
拡張鍵の半分は鍵ではありません。BIP-32では512ビットのハッシュを256ビットの鍵と256ビットのチェーンコードに分割し、xpubの文字列はその両方を合わせて111文字で保持します。xpubを渡すときはチェーンコードも一緒に渡しており、それによって受け取った側はあなたの将来のアドレスを導出できるようになります。
仕組み
チェーンコードは1回のHMAC呼び出しの中で役割を果たします。子鍵の導出では、親のチェーンコードを鍵とし、親の公開鍵と4バイトのインデックスをメッセージとしてHMAC-SHA512を実行します。64バイトの結果は中央で分割されます。左側の32バイトを親の秘密鍵に加算し、曲線の位数で割った余りを子の秘密鍵とし、右側の32バイトが子自身のチェーンコードとなり、子はこれを自身の子の導出に使います。
このソルトの意味は、誰がツリーをたどれるかという点にあります。公開鍵だけでは何も導出できません。対応するチェーンコードがなければ導出関数が実行されないからです。そのため、拡張公開鍵は単に名前が長い公開鍵ではありません。公開鍵とそのチェーンコードの組であり、この組を誰かに渡すと、曲線上のある1点が、まだ使っていない無制限に列挙可能なアドレスの枝に変わります。
BIP-32は、そこから生じる危険な点を記述しています。攻撃者があなたの拡張公開鍵を保有し、さらに非強化の子秘密鍵を1つ入手した場合、導出されたオフセットを差し引くことで親秘密鍵を復元でき、それとともにすべての兄弟鍵とすべての子孫鍵も復元できます。強化導出はこの経路を断つために存在します。強化されたステップでは、ハッシュ化されるメッセージに親の公開鍵ではなく親の秘密鍵が含まれるため、公開情報をどれだけ集めても上位へさかのぼることはできません。
目にする場所
チェーンコードを自分で入力することはありませんし、一般向けウォレットがチェーンコードだけを表示することもありません。チェーンコードは拡張鍵の中に入って移動します。xpubまたはxprvで始まるBase58Checkの文字列は、78バイトにデコードされ、4バイトのバージョン、1バイトの深さ、4バイトの親フィンガープリント、4バイトの子番号、32バイトのチェーンコード、最後に33バイトの鍵という並びになっており、そのためxpubは111文字のテキストになります。
このフィールドがフィールドとして見えるようになるのは、開発者向けツールにおいてです。Bitcoin Coreのderiveaddresses RPCは拡張鍵を埋め込んだディスクリプタを扱い、python-bip32のようなライブラリはチェーンコードを別の属性として返し、ウォッチオンリー構成のためにアカウントをエクスポートする署名デバイスは、まさにこの組をエクスポートしています。
適切な注意の度合いは、パスワードに対して払うものではなく、取引履歴全体に対して払うものです。チェーンコードは署名できないため、チェーンコード単体では何も失われません。しかし分析会社、クラウドバックアップ、あるいはサポートチケットにxpubを貼り付けた人の手に渡ると、その枝の過去と未来のすべての支払いが露出し、後からアクセスを取り消す方法はありません。
チェーンコードvs秘密鍵
チェーンコードと秘密鍵はどちらも乱数のように見える32バイトですが、支出できるのは片方だけです。秘密鍵は署名を生成します。チェーンコードはさらなる導出以外に何も生み出さず、まさにそのために人々は過小評価します。お金を動かせないからこそ、鍵に対しては決してしないようなことをする人が、拡張公開鍵を共有スプレッドシートやバグ報告、スマートフォンのアプリに貼り付けてしまうのです。その結果は盗難ではなく、自分の財務を恒久的にのぞかれる窓であり、この2つの失敗には別の名前がふさわしいのです。