慢雾:ZKPの主流実装方案の技術的特徴を振り返る

慢雾 Slowmist
2023-02-13 19:23:03
コレクション
開発者はゼロ知識証明回路を開発する際、要求に応じて適切なフレームワークを選択し、プロジェクトのローンチ前にアプリケーションの安全性について包括的なセキュリティ監査を行うことを確認する必要があります。

出典:慢雾

概要

ブロックチェーンシステムの動作原理を研究する際、私たちはさまざまな暗号学の知識を理解する必要があります。例えば、secp256k1は曲線と非対称署名アルゴリズムであり、ビットコインやイーサリアムシステムでアカウントの署名と検証に使用されます。例えば、sha256は可変長の情報を固定長のエンコードに圧縮するためのハッシュアルゴリズムです。例えば、base58は情報のエンコードを印刷可能な文字列に変換します。例えば、ECDHはDiffie-Hellman鍵交換アルゴリズムであり、P2Pノード間で通信鍵を安全に交換するために使用されます。

ゼロ知識証明(Zero-knowledge Proof)は暗号学アルゴリズムの一種で、略してZKPまたはZKと呼ばれます。その特徴は、他の情報を漏らすことなく命題の正しさを証明できることです(多くの人が「ゼロ知識証明」という名称に異議を唱え、「ゼロ漏洩証明」の方がその本質的な能力を表していると考えています)。

ZKPは1985年に初めて提案されましたが、長い間大規模な応用シーンが見つからなかったため、技術の発展は非常に遅れていました。2009年にビットコインが誕生した後、人々はそれがブロックチェーンのプライバシーとスケーラビリティの問題を解決するのに非常に適していることを発見し、それ以来、多くの資本と人材がこの技術の開発と工学的応用に投入されました。ZKPには多くの実装があり、例えばGroth16、PlonK、STARKなどがありますが、今のところ真の業界標準は存在していません。本稿では、さまざまなZKP実装の技術的特徴を振り返り、皆さんの学習研究や工学開発に役立つことを期待しています。

ZKPの応用分野

1. プライバシー証明

ZcashはZKPの最初の広く使用されるアプリケーションかもしれません。これはビットコインのソースコードを基に、ZKPをトークンの移転に適用し、取引情報を完全に秘密にしながら、ブロックチェーン上のノードによって検証可能にします。

Tornado Cashはイーサリアム上で動作するミキサーで、ZKPを使用してMerkle-Tree上のノードを証明します。ユーザーは固定額のトークンを資金プールに預け、その後ZKP生成のProofを使用して自分が資金を預けたことを証明できますが、預け入れ時の取引情報を公開する必要はありません。

2. 計算アウトソーシング

ブロックチェーンでは、各ノードの計算能力は限られていますが、ZKP技術を利用することで、ノードは大量の計算をオフチェーンノードにアウトソースできます。この場合、アウトソースされた計算結果と計算証明を検証するだけで、計算が正しいかどうかを知ることができます。

zksync1.0はその良い例で、オフチェーンでイーサリアムトークンの送金と取引を行い、その結果をノードに提出します。ノードはZKP証明を検証することで、宣言された方法で計算が行われたかどうかを知ることができます。

3. データ圧縮

FilecoinはZKPを利用して時空証明システムを構築し、ユーザーが特定のファイルをローカルに保存していることを証明できます。現在、保存されたファイルは18EiBに達しています。

Minaは別の例で、多くの高速ブロックチェーンシステムでは取引データが非常に大きく、システムは合意プロトコルの検証のためにすべてのブロックを保持する必要があります。そのため、システムはハードウェアに対する要求が非常に高く、永続的な保存はブロックチェーンノードがディスクスペースとデータインデックス能力を増大させ続けることを意味します。この時、ZKPを利用して検証データを圧縮することができます。Minaは再帰的ゼロ知識証明を通じて帳簿を11KBに圧縮しながら、依然としてブロックの正確性を検証できます。

