Bitcoinの主要ウォレットはBIP-32 HDウォレットをサポートしており、単一のマスターシードから、支払いや受け取りに使用するすべての鍵を導出するようになっている。オンチェーンの資金は、基本的にこのマスターシードだけ保持していれば、そこからリカバリーができる。
既存のエンコード方法
このマスターシードのエンコード方法として現在最も主流なのが、BIP-39のニーモニックワードとしてエンコードする方法。12個や24個の単語として覚えておく方法。
もう1つはSLIP-39。こちらは、BIP-39が単一のシードを単語に変換するのに対し
TrezorのShamir Bakupなどで採用されている。
Codex32
↑のような方式を使わずに、マスターシードそのまま保存するということも可能だけど、データの欠落やコピーミスなんかで、誤ったデータになっていないか確認できる機能は欲しい。
最近このマスターシードについて、Codex32という新しいエンコード方式のBIPドラフトが提案された↓
https://github.com/apoelstra/bips/blob/2023-02--volvelles/bip-0000.mediawiki
Codex32の機能については、↑のBIPよりこのウェブサイトの方が分かりやすいかも。
Codex32では、マスターシードをBech32のアルファベット(BIP-173参照)を使って
2種類のエンコード方法をサポートしている。
既存のエンコード方法との違いは、
- 単語リストを使わずに、Bech32のアルファベットを使用するので、エンコード結果はコンパクトになる。
- ソフトウェアを使わずに手計算で、シェアやシードの生成や検証ができる。
特に後者が特徴的で、シェアの正しさの検証のためにデジタル機器にシェアを入力する機会をなくすことができる。
一方で、手計算をサポートするため、BIP-39でサポートされるようなシードに対するパスフレーズの設定はできない。
データフォーマット
Codex32のフォーマットは、BIP-173のBech32フォーマットと似ており、以下のデータで構成される。
- 人が識別可能な部分:
ms
- セパレーター:
1
- データ部:
シードもシェアも同じこのフォーマットを使用する。シェアインデックスがs
の場合、シードを直接エンコードしたもので、それ以外の場合はシェアをエンコードしたデータになる。
新しいマスターシードの生成
新しくマスターシードを生成する場合、まず先に閾値分のシェアを生成して、そのデータからマスターシードを生成する。具体的な手順は、
- マスターシードのビットサイズを決める。128 bit〜512 bitの範囲で、8の倍数であること。
- 閾値
k
を決める(2〜9) - 4文字の識別子を決める。
k
回分、ランダムにシェアを生成する↓
結果、k
個のシェアをエンコードしたリストができる。シェアのランダムなbech32文字の選択方法については、特に明記されてないけど、サイコロとワークシート使った導出方法とかは紹介されてる。
マスターシードは、このk
個のシェアからシャミアの秘密分散法によって計算される。↑のシェアインデックスをxの値として、ランダムなシェアの値と合わせてラグランジュ補間でマスターシークレットを導出するみたい。
マスターシードは、x = 16
として多項式を評価した値で、bech32文字の16番目の要素がs
なので、マスターシードのシェアインデックスはs
になってるっぽい。
補間したデータのシークレット値は、8bit単位に変換し、過剰分を切り詰めるとマスターシードになる。
新しいシェアの生成
閾値分のシェアが準備できたら、他のシェアも生成することができる。シェアの生成は↑のマスターシードの計算方法と同様で、異なるのはラグランジュ補間で多項式を評価する際の値だけ。マスターシードの場合はs
だったけど、代わりに新しく生成するシェアのインデックスをx値として評価することで、シェアが導出できる。
既存のマスタシードを使用する場合
既にあるマスタシードを利用する場合は、まず最初にそのシードデータを以下の手順でCodex32フォーマットに変換する。
これでマスターシードのCodex32文字列ができるので、続いて、k-1個のシェアを生成する。この時、シェアの生成方法は↑の新しいマスターシードの生成方法と同じでランダムにシェアを生成する。
k-1個ランダムに選択したシェアとx = s = 16
となるシードデータがあれば、後はそれを使っていくつでもシェアを生成できる。k個のシェアが作れたらマスターシードのCodex32データはマスターシードごと削除してもいい。
チェックサムの計算
チェックサムは、
を元に計算される13文字のbech32文字で、最大4文字の誤り、最大8文字の消失を訂正できる機能を持つ。BIP-173と同じ文字セットを使用したBCH符号ベースのチェックサムだが、文字数やパラメーター、計算対象(hrpは含まない)、bit変換時の不要データの扱い(切り詰め)などは異なる。
ロングCodex32
↑の13文字のチェックサムでサポートされるデータ部は最大80文字(ペイロードは74文字、46バイトまで)で、それを超えるサイズのシードデータを扱う場合には、15文字のロングチェックサムを持つ、ロングCodex32フォーマットを用いることになる。
BIP-32のシードは32バイトで通常のCodex32フォーマットで十分なものの、BIP-32ではこのシードを最大64バイトにすることもでき、この場合は通常のCodex32ではエンコードできない。このようなシードをエンコードする場合にロングCodex32が使用され、この場合
シェアの生成方法やマスターシードのリカバリー方法は通常のCodex32と同様。