用語集 / アドレスと鍵
圧縮公開鍵
- 圧縮公開鍵とは?
- 圧縮公開鍵は、曲線上の点のx座標と1バイトのパリティフラグだけを保存するもので、完全な公開鍵が65バイトではなく33バイトに収まります。
secp256k1上のすべての点は、与えられたxに対して取り得るyの値が2つあるため、どちらであるかを記録するには32バイトではなく1バイトで済みます。2012年3月にリリースされたBitcoin Core 0.6以降、ウォレットはデフォルトで圧縮鍵を生成しており、節約されたバイトは、その後使用するすべてのインプットのサイズから差し引かれます。支払いが安くなることこそが利点のすべてであり、この形式は日常的な使用では見えません。
仕組み
公開鍵の圧縮はデータ圧縮ではなく代数です。曲線の方程式、すなわちyの2乗はxの立方に7を加えたものに等しいという式は、任意のxに対してyの解を最大2つ持ち、その2つの解は常に1つの偶数と1つの奇数です。したがって、xと、どちらの解に当たるかを示す1ビットの情報を保存すれば、方程式を解き、正しい偶奇を持つ根を選ぶことで、誰でもその点を正確に復元するのに十分です。
エンコードでは、そのビットを先頭バイトに置きます。接頭辞0x02はyの値が偶数であることを、0x03は奇数であることを意味し、続く32バイトがx座標です。全長は33バイトです。旧形式は0x04の接頭辞でそれと分かり、両方の座標を完全に保持して65バイトになります。鍵を読み取るソフトウェアは最初の1バイトだけで両者を区別できるため、ウォレットは移行期間を通じて互換性を保てました。
節約される32バイトは、出力の種類によって異なる場所に現れます。レガシーのインプットでは鍵はアンロックスクリプト内にあり、全重量で計算されるため、32バイトは32vbyte、20 sat/vBの手数料率では約640サトシになります。SegWitのインプットでは鍵はウィットネス内にあり、4分の1に割り引かれるため、同じ32バイトは8vbyteになります。どちらの数値も単独では劇的ではなく、どちらも、署名するすべてのトランザクションのすべてのインプットで繰り返されます。
どこで目にするか
圧縮鍵は生のトランザクションデータで目にします。ブロックエクスプローラーで最近の使用を開くと、ウィットネスまたはスクリプト内の公開鍵は02または03で始まり、その後に64桁の16進文字が続きます。04で始まる鍵は遺物です。
この形式はアドレスの見た目も決めます。圧縮鍵をハッシュ化した結果は、同じ鍵の非圧縮版をハッシュ化した結果と異なるため、1つの秘密鍵が、それぞれ残高が別々の、完全に独立した2つのレガシーアドレスに対応し得ます。ウォレットはこれを工夫ではなく慣習で扱います。通常使用されるすべてのシードフレーズウォレットを対象とするBIP-32を通じて導出されるものはすべて全体が圧縮されており、KまたはLで始まるWallet Import Format文字列は、その鍵がこの分岐の圧縮側に属することを示します。
SegWitはこの曖昧さを完全に取り除きました。BIP-143はバージョン0のウィットネスプログラム内での非圧縮鍵を禁止しているため、bc1qアドレスは規則によりすべて圧縮されており、Taprootはさらに進んで、パリティバイトを完全に省いたxのみの32バイト鍵を定義しました。
圧縮公開鍵vs非圧縮公開鍵
圧縮形式と非圧縮形式は同じ点をエンコードしており、違いは書き留める必要があるものだけです。圧縮形式はxを保持し、必要に応じてyを導出します。これには数マイクロ秒の計算がかかり、32バイトを永久に節約します。非圧縮形式はyをそのまま保存します。これは2009年のハードウェアでは計算を節約しましたが、現在は何の利点もありません。2つのバイト列が異なるため、ハッシュ化すると異なるアドレスになり、バイト数よりもこの不一致こそが、非常に古いウォレットの資金を時折行き場を失わせる原因です。