ZKP証明システム

証明システムはZKPの基盤となるアルゴリズム実装で、インタラクティブと非インタラクティブの2種類に分けられます。

1. インタラクティブ証明システム

インタラクティブ証明システムは、証明者(Prover、略してP)と検証者(Verifier、略してV)の2者が参加します。Pはある秘密(例えば公開鍵暗号方式の秘密鍵や二次残余xの平方根)を知っており、PはVに自分がその秘密を持っていることを信じてもらいたいと考えています。インタラクティブ証明は数ラウンドで構成され、各ラウンドでPとVは相手から受け取ったメッセージや自分が計算した結果に基づいてメッセージを送信する必要があります。典型的な方法は、各ラウンドでVがPに質問を発し、PがVに応答することです。すべてのラウンドが終了した後、VはPが自分の質問に正しく応答できたかどうかに基づいて、Pの証明を受け入れるかどうかを決定します。

2. 非インタラクティブ証明システム

上記のインタラクティブ証明システムでは、PとVは相互作用せず、証明はPによって生成され、直接Vに渡され、Vは証明を直接検証します。このような証明システムは非インタラクティブ証明システム(NIZK)と呼ばれます。

私たちがブロックチェーンで使用する証明システムは一般的にNIZKであり、ブロックチェーンのノードは検証者Vであり、エンドユーザーまたはレイヤー2ネットワーク(Layer2)は証明者Pです。

文末の参考リンク[1]では、過去10年間に公開されたNIZKスキームとその特徴について説明しています。

実際の工学的応用では、私たちは主に性能と汎用性に注目しています。そのため、一般的な証明システムについてより詳細な分類と比較を行います。文末の参考リンク[2]を参照してください:

  • Bulletproofs

    特徴:簡潔な証明サイズ、信頼できる設定は不要ですが、証明の生成と検証に時間がかかります。

    代表プロジェクト:Bulletproofs、Halo、Halo2。

  • SNARKs(Succinct Non-interactive ARguments of Knowledge)

    特徴:簡潔な証明サイズ、証明の検証にかかる時間は比較的短いですが、各回路に対して信頼できる設定が必要です。

    代表プロジェクト:Groth16。

  • SNORKs(Succinct Non-interactive Oecumenical(Universal)Arguments of Knowledge)

    特徴:簡潔な証明サイズ、すべての回路に対して一度の信頼できる設定で使用できます。

    代表プロジェクト:Sonic、PlonK、Marlin、Plonky2。

  • STARKs(Succinct(Scalable)Transparent ARguments of Knowledge)

    特徴:証明は非常に大きく、信頼できる設定は不要で、良好なスケーラビリティを持っています。

    代表プロジェクト:STARK。

この分類も絶対的ではありません。例えば、Halo/Halo2プロジェクトは、設計時に多くのPlonkの考え方を参考にしています。また、SNORKsは通常SNARKsに分類されます。なぜなら、両者とも信頼できる設定が必要だからです。

3. 性能比較

image

image

(文末の参考リンク[3]を参照)

回路プログラミング

回路はZKPシステムのビジネスロジックの実装であり、ZKPアプリケーションを開発するには回路プログラミングが必要です。なぜZKPロジックコードが「回路」と呼ばれるのか、主に以下の理由があります:

  • ZKP証明のコードは、一連の単純な制約条件の表現R1CSに変換され、その後ラグランジュ補間法を使用して巨大な多項式QAPに変換され、最終的にゲート回路の形式で制約されます。

  • ハードウェア回路と同様に、すべての分岐のコードは一緒に実行されます。

  • ハードウェア回路と同様に、ZKP証明回路には再帰や複雑なループがなく、ループの数は一定でなければなりません。

