Develop with pleasure!

福岡でCloudとかBlockchainとか。

高速で秘匿性の高いスマートコントラクトをサポートするZkVM

Scaling Bitcoin 2019予習シリーズ第5弾は、「ZkVM: zero-knowledge virtual machine for fast confidential smart contracts」。おそらく内容はStellarが開発している↓のZkVMの話だと思われる。

https://github.com/stellar/slingshot/tree/main/zkvm

ZkVMブロックチェーン

ZkVMはTxVMの研究から生まれたゼロ知識仮想マシンで、キーとなる機能はゼロ知識証明を利用したコインやコントラクトの秘匿化だが、その他にもTaprootやUtreexoなど現在Bitcoinの改善案として提案されている新しい技術が導入されている。

ブロックチェーンの構造

ZkVMブロックチェーンの参加ノードはそれぞれがブロックチェーンステートを管理する。このブロックチェーンステートは以下の要素で構成される。

名称 定義
initialheader ブロックチェーンの初期ブロックヘッダー
tipheader 最新のブロックヘッダー
utxos Utreexoで管理するUTXOのルート

そしてブロックヘッダーは以下の要素で構成される。

名称 定義
version ブロックのバージョンで、現在は1
height ブロック高
previd 前のブロックのID
timstamp_ms タイムスタンプ
txroot ブロック内のトランザクションのマークルルート
utxoroot Utreexoのルート
ext 将来の拡張用でversion 1では空

既存のネットワークに参加する場合は、公開されている初期ブロックとブロックの履歴を入手しチェーンを同期する。新しいネットワークを作る場合は自分で任意のtimstamp_msutxosをセットして初期ブロックを作成するみたい。

各ノードは新しいブロックを受け取ると、ローカルに保持しているブロックチェーンステートを更新する。

トランザクション

ZkVMブロックチェーンはUTXOモデルのブロックチェーンで、トランザクションのインプットが前のトランザクションのアウトプットを参照し、そのコインを新しいトランザクションアウトプットへ移動させる仕組みはBitcoinと同様。

f:id:techmedia-think:20190906150918p:plain
UTXOモデルのトランザクション

各インプットは前のトランザクションアウトプットを参照する識別子を持ち、暗号署名でそのコインをアンロックする。各アウトプットはコインの新しい宛先。トランザクションの各アウトプットはコントラクトを持ち、コントラクトには値もしくはデータパラメータである任意の数のアイテムが含まれ、Predicateによって保護される。Predicateはこのアウトプットの資産をアンロックするために満たす必要がある条件で、公開鍵やサブプログラムで構成される。

トランザクションは一意のトランザクションIDを生成するのに必要なデータとロジックを含む以下の要素で構成される。

名称 定義
Version バージョン
Time bounds 最小時間と最大時間の範囲を表す時間制限
Program ZkVMの命令シーケンスを表す可変長のバイト配列で、スタックベースのZkVMで実行されるプログラム。
Signature 64バイトの署名
Proof VM実行中にConstraint systemを満たす証明で、可変長の点の配列とスカラー

表から分かるように、実はBitcoinトランザクションのように明示的にインプットやアウトプットをセットするフィールドは存在しない。ZkVMにはinput命令やoutput命令があり、インプットとアウトプットの組み立てもProgram内の命令コードとデータを使って行うようになっている。

ZkVMの実行

ZkVMはトランザクションを検証するためのスタックマシンで、トランザクションのプログラムを実行し、そのトランザクションの有効性を検証し、ブロックチェンステートの更新リストを計算するようになっている。

f:id:techmedia-think:20190906165557p:plain
ZkVMの処理フロー

上述したように、インプットおよびアウトプットの指定もこのProgram内で行われる。例えば、ZkVMがProgramを実行し、その中にinput命令があれば、スタックからUTXOを識別するprevoutをpopし、そのprevoutに対応するコントラクトを構築しスタックにプッシュし、トランザクションログにインプットエントリーを追加する。output命令があれば、スタックからPredicateおよびアイテムをpopしContractを作成し、アウトプットエントリーをトランザクションログに追加する。このようにして消費したUTXOと新しいアウトプットの情報はトランザクションの実行結果としてトランザクションアウトプットに記録される。そして最終的にトランザクションログを使ってブロックチェーンステートを更新する仕組みになっている。トランザクションの検証とトランザクションログによるブロックチェーンステートの更新を分離することで並列性を高めるみたい。

秘匿性

↑のZkVMはには、Program、スタック、トランザクションログ以外に、もう1つConstraint systemと呼ばれるものが含まれている。

ZkVMはゼロ知識証明システムの一種であるBulletproofs上に構築されている。コインの量を示す値やデータはデフォルトで暗号化され、Pedersen commitmentとして表現される。

f:id:techmedia-think:20190906184413p:plain
Constraint System

Programの実行中にさまざまな命令がConstraint systemに制約を追加し、VMがProgramの実行を完全に終えると、Bulletproofsプロトコルトランザクション内に格納された証明の文字列を使ってConstraint systemを検証する。トランザクションにセットする証明を作成するには、トランザクション作成者が最初にVMを証明モードで実行する。するとトランザクションのProgramは検証モードと同じ制約を作成するが、証明をチェックする代わりにConstraint systemを使って証明を生成するようになってるみたい。(この辺のBulletproofsを使った証明の仕組みはもっと掘り下げて別の記事で書きたい。)

Taprootの利用

トランザクションアウトプットに定義されるPredicateは公開鍵やサブプログラムで構成されると書いたが、この時Taprootのコミットメントスキームが利用される。コントラクトのアンロック条件をMASTで構成し、その条件セットをTaprootのスキームを利用して公開鍵にエンコードする。Taprootを利用することでロック時に全てのコントラクトロジックをが明らかになることを回避する。また、コントラクトの全参加者が協力する場合、アウトプットをアンロックする際にコントラクトの条件を公開することもない。

具体的なTaprootの仕組みについては以前書いた↓を参照。

techmedia-think.hatenablog.com

Utreexoを利用したUTXOセットの管理

ZkVMブロックチェーンは、UTXOセットの管理にUtreexoを使用する。現在のBitcoinはUTXOセットの全データをKVSで管理し、その容量は3〜4GBほどになるが、ZkVMブロックチェーンではUTXOセットをUtreexoというハッシュベースのアキュムレータを使って管理する。UtreexoではUTXOのセットで複数のマークルツリーを構成し、そのマークルルートのみを保存するため、UTXOセットの容量は数KBまで圧縮される。Uteexoの具体的な仕組みについては、以前書いた↓を参照。

techmedia-think.hatenablog.com