用語集 / アドレスと鍵
ハードニングありvsなしの導出
- ハードニングありvsなしの導出とは?
- ハードニングありの導出とハードニングなしの導出は、BIP-32の子インデックスを半分に分けます。ハードニングなしの子は拡張公開鍵から計算できますが、ハードニングありの子は計算できません。
BIP-32で規定されています。
ハードニングは、切り替える設定ではなく、導出パス上の境界です。BIP-32は2012年2月11日にハードニングなしの導出のみで割り当てられ、0x80000000以上のインデックスに対する秘密導出は2013年4月16日に追加され、それらの鍵は2014年1月15日にハードニングありと改名されました。この境界がどこに位置するかで、共有した拡張公開鍵がウォレットのどこまでを引き渡すかが決まります。
仕組み
ハードニングなしの導出には、ハードニングありの導出が意図的に欠いている性質が1つあり、BIP-32はその違いを代数の等式として記録しています。拡張鍵の秘密の半分を捨てて32バイトのチェーンコードを残す処理をニュートラリングと呼び、N()と書きます。ハードニングなしの階層では、N(m/a/b/c)はN(m)/a/b/cと等しいため、導出の前にニュートラリングしても、導出の後にニュートラリングしても、同じ鍵に到達します。ハードニングありの階層ではこの書き換えが成り立ちません。N(m/a')をN(m)/a'に変えることはできません。公開導出はハードニングなしの子に対してのみ定義され、それ以外には失敗を返すからです。
仕組みとしては、2つのモードは1つのフィールドだけが異なります。どちらも親のチェーンコードを鍵としてHMAC-SHA512を使い、4バイトのインデックスを付加します。ハードニングなしのモードは親の圧縮公開鍵を渡します。ハードニングありのモードは親の秘密を先頭のゼロバイトで埋めて同じ33バイト幅にして渡します。xpubだけを持つものはこの2番目の入力を持たないため、導出は境界で止まります。
BIP-32は、ハードニングなしの鍵が守れないことについて異例なほど率直です。そのセキュリティの節は2つの性質を備わっているものではなく欠けているものとして挙げています。親の拡張公開鍵と子の公開鍵が与えられたとき、インデックスを見つけるのは難しくありません。また、同じ親の拡張公開鍵とハードニングなしの子の秘密鍵が1つでも与えられたとき、親の拡張秘密鍵を復元するのも難しくありません。前者はプライバシーを失わせます。後者はその枝を失わせます。
どこで見られるか
拡張公開鍵をエクスポートする価値があるのはハードニングなしの階層があるからであり、BIP-32はそれに基づく共有の取り決めに1つの節を割いています。口座の拡張公開鍵を渡された監査人は、各口座への入出金のすべてを見ますが、秘密鍵は1つも見ません。頻繁に取引する2社は、単一口座の外部チェーンを常設の入金先アドレスとして共有できるため、送金のたびに新しいアドレスを要求する必要がありません。ウェブショップは同じ種類の鍵をウェブサーバーに渡すことができ、サーバーはそこから、支出する権限を持たない受取アドレスを生成します。
境界を口座の階層に置く構成は助言であり、規則ではありません。BIP-32はマスター、口座、チェーン、サブチェーンの構造をあくまで参考として位置づけ、実装は特定の必要に応じて逸脱してよいと述べています。そのため、準拠したあるウォレットが隣の準拠したウォレットよりも多くの階層をハードニングすることがあります。
相互運用性の落とし穴が1つあり、知っておく価値があります。仕様はこれのために2度パッチを当てられました。先頭のゼロを含むハードニングありの導出を扱うテストベクターが2017年2月24日に、そして再び2020年11月4日に追加されました。ハードニングありの入力は33バイトに固定されており、ゼロバイトの後に32バイトの秘密が続きます。そのため、その幅を保たずに先頭のゼロを切り詰めるソフトウェアは、異なるデータをハッシュし、異なる枝を生成し、誰かがそのシードを別のプログラムで復元したときに空のウォレットを見つけることになります。ハードニングなしの導出はこの不具合に決して遭遇しません。圧縮公開鍵は必ず0x02または0x03で始まるため、失う先頭のゼロが存在しないからです。