私たちはゼロから暗号学を用いてZKPアプリケーションを実装する必要はありません。多くの開発ライブラリがこれらの基盤となる証明システムを実装していますので、私たちはビジネスロジックの実装に注目すればよいのです。もちろん、各ライブラリには異なる抽象度があり、回路の表現を学ぶ必要があるものもあれば、プロセスに従ってコードを定義するだけで簡単に実装できるものもあります。

1. よく使われる開発ライブラリ

  • libsnark

C++言語で実装された汎用証明システム、基礎回路ライブラリ、およびアプリケーションの例。

証明システム:BBFR15、BCCT12、BCCT13、BCGTV13、BCIOP13、BCTV14a、BCTV14b、CTV15、DFGK14、Groth16、GM17、GGPR13、PGHR13。

リンク:https://github.com/scipr-lab/libsnark。

  • gnark

Go言語で実装された証明システムで、回路設計のための高レベルAPIを提供します。

証明システム:Groth16、PlonK。

リンク:https://github.com/consensys/gnark。

  • bellman

Rustで実装された証明システムで、回路インターフェース、基盤構造、およびいくつかの基本的な回路実装(例えばブールおよび数値抽象)を提供します。

証明システム:Groth16。

リンク:https://github.com/zkcrypto/bellman。

  • snarkjs

JavascriptおよびWASMで実装された証明システムで、信頼できる設定、証明の生成および検証に使用できます。snarkjsはiden3独自のcircomコンパイラを使用してDSLで定義された回路をコンパイルします。

証明システム:Groth16、PlonK。

リンク:https://github.com/iden3/snarkjs。

  • ethsnarks

Pythonで実装されており、ユーザーのブラウザで証明を生成し、イーサリアムスマートコントラクトを検証者として使用できます。現在、プロジェクトの開発は活発ではなく、同じシーンではCircomを使用する方が良い選択かもしれません。

証明システム:Groth16。

リンク:https://github.com/HarryR/ethsnarks。

  • bulletproofs

Rustで実装された証明システムで、単一および集約範囲の証明、強い型の多者計算を持ち、任意の文のプログラム可能な制約システムAPIの証明に向けて開発中です。

証明システム:bulletproofs。

リンク:https://github.com/dalek-cryptography/bulletproofs。

  • halo2

Rustに基づいて実装された証明システムで、ZCashチームによって維持されています。Halo2はPLONKishに特化しており、算術演算における回路の表現方法を非常に直接的に制御でき、高度に最適化された回路を書くのに非常に適しています。

証明システム:Halo2。

リンク:https://github.com/zcash/halo2。

2. 開発プロセス

gnarkを例にとると、典型的な作業フローは以下の図のようになります:

image

1)コードを使用して解決すべき問題を記述します。

2)R1CS制約システムにコンパイルします。

3)R1CSに対して信頼できる設定を行い、Proving keyとVerify keyを取得します。

4)証明者はR1CSとProving keyを使用して秘密データを計算し、証明Proofを生成します。

5)検証者はVerify keyを使用してProofを検証します。

回路プログラミング専用言語

1. イーサリアムプラットフォームに基づく

  • Cairo

Cairoは、ある一方が別の一方に特定の計算が正しく実行されたことを証明できるプログラミング言語です。Cairoと類似の証明システムは、ブロックチェーンにスケーラビリティを提供するために使用できます。StarkNetはCairoプログラミング言語をそのインフラストラクチャとStarkNet契約の作成に使用しています。

証明システム:STARK。

リンク:https://www.cairo-lang.org/docs/。

  • Zokrates

ZoKratesはDSLを使用して回路を記述し、いくつかの一般的な回路ライブラリを提供します。これにより、DAppで検証可能な計算を使用するのが容易になります。高級言語でプログラムを仕様し、計算証明を生成し、Solidityでこれらの証明を検証することができます。

証明システム:GM17、Groth16、Marlin。

リンク:https://zokrates.github.io/。

  • Circom

Circom言語はDSLを使用して回路を記述し、snarkjsと組み合わせてユーザーのブラウザで証明を生成し、イーサリアムスマートコントラクトを検証者として使用できます。

