はじめに
本記事では,ブロックチェーン分野で実用が進むゼロ知識証明(ZKP:Zero-Knowledge Proof)技術について解説したものです.昨今のZKP技術は,様々な暗号学的な知識や背景となる数学を多用しており,全体を把握することや,ゼロから全てを説明しようとすることは難しくなってきています.この記事では,暗号学的な理屈は一旦脇に置いて,ゼロ知識証明になぜ注目があつまっているのか,ゼロ知識証明がどのように進化し,どう使われる可能性があるかに焦点を当てて,複数回に分けて解説したいと思います.また実践編として,zkVM(ゼロ知識仮想マシン)を用いたアプリケーションの実装検証についても予定しています.
なお,本記事の内容はレポート「ゼロ知識証明の現在地〜ブロックチェーンを超えた活用可能性〜(日本総合研究所 先端技術リサーチ)」を基とした詳細解説となっており,記事中の図表は全てレポートより引用しております.
ゼロ知識証明技術は,プライバシー強化技術(PETs)として分類されることもあります.プライバシー強化技術全体についての説明は是非,下記をご覧ください.
ゼロ知識証明とは
ゼロ知識証明(ZKP: Zero-Knowledge Proof)は,ある当事者が他の当事者に対して,自身が特定の値を知っていることや,ある条件が成立していることを証明するための暗号技術の一種です.この技術の特徴は,証明を行う際に,その値自体や条件の具体的な内容を一切公開しない点にあります.ゼロ知識証明は,約40年の歴史を持つ技術ですが,当初,ゼロ知識証明の研究は,理論的な基盤の確立とともに,スマートカードなどリソースの限られた環境でのユーザ認証やデジタル署名といった応用を目的としていました12.2015年頃までは,ゼロ知識証明の実用的な応用例は(産業的には)限られていると見られていました(『古い技術:ゼロ知識対話証明』でも「明確に役に立ちそうな目的があって研究された技術なのに使われていない」との言及がされています).
状況が大きく変わったのは,2016年以降に実用的な非対話式ゼロ知識証明(zk-SNARK)の手法が,暗号資産のプロダクトに採用され始めてからです.特に,2013年にIBMとMicrosoft Researchの研究者らが発表したPinocchioプロトコルは,前年に同研究チームが提案したQAP(Quadratic Arithmetic Programs)という手法を基に,プログラムコードを算術回路として表現し,その実行を効率的に証明する実装可能なシステムとして発展させました34.これを基にGroth16など,更に効率的な手法が開発され,より小さな証明サイズと高速な検証を実現しました5.これらの技術は,暗号資産ZCashなどに採用され,ユーザーの残高を秘匿しつつ,その通貨の移動が正しく計算されたことを証明することで,暗号資産の取引における強力なプライバシー保護を実現しました.
その後,ブロックチェーン業界での様々なプロダクト(zkRollupやzkEVMなど)に採用され,ゼロ知識証明技術の需要は急速に膨らんできました.学術界での研究論文数も2016年を境に,発展が伸びていることがわかります.暗号資産/ブロックチェーン業界で広く普及している手法は,zk-SNARK(Zero-Knowledge Succinct Non-interactive Argument of Knowledge)とも呼ばれている手法です.
実は,「zk(ゼロ知識)」と「SNARK」はもともとは別のコンテキストを持つ技術です.SNARKというのは,ゼロ知識証明と同じく証明技術の一種ではありますが,Verifiable Computation(検証可能な計算)を実現する分野の一つです.Verifiable Computationとは,クライアントが複雑な計算をクラウドにアウトソースし,その計算結果が正しいことを証明するための技術です.(詳しくは,『(zk)SNARKへの再入門』の記事が大変わかりやすいです.)
この文脈で重要なのは,証明がコンパクトであり,計算コストが軽いことで,これによりクライアントが少ない計算リソースで計算結果を検証できるようになる点です.SNARK(Succinct Non-interactive ARgument of Knowledge)では,非対話式で簡潔な証明を提供することが可能です.この特徴は,計算量や容量に制限のあるブロックチェーンのプロダクトと非常に相性が良いです.
より厳密に言えば,zk-SNARKは計算量的ゼロ知識アーギュメントに分類されます.これは,zk-SNARKのゼロ知識性と健全性が計算量的な仮定に基づいて保証されているためです.現在,普及している汎用ZKPのプロダクトは計算量的ゼロ知識アーギュメントです.
ZKP技術の特徴
したがって,昨今さまざまなところ(主に暗号資産/ブロックチェーン業界で)用いられている「ゼロ知識証明(zk)」という用語(プロダクトの前に,zkという接頭語がつけることが慣例のようです)には,主に以下の2つの重要な要素が含まれています:
-
ゼロ知識性 - 入力の詳細を一切公開せずに計算を実行し,その結果が信頼できることを保証する
-
検証可能な計算 - コードが設計通りに実行されたことを証明し,それにより得られた出力が信頼できるものであることを保証する
暗号資産やブロックチェーン分野の文脈では,これらの特徴はプライバシーコイン(送金情報を隠して取引する暗号資産)やzkRollup(スケーラビリティ向上のための取引の圧縮)に生かされています.
ところで,やや混乱を生むことが一つあります.「zk」とプロダクトやプロジェクトの名称に付加されていても,必ずしも「ゼロ知識性」を備えているとは限らないのです.(「zk」という用語がブランディング目的で使用されている場合があります.)つまり,入力は公開されており,「検証可能な計算」部分だけを利用することがあります.zkRollupおいては,この誤用については,しばしば言及されており,ゼロ知識証明ではなく「有効性証明(Validity Proof)」と表現されることが多くなってきています.
汎用(General Purpose)なゼロ知識証明
直近10年のゼロ知識証明技術は,幅広く様々な用途に使えるよう進化してきました(したがって,General-purpose ZKP とも呼ばれています).以前は,適用ユースケースが限られていたことを先に述べましたが,実用的な zk-SNARK 手法の登場により,「設計されたプログラムコードが実際に実行されたかどうか」を効率的に証明できるようになりました.これにより,証明したい事柄を柔軟に表現できるようになり,より多様な用途に対応できるようになっています.
典型的な具体的な例としては,年齢が一定以上であるかどうかを証明するケースがあります.以下のコードは,入力された年齢が18歳以上であるかどうかを簡単に判定します.
function proveAgeOver18(age: number): boolean {
return age >= 18;
}
次に,年齢以外のケースとして,JSON ファイルの内容を検証する例を見てみましょう.ここでは,JSON データ内の値の合計が指定された閾値を超えるかどうかを確認します.
function verifyJsonScore(jsonData: Record<string, number>, threshold: number): boolean {
let totalValue = 0;
for (const key in jsonData) {
if (jsonData.hasOwnProperty(key)) {
totalValue += jsonData[key];
}
}
return totalValue >= threshold;
}
この関数は,JSON データ内のすべての数値の合計を計算し,それが指定した閾値を満たすかどうかを確認します.
ゼロ知識証明システムを用いることで,入力データそのものを公開せずに,このようなプログラムの実行結果が正しいことを証明できます.たとえば,ユーザーのアンケート結果から算出されたスコアがある閾値を超えているかどうかを証明する場合,細かいアンケートの回答内容を公開せずに結果だけを証明できます.
このように一般的なプログラムコードを活用し,柔軟に検証内容が表現できるようになれば,暗号資産/ブロックチェーンのコンテキスト以外にも幅広く活用できそうです.例えば,期待できるユースケースとして「デジタルアイデンティティの検証」「プライバシーとコンプライアンスの両立」「計算のアウトソーシング」などが考えられます.(ご興味あれば引用元レポートについてご参照ください.)
汎用ZKPはどのように進化してきているか
さきほど汎用ZKPは,「設計したプログラムコードが実行されたか」を効率的に証明する技術であると紹介しました.古典的なZKPでも,汎用なZKPでも,システム全体としては,証明システム(証明したい事柄があるユーザが用いる)と検証システム(ユーザが主張する事柄を検証したいユーザが用いる)の2つのエンティティが必要であることは変わりません.汎用ZKPでは,この2つのエンティティの間でやり取りされる情報量(Proofのデータサイズ)や通信・計算コストが少なく,実用的な時間内でプロトコルを完了できることに重点を置いて進化してきました.
さらに2016年以降,実際にブロックチェーンのプロダクトに採用されるようになると,ユーザやエンジニアがストレスなく利用や開発できることにも,重点が置かれるように進化してきました.
たとえば,トラステッドセットアップ(trusted setup)の改善です.zk-SNARK では,証明を行う側と検証を行う側が利用するプロトコルのパラメータについて事前に合意する必要があります.このパラメータは,zk-SNARK において CRS(Common Reference String)と呼ばれます.初期の Pinocchio や Groth16 では,プログラムの計算を算術回路として表現し,それを多項式制約に変換した後,正しさを証明するために QAP(Quadratic Arithmetic Programs)というアプローチを採用しています.この方法では,プログラムごとに専用の CRS を生成する必要がありました.
一方,よりモダンな zk-SNARK(例えば PLONK)では,算術回路を構築し,多項式 IOP(Interactive Oracle Proofs)を利用することで,ユニバーサルなトラステッドセットアップを行います.この方法では,一度のトラステッドセットアップで複数のプログラムに対応でき,プログラムごとに CRS を再生成する必要がありません.
また,zk-STARK (Zero-Knowledge Scalable Transparent ARgument of Knowledge) というプロトコルでは,そもそも CRS 自体が不要です.zk-STARK は,透明性のあるセットアップ(transparent setup)を使用するため,トラステッドセットアップのリスクを回避できます.ただし,zk-STARK では証明データのサイズが大きく,証明および検証のパフォーマンスにおいて zk-SNARK に基づく手法より劣ることがあります.とはいえ,セキュリティ面では,透明性とセットアップ不要の利点が zk-STARK の強みです.
このようなユーザーや開発者体験の改善は,ゼロ知識証明を実装するためのプログラムコードにも反映されています.従来,ゼロ知識証明を構築する際には,プログラマは算術回路を意識してコードを記述し,さらに暗号学的な特性を理解しながらプログラミングを行う必要がありました.
そのため,Circom のようなゼロ知識証明専用の DSL(Domain Specific Language)が登場し,こうしたプログラミングの敷居を下げ,多くのエンジニアがゼロ知識証明の実装に取り組めるようにしています.Circomの他にも,Cairo,Noir,Leo など他の多くの ゼロ知識証明のDSL が存在し,複雑なZKP技術の普及に貢献しています.
zkVM(ゼロ知識仮想マシン)の登場
しかし,究極的には,広く普及している既存の言語で,ほとんど制約を意識せずにプログラムの正しさを証明できることが理想です.ここで登場するのが zkVM(ゼロ知識仮想マシン)という概念です.zkVM では,プログラムを直接算術回路に変換するのではなく,まずプログラムを実行し,その実行トレース(メモリやレジスタなどの状態遷移)の整合性を証明します.これにより,zkVM 上で実行されたプログラムについて,第三者は同じ入力で同じ出力が得られることを,再度プログラムを実行せずに短時間で検証できるようになります.さらに,入力の一部は,公開しない(ゼロ知識)という選択も取れます.
アプリケーションの用途を限定しないzkVMのプロダクトとしては,Risc ZeroやSuccinct社のSP1などが知られています.zkVMは従来のプログラムをほぼそのまま利用できるため,既存の開発者が持つスキルを活かしながらゼロ知識証明技術を導入できるという利点もあります.Risc ZeroやSP1ではRustを用いて証明プログラムを実装できるため,Rustクレートをそのまま活用するということも可能です.これにより,エンジニアは暗号技術の専門知識がなくても,高度なプライバシー保護機能を実装できるようになります.
zkVM を利用するメリットとして,例えば先ほどの JSON データをパースして値の合計をチェックするような例でも,プログラマは算術回路に変換する際の複雑な制約を意識する必要がありません.さらに,JSON を扱うための既存のライブラリやプログラムをそのまま流用できる場面も多いと思われます.このように,一般的なプログラミングの感覚で実装できるため,従来の手法に比べて開発が格段に容易になります.
zkVM のカテゴリの一つに,zkEVM というものがあります。zkEVM とは,Ethereum 仮想マシン(EVM)の動作をゼロ知識証明技術でエミュレートする技術です。zkEVM は,Ethereum のスマートコントラクトをそのまま使用できる点が zkVM とは異なります。つまり,Ethereum ベースの DApp やスマートコントラクトに最適化されたアプリケーションのために開発されている技術です。
おわりに
本記事では,ゼロ知識証明技術の進化について解説し,その技術が暗号資産やブロックチェーンの領域を超えて,一般的な用途にも活用できる汎用性を獲得しつつあることを解説しました.特に、zkVM(ゼロ知識仮想マシン)に注目し,プログラマが複雑な算術回路に縛られることなく,容易にゼロ知識証明を実装できる利点について説明しました.
次回パート2では、一般的な zkVM の構造を詳しく解説し、zkVM を用いたアプリケーションの具体的な実装方法を紹介する予定です.
文献
-
Fiat, A., & Shamir, A. (1987). How to Prove Yourself: Practical Solutions to Identification and Signature Problems. Advances in Cryptology — CRYPTO ’86, Lecture Notes in Computer Science, Vol. 263, pp. 186–194. Springer-Verlag. ↩
-
Schnorr, C. P. (1991). Efficient Signature Generation by Smart Cards. Journal of Cryptology, 4(3), 161–174. ↩
-
Gennaro, R., Gentry, C., Parno, B., & Raykova, M. (2013). Quadratic Span Programs and Succinct NIZKs without PCPs. Advances in Cryptology — EUROCRYPT 2013, Lecture Notes in Computer Science, Vol. 7881, pp. 626–645. Springer. ↩
-
Parno, B., Howell, J., Gentry, C., & Raykova, M. (2013). Pinocchio: Nearly Practical Verifiable Computation. 2013 IEEE Symposium on Security and Privacy, pp. 238–252. ↩
-
Groth, J. (2016). On the Size of Pairing-Based Non-interactive Arguments. Advances in Cryptology — EUROCRYPT 2016, Lecture Notes in Computer Science, Vol. 9665, pp. 305–326. Springer. ↩