Great Script Restoration
Great Script Restoration(GSR)は、2010年にBitcoinで無効化されたopcode群に対して、重みベースのバジェットを付与して再導入するRusty Russellの提案↓
Jonas Nickが、このプロジェクトで有効になったopcodeを用いて量子耐性のあるWinternitz OTS+署名を実装したプロジェクトが↓
https://github.com/jonasnick/GreatRSI
Winternitz OTS+
W-OTS+は、量子耐性のあるハッシュベースのワンタイムデジタル署名スキーム。
パラメーター
W-OTS+は、以下の2つのパラメーターを使用する。
n:メッセージ、秘密鍵、公開鍵、署名要素の長さ(byte単位)。メッセージダイジェストを生成するハッシュ関数によって決り、WOTSP-SHA2_256の場合は32。w:Winternitzパラメーター。4か16のいずれかを選択*1。WOTSP-SHA2_256の場合は16。
この2つのパラメーターから以下のパラメーターを導出する。
len:WOTS+の秘密鍵、公開鍵、署名内のn byte文字列の数。len1 = ceil(8n / lg(w))、len2 = floor(lg(len1 * (w - 1)) / lg(w)) + 1とし、len = len1 + len2。WOTSP-SHA2_256の場合は67。
鍵生成
秘密鍵は、len個のn byte文字列の配列で、各n byte値は単純にランダムに選択するか、暗号学的に安全な疑似乱数法を使用してn byte値からすべて生成する。ワンタイム署名スキームなので、生成した秘密鍵は1つのメッセージへの署名にしか使えない。
対応する公開鍵もlen個のn byte値の配列で、
len個の秘密鍵の各nbyte値を起点として、各値をw - 1回ハッシュする連鎖関数を実行し、- ハッシュした
len個のデータを連結したものが公開鍵となる。
つまり、秘密鍵の各値は、公開鍵を計算するためのハッシュチェーンの起点ノードで、公開鍵の各値はこのハッシュチェーンの終点ノードということ。
署名の生成
W-OTS+の署名生成手順は、
- 署名対象のメッセージのハッシュ値H(m)を計算し、
- H(m)を
len1個の基数wの整数値に変換する。 - 次にチェックサムを計算し、2に追加する。
- 3の基数
wの各整数値をインデックスとして、公開鍵を生成する際のハッシュチェーンからそのインデックスに対応するノード値をピックアップする - 4の値を連結した値が署名データとなる。
署名の検証
W-OTS+の署名検証手順は、
- 署名対象のメッセージのハッシュ値H(m)を計算し、
- H(m)を
len1個の基数wの整数値に変換する。 - 次にチェックサムを計算し、2に追加する。
- 3の基数
wの各整数値とw - 1の差分分、連鎖関数を実行し - 4で計算した各ハッシュ値が、公開鍵の各値と一致すれば署名検証は成功。異なる場合は無効な署名。
という仕組み。
ちなみに、W-OTS+を拡張し、マークルツリーでワンタイム性を排除しステートレスなハッシュベースの署名スキームにしたのが現在NISTでポスト量子暗号の標準化対象になっているSPHINCS+。
データサイズ
WOTSP-SHA2_256の場合、秘密鍵、公開鍵、署名のサイズはそれぞれ2,144 byte。同様のハッシュベースのランポート署名の場合、単純な形だと公開鍵のデータ長だけで16KBとかになるので、それに比べるとまだ小さい方。W-OTS+は、基数wとハッシュチェーンの構成によって公開すべきデータが圧縮できているのが大きい。
Bitcoin ScriptでW-OTS+の検証
Bitcoin ScriptでW-OTS+の検証を行う場合、上記の検証ロジックをBitcoin Scriptで実装する必要があり、それが冒頭に貼ったGithubのプロジェクト。プロジェクトをビルドして生成したwotsコマンドを使うと、
- 鍵ペアの生成
(各256 bitの67個のシークレット、1つのシード、15個のランダマイザで、合計約2.6kB) - 公開鍵をエンコードしたBitcoin Scriptの生成(約20kB)
- Txに対してWOTS+署名とwitnessを生成(約2.2kB)
- Txに対してスクリプト及びWOTS+署名の検証
ができる。
量子耐性への対応
上記の検証スクリプトを利用することで、Bitcoinに量子耐性のあるデジタル署名スキームを導入することができるけど、W-OTS+のサポートはTaprootのscript-pathを利用する場合にのみ有効で、Taprootのkey-path条件がまだ利用可能。key-pathの方はSchnorr署名に依存しているのでこちらが利用可能な場合、量子耐性はない。そのため、GSRの導入に加えてTaprootのkey-pathを無効化する必要がある。
サイズの問題
W-OTS+を利用することで量子耐性は得られるけど、
- 鍵長自体はランポート署名より小さいけど、スクリプト自体のサイズは大きい
- ワンタイム署名スキームなので、鍵の導出管理などの仕組みが別途必要
あたりがネック。前者はBitcoin Scriptでループができないことが原因で、このあたりを改善しようとしてるAnthony TownsのLisp言語提案とか気になる。
*1:wが大きい方が署名は短くなるが、署名コストは高くなる