証明システム:Groth16、PlonK。

リンク:https://iden3.io/circom。

  • Noir

AztecのRustに基づくプライバシープログラミング言語で、DSLを使用して回路を記述し、安全かつシームレスにプライバシー保護のゼロ知識回路を構築できます。

証明システム:PlonK。

リンク:https://noir-lang.org/index.html。

  • zkEVM

EVMと同様に、zkEVMは仮想マシンであり、プログラム操作の結果として状態間で変換されますが、zkEVMは計算の各部分の正確性を証明するために証明を生成します。本質的に、zkEVMは実行ステップがルールに従っていることを証明するメカニズムを使用します。

現在、zkSync、Polygon、Scroll、StarkwareなどのチームがzkEVMの実装に取り組んでおり、重要な進展を遂げています。

2. 公共チェーンプラットフォームに基づく

  • zkApp(Mina)

zkAppsはMina Protocolのスマートコントラクトで、ゼロ知識証明によってサポートされています。zkAppsはオフチェーンで任意の複雑な計算を実行でき、生成されたゼロ知識証明をチェーンに送信してこの計算を検証するために固定料金を請求します。これは、他のチェーン上で計算を実行し、可変ガス料金に基づくブロックチェーンとは対照的なモデルです。zkAppsはTypescriptで記述されています。

証明システム:PlonK。

リンク:https://docs.minaprotocol.com/zkapps。

  • LEO(Aleo)

Leoは関数型静的型プログラミング言語で、プライベートアプリケーションの作成のために構築されています。開発者向けに設計されており、Aleoブロックチェーン上で直感的に構築でき、プライベートで分散型のエコシステムの基盤を提供します。

証明システム:Marlin。

リンク:https://leo-lang.org/。

ZKPの一般的なセキュリティ問題

過去数年、慢雾のセキュリティチームは、ZKSwap、Zkdex、Zksafeなどの複数の著名なZKP製品に対して回路およびアプリケーションのセキュリティ監査を実施し、複数の中高危険な脆弱性を発見しました。Circom、libsnarkなどの一般的なフレームワークで開発されたアプリケーションに対して深い理解を持っています。慢雾のセキュリティチームは、ZKPアプリケーションの監査において一般的なセキュリティ問題を以下のように発見しました:

  • 信頼パラメータリスク

zk-SNARKsを使用するためには、公共パラメータのセットが必要で、これを公共参照文字列(CRS)と呼びます。しかし、これらのパラメータの生成にはいくつかのプライベートパラメータも生成されます。もしある一方がこれらのプライベートパラメータを取得した場合、彼らは証明を偽造することができます。

さらに、CRSの生成プロセスは監査を受ける必要があり、ランダム数のバックドアがないことや、プライベートパラメータが意図的に保持されないことを確認する必要があります。zk-SNORKsを使用する際も、構造化参照文字列(SRS)が信頼できることを確認する必要があります。

信頼できる設定段階のセキュリティリスクは、安全な多者計算(MPC)を使用して解決できます。MPCの特徴は、参加者のいずれかが誠実に参加すれば、最終的に得られる計算結果が信頼できることです。

  • 静的コードセキュリティ

この部分は主にコーディングの不規則性から生じるセキュリティ問題です。例えば、パラメータが検証されていない、戻り値が処理されていない、数値オーバーフロー、境界がチェックされていないなどです。回路を記述する言語がC/C++の場合、メモリオーバーフローのリスクも存在します。

  • サプライチェーン攻撃リスク

サプライチェーンのリスクは、脆弱性のあるコードライブラリを使用することから来ます。例えば、古いバージョンのリポジトリです。通常、ZKPアプリケーションはクライアントやWebフロントエンドと連携して使用される必要があり、これらの部分もさまざまな方法でハッカー攻撃を受けやすいです。

  • 論理エラー

