今年に入ってBlockstreamの元CTOであるGregory MaxwellがBitcoinの開発MLで“Taproot”と“Graftroot”という2つの新しいコンセプトを発表した。とても魅力的なコンセプトなので是非おさえておきたい。

前提となるシュノア（Schnorr）署名

Bitcoinはもともと楕円曲線を使った署名「ECDSA」をサポートしているが、現在ECDSAの代わりに新しく提案されている署名がシュノア署名だ。シュノア署名にはECDSAにはない鍵の集約特性がある。どういうものかというと、アリスが持つ公開鍵Aとボブが持つ公開鍵Bがある場合、この２つの公開鍵を結合して新たな公開鍵Cを作ることができる。

より具体的なユースケースとしてマルチシグで考えてみよう。既存のBitcoinの場合、2-of-2のマルチシグのスクリプトは以下のような構成になる。

2 <公開鍵A> <公開鍵B> OP_CHECKMULTISIG

このマルチシグにロックされたコインを使用する際は、アンロックスクリプト（scriptSig）に以下の要素を提供する必要がある。

0 <公開鍵Aに対応した秘密鍵で作成した署名> <公開鍵Bに対応した秘密鍵で作成した署名>

ロックする際はそれぞれ33バイトの公開鍵✕2が必要で、アンロックする際はそれぞれ約73バイトの署名データ✕2が必要になる。マルチシグの参加者が増えるほど、必要な公開鍵と署名のデータサイズも比例して増加する。

シュノア署名を利用すると複数の公開鍵を集約して１つの公開鍵を作ることができ、署名も同様に１つに集約できるようになるため、マルチシグのデータサイズ大幅に削減することが可能になる。また、マルチシグ以外にも複数のインプットを持つトランザクションの署名を１つに集約することも可能だ。

TaprootとGraftrootでは前提としてこのシュノア署名の鍵の集約特性を利用する。

MASTの課題

以前の記事で複雑で巨大なコントラクトをプライバシーを強化しつつコンパクトに実現するMASTについて紹介したが、MASTの唯一の欠点はMASTを使用していることが明らかになる点だ。スクリプト構成から単純な１つの公開鍵への支払いではなく何らかのコントラクトへの支払いが含まれていることが公開される。

MASTを使用しない単一の公開鍵への支払いの場合でも、わざとMASTを構成するようにすれば懸念を解消できるが、単純に相手の公開鍵へ支払うだけの場合の手間が増え、データサイズも増えるためあまり現実的ではない。これを改善しようというのがTaprootの提案だった。

Taproot

コインのアンロック条件が以下のいずれかのケースを考える。

アリスとボブのマルチシグでアンロック可能

一定期間経過したらボブの署名のみでアンロック可能

通常のBitcoin Scriptだと以下のようなスクリプトになる。

OP_IF 2 <アリスの公開鍵A> <ボブの公開鍵B> 2 OP_CHECKMULTISIGOP_ELSE <ロック時間> OP_CSV OP_DROP <ボブの公開鍵B> OP_CHECKSIGOP_END

Taprootではこういったマルチシグと他のアンロック条件で構成されるスクリプトを単一の公開鍵に支払いをするスクリプトに変換する。具体的には以下のようにしてロックスクリプト（scriptPubkey）を作る。

1. アリスの公開鍵Aとボブの公開鍵Bを集約して新しい公開鍵Cを作る。

C = A + B

2. もう１つのアンロック条件であるタイムロック条件のスクリプトを以下のようにする。

S = <ロック時間> OP_CSV OP_DROP <B> OP_CHECKSIG

3. CとSを結合してハッシュ値を計算し、それを秘密鍵として新しい公開鍵Dを作成する。

D = H(C || S)G

（H()はハッシュ関数で、||は結合を表し、Gは楕円曲線の生成点）

4. 公開鍵Cと公開鍵Dを加算して新しい公開鍵Eを作る。

E = C + D

こうしてできた公開鍵Eに対してコインを送る。この段階では単純に公開鍵に対してコインを送っているだけで誰もタイムロックされた条件があることを知ることはできない。

公開鍵Eに送られたコインは以下のいずれかの方法で使用（アンロック）できる。

アリスとボブのマルチシグでアンロックする場合

Eはアリスとボブの公開鍵を集約して作成した公開鍵Cに、H(C || S)を秘密鍵とした公開鍵Dを加算して作った公開鍵なので、アリスとボブの秘密鍵にH(C || S)を加算すればEに対して有効な署名を作成することができる。

コインをアンロックする際は、集約した署名データをアンロックスクリプトにセットすればいい。

タイムロックされた条件でアンロックする場合

この条件でアンロックする場合に、今までとは異なるコンセンサスルールが適用される。

アンロックスクリプトとして、アリスとボブの公開鍵を集約した公開鍵CとSを提供する。提供されたデータから C ＋ H(C || S)Gを計算し、それがEと一致すれば、条件Sを使ってアンロックできるようになる。

まとめると、Taprootはアンロック条件がマルチシグ or その他の条件で構成されるロックスクリプトを1つの公開鍵への支払いスクリプトにすることで、ロック時点では単一の公開鍵への支払いなのかコントラクトを使った支払いなのか分からなくなり、そのままマルチシグでアンロックされた場合、代替条件が明らかになることもなくプライバシーが向上する。

ただ、Taprootはマルチシグ or その他の条件１つという構成で、その他の条件部分を複数にしようとするとオーバーヘッドが発生し、プライバシーや効率が低下してしまう。そんな問題を解消するより柔軟なスクリプトシステムの提案が、Taprootの発表から数日後に発表されたGraftrootというコンセプトだ。

Graftroot

TraprootやMASTと違って、Graftrootは後から柔軟にアンロック条件を追加できる。どういう仕組みか上記のTaprootのスクリプトを使って説明しよう。（※詳細なプロトコルはまだ定義されていないので正式なものではない）

Taprootと同様、アリスとボブの公開鍵を集約して新たな公開鍵Cを作成することろまでは変わらない。Graftrootではロックスクリプトを作る際にアンロック条件を全て列挙する必要がなく、単純にこの公開鍵Cへ支払いをする。

マルチシグを使ってコインをアンロックする場合は、単純にアリスとボブが協力して署名を作成すればいい。

もう一方のタイムロック条件を使ってアンロックする場合は、

1. アンロック条件を記載したスクリプトを作成する。

S = <ロック時間> OP_CSV OP_DROP <B> OP_CHECKSIG

2. 作成したスクリプトSに対して、アリスとボブが協力して公開鍵Cに対応した署名を作成する。3. Sと2で作成した署名および、Sを満たすアイテムをアンロックスクリプトにセットする。 提供された署名データがスクリプトSの有効な署名か公開鍵Cを使って検証し、有効であればスクリプトSを評価してコインをアンロックできる。

Bitcoinでは、通常ある公開鍵にロックされたコインは、その公開鍵に対応する秘密鍵でコインを使用するトランザクションに署名をすることでアンロックするが、Graftrootでは対応する秘密鍵で任意のスクリプトに署名することで、その署名とスクリプトを提示すれば、そちらの条件でもコインがアンロックできる、いわばコインの使用権を委譲できる仕組みを実現しようとしている。

これにより事実上、無制限にアンロック条件を作成することができるようになり、かつその条件はコインのロック時には必要なく、ロックされたコインに対して後からいつでもアンロック条件を追加できるようになる。

Graftrootが実現すればTaprootはもちろんMASTのような仕組みを導入する必要なく、より柔軟なスクリプトの実装が可能になり、今後の展開が注目される。