用語集 / アドレスと鍵
子鍵
別名は子公開鍵、子秘密鍵、Child keyです。
- 子鍵とは?
- 子キーは乱数生成器ではなく導出の段階から得られる鍵で、親キーがそれを生成するときに使ったインデックスによって識別されます。
BIP-32で規定されています。
子キーは、上位のキーに比べて弱いところがひとつもありません。子キーは256ビットの完全な秘密鍵で、独自のチェーンコードを持ち、トランザクションに署名でき、さらに自分の子キーを持つこともできます。この言葉は木構造の中の位置を表しており、標準的なウォレットでは、実際にビットコインを保有している鍵はルートから5階層下にあります。
仕組み
子キーの導出にはハッシュ1回と加算1回が必要です。親のチェーンコードがHMAC-SHA512の鍵になり、データは親の鍵素材に4バイトのインデックスを続けたものになり、64バイトの結果が半分に分かれます。右側の32バイトが子のチェーンコードになります。左側の32バイトはsecp256k1曲線の位数を法として親の秘密鍵に加算され、その和が子の秘密鍵になります。
この加算があるからこそ、公開導出が可能になります。秘密鍵に数を足すことは公開鍵に点を足すことに対応するため、公開側だけを持つソフトウェアでも、秘密を一切見ることなく同じ子の公開鍵を計算できます。BIP-32は、ハッシュの出力が有効範囲を外れた場合についても定めており、その確率を2の127乗分の1未満としています。その場合の指示は、そのインデックスを飛ばして次に進むことです。
兄弟キーは何も漏らしません。同じ親を持つ2つの子は、アドレスから観察者が気づけるものを何も共有していません。だからこそ、支払いごとに新しいアドレスを使う価値があるのです。この関係を復元できるのは、親の拡張公開鍵を持つ者だけです。
どこで見かけるか
ウォレットは実際には子キーから組み立てられているため、子キーには鍵としてではなくインデックス番号として出会います。
SparrowやElectrumでコイン管理画面を開くと、どのアドレスにもそのパスが付いています。m/84'/0'/0'/0/7は、最初のアカウントの8番目の受取アドレスで、ゼロから数えています。TrezorやLedgerで出金を確認すると、機器はアドレスの横に同じパスを表示します。これにより、送金先が自分自身のツリーに属しているのか、それともコンピュータを侵害した者のものなのかを確認できます。
深さも読む価値があります。マスターキーは深さ0にあり、BIP-44形式のパスでは、支払いに署名する鍵は深さ5にあります。その間のどの階層も、上に対しては子、下に対しては親です。つまりどちらの言葉も、階級ではなく関係を表しています。
このことからひとつの習慣が導かれます。ブランチを完全に放棄する意図がない限り、HDウォレットから個々の子の秘密鍵をエクスポートしないでください。非ハードニングの子の秘密鍵を親の拡張公開鍵と組み合わせると、親の拡張秘密鍵が明らかになるため、不用意なエクスポート1回で、1つのアドレスではなくアカウント全体を明け渡すことになりかねません。
子キーvs親キー
子キーと親キーは、1回の導出ステップの両端から見た同じ種類の対象です。マスター以外のどの鍵も誰かの子であり、そこから導出されたことのあるどの鍵も誰かの親であるため、m/84'/0'/0'にあるノードは両方を兼ねています。非対称性は、それぞれが計算できるものにあります。親は子を際限なく導出できますが、子は単独では上位の鍵について何も明かしません。この一方向性がツリーのセキュリティモデルのすべてであり、ハードニング導出がそれを一方向に保っています。