論理エラーは回路実装で最も発生しやすいエラーであり、要件文書と照らし合わせて回路の設計が要件に合致しているかを確認する必要があります。

  • 二重支払い攻撃

誤った設計は二重支払い攻撃を引き起こす可能性があります。例えば、特定のZKPライブラリには拡張性リスクがあり、攻撃者は既知のProofを利用して異なるProofを生成できます。設計が不適切であれば、二重支払い攻撃を引き起こす可能性があります。

  • 証明の偽造

有効な証明はZKPが最初に解決すべき問題であり、完全性と信頼性を確保する必要があります。つまり、「偽は真にならず、真は偽にならない」ということです。したがって、ある回路が偽の証明を生成できる場合、通常は基盤ライブラリに脆弱性があるため、私たちはプロジェクト側に公開され、監査されたZKPライブラリを使用し、安定したリリース版を使用することをお勧めします。

  • サイドチャネル攻撃

回路設計が不適切な場合、異なるプライバシー情報は異なる計算特性を持つ可能性があり、攻撃者は公開された入力や証明を通じてプライベート入力データを推測する可能性があります。

  • 回路制約の無効化

不適切な回路表現は、変数が制約されない原因となる可能性があります。

  • 特殊値攻撃

特定の入力値はシステムの検証ロジックを回避する可能性があります。例えば、0やnullなどです。

  • プライバシー入力の推測

Tornado Cashなどのアプリケーションでは、入力情報が推測可能な場合、深刻なプライバシー漏洩問題を引き起こす可能性があります。この場合、入力データに対して厳格な監査を行い、推測できないことを確認する必要があります。

  • RugPullリスク

一部のプロジェクトには特別な管理者権限が存在する可能性があり、一旦権限が不正に使用されると、プロジェクトの資金やユーザーの資産が盗まれる可能性があります。

  • スマートコントラクトリスク

一部のZKP証明はスマートコントラクトを使用して検証されます。例えば、CircomやZoKratesなどです。スマートコントラクトには再入、リプレイ、論理エラーなどのリスクが存在する可能性があります。詳細は慢雾のセキュリティチームのスマートコントラクトセキュリティ監査サービスを参照してください。

上記のZKPセキュリティ問題に対して、慢雾のセキュリティチームは攻防実戦の中で一連の安全解決策をまとめ、ブラックボックス/グレーボックス/ホワイトボックスのさまざまなテスト手法を組み合わせて、ブロックチェーン業界向けのZKP回路監査サービスを提供しています。

まとめ

ゼロ知識証明は、ブロックチェーンのプライバシー、計算のスケーラビリティ、データ圧縮の問題を解決するための有効な方法です。現在、多くの実装ソリューションが存在し、これらの実装ソリューションは異なる性能パラメータ指標とセキュリティ基準を持っています。開発者はゼロ知識証明回路を開発する際、要件に応じて適切なフレームワークを選択し、プロジェクトのローンチ前にアプリケーションのセキュリティを全面的に監査することに注意する必要があります。

最後に、先進的なワンストップデジタル資産自己管理サービスプロバイダーであるSafeheronからの専門的な技術アドバイスに感謝します。

参考リンク:

[1]. https://en.wikipedia.org/wiki/Zero-knowledge_proof

[2]. https://github.com/matter-labs/awesome-zero-knowledge-proofs

[3].https://docs.google.com/presentation/d/1gfB6WZMvM9mmDKofFibIgsyYShdf0RV_Y8TLz3k1Ls0/edit

ChainCatcherは、広大な読者の皆様に対し、ブロックチェーンを理性的に見るよう呼びかけ、リスク意識を向上させ、各種仮想トークンの発行や投機に注意することを提唱します。当サイト内の全てのコンテンツは市場情報や関係者の見解であり、何らかの投資助言として扱われるものではありません。万が一不適切な内容が含まれていた場合は「通報」することができます。私たちは迅速に対処いたします。
banner
チェーンキャッチャー イノベーターとともにWeb3の世界を構築する