零知識電路開發完整教學:從理論基礎到智能合約整合的開發者路徑

本文提供從電路設計基礎到實際智能合約整合的完整開發者路徑。涵蓋:零知識證明的形式化定義與代數電路視角、Circom 開發環境架設與工具鏈配置、常見電路設計模式(比較器、範圍證明、Merkle 樹驗證)、複雜電路設計原則與調試技巧、從電路到 Solidity 驗證合約的完整工作流、信任設置(Powers of Tau)詳解、以及 NOIR 和 Halo2 等新一代工具的入門介紹。提供完整的代碼範例和開發實踐指導。

零知識電路開發完整教學:從理論基礎到智能合約整合的開發者路徑

概述

零知識證明(Zero-Knowledge Proof,ZKP)是以太坊隱私技術的核心支柱,也是當今密碼學領域最具變革性的技術之一。本文提供從電路設計基礎到實際智能合約整合的完整開發者路徑,涵蓋 ZK-SNARKs 和 ZK-STARKs 兩大主流證明系統的理論基礎、開發工具、実作技巧和部署流程。

本文假設讀者具備以下背景知識:熟悉以太坊智能合約開發(Solidity)、理解基本的密碼學概念(如哈希函數、橢圓曲線)、有基本的命令行操作能力。對於零基礎讀者,建議先閱讀本系列的其他基礎文章,如《零知識證明完整指南》和《橢圓曲線密碼學基礎》。

零知識電路開發是以太坊隱私技術從理論走向實際應用的橋樑。一個設計良好的 ZK 電路可以讓開發者在不透露具體輸入值的情況下,向驗證者證明某個計算陳述式為真。這種能力對於實現隱私交易、去中心化身份、監管合規等應用場景至關重要。隨著 zkEVM、zkSync、StarkNet 等 Layer 2 解決方案的成熟,零知識證明技術的市場需求正在快速增長,熟練掌握這項技術的開發者將在未來的就業市場中佔據顯著優勢。

第一章:理論基礎回顧

1.1 零知識證明的形式化定義

零知識證明系統由三個核心角色構成:證明者(Prover)、驗證者(Verifier)和抽取器(Extractor)。一個 ZK 協議需要滿足三個性質:

完整性(Completeness):如果陳述式為真,且證明者是誠實的,則驗證者最終一定會接受證明。換句話說,誠實的證明者總能說服誠實的驗證者。

穩健性(Soundness):如果陳述式為假,則任何證明者(即使是不誠實的)都幾乎不可能說服驗證者。這個性質保證了零知識證明的安全性。

零知識性(Zero-Knowledge):驗證者在證明過程中無法獲得任何關於「秘密輸入」的知識,只能確認陳述式為真。這是零知識證明區別於其他證明系統的核心特徵。

在實際應用中,我們通常使用「非互動式零知識證明」(Non-Interactive Zero-Knowledge Proof,NIZK)。非互動式的好處是證明可以被任何人驗證,無需證明者和驗證者之間的在線交互。這種特性特別適合區塊鏈應用場景,因為區塊上的交易可以被任何人獨立驗證。

1.2 代數電路的視角

從電路設計的角度,我們可以將零知識證明理解為一種「可驗證計算」協議。假設我們有一個計算函數 f,以及公開的輸出 y 和私密的輸入 x。我們的目標是讓證明者證明「存在 x 使得 f(x) = y」,而驗證者除了「陳述式為真」之外無法獲得關於 x 的任何信息。

在 ZK 電路模型中,計算首先被轉換為一組多項式約束。這些約束通常以「R1CS」(Rank-1 Constraint System,一階約束系統)的形式表達。一個 R1CS 由一組形如 <A, W> * <B, W> = <C, W> 的約束組成,其中 A、B、C 是線性組合矩陣,W 是見證向量(witness vector)。

舉一個具體例子。假設我們要證明「我知道一個數字的平方等於 9」。這個陳述式可以轉換為 R1CS 約束:a * a = b,其中 a 是秘密輸入(3),b 是公開輸出(9)。R1CS 約束會檢查 W 中的相應元素是否滿足這個等式。

1.3 從 NP 到 NIZK:複雜性理論視角

從計算複雜性理論的角度,零知識證明的適用範圍與 NP 問題類別高度重合。對於任何在 NP 時間內可驗證的陳述式,原則上都可以構造相應的零知識證明協議。

這個結論的直覺含義是:任何可以用「簡潔證據」快速驗證的計算,都可以用零知識方式證明。這涵蓋了非常廣泛的應用場景,包括:

第二章:Circom 開發環境架設

2.1 工具鏈概述

Circom 是目前最流行的零知識電路編譯器之一,由 Identrium(原 ZK-Snarks)團隊開發。它使用一種領域特定語言(DSL)來描述電路,編譯器會自動生成相應的 R1CS 約束系統和見證生成程序。

Circom 開發環境的標準工具鏈包括:

Circom 編譯器:將 .circom 源文件編譯為電路約束文件和 proving key / verification key。

SnarkJS:JavaScript/TypeScript 實現的 ZK-SNARK 證明和驗證庫,支持在瀏覽器和 Node.js 環境中運行。

編譯後的 Rust 組件:SnarkJS 底層使用 WebAssembly 和 Rust 實現的高性能密碼學運算。

2.2 開發環境架設步驟

以下是在 Ubuntu 22.04 環境中架設 Circom 開發環境的完整步驟。

首先,安裝系統依賴:

# 更新系統並安裝基礎工具
sudo apt-get update
sudo apt-get install -y build-essential git curl wget pkg-config libomp-dev

# 安裝 Rust(用於編譯 circom)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
rustup default stable

# 安裝 Node.js(建議使用 v18 LTS 或更高版本)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

其次,下載並編譯 Circom:

# 克隆 Circom 倉庫
git clone https://github.com/iden3/circom.git
cd circom

# 檢出穩定版本(本文基於 v2.1.6)
git checkout v2.1.6
git submodule update --init --recursive

# 編譯 Release 版本
cargo build --release
cargo install --path circom

# 將路徑添加到 PATH
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

第三,安裝 SnarkJS:

# 使用 npm 安裝 snarkjs
npm install -g snarkjs

# 驗證安裝
snarkjs --version

第四,設置項目結構:

# 創建項目目錄
mkdir -p ~/zk-learning && cd ~/zk-learning
mkdir -p circuits src build powers_of_tau

# 初始化 npm 項目
npm init -y
npm install circomlib snarkjs

2.3 驗證開發環境

完成架設後,讓我們用一個簡單的電路來驗證環境是否正確配置。

首先,創建第一個電路文件 src/simple_multiplier.circom

pragma circom 2.1.6;

// 簡單的乘法電路:證明我知道 a 和 b 使得 a * b = out
template Multiplier() {
    // 宣告輸入信號
    signal input a;
    signal input b;
    
    // 宣告輸出信號
    signal output out;
    
    // 約束:輸出必須是 a * b
    out <== a * b;
    
    // 附加約束(防止簡化攻擊)
    a * b === out;
}

// 主電路
component main {public [out]} = Multiplier();

編譯這個電路:

# 編譯電路
circom src/simple_multiplier.circom --r1cs --wasm --sym -o build

# 查看電路信息
snarkjs r1cs info build/simple_multiplier.r1cs

正確配置下,輸出應該顯示:

第三章:電路設計模式

3.1 常見電路組件

在實際開發中,大多數電路會使用一些常見的電路組件。Circomlib 是 Circom 社區維護的標準組件庫,提供了大多數常用電路的實現。

以下是一些最常用的電路組件:

比較器(Comparator):用於比較兩個值的大小。例如,要檢查 a >= b,可以利用 a - b 的符號來判斷。

// circuit_less_than.circom
pragma circom 2.1.6;
include "../node_modules/circomlib/circuits/comparators.circom";

// 檢查 a < b
template LessThan(n) {
    signal input in[2];
    signal output out;
    
    component lt = LessThan(n);
    lt.in[0] <== in[0];
    lt.in[1] <== in[1];
    out <== lt.out;
}

範圍證明(Range Proof):證明一個值在特定範圍內,而不提確切值。這在隱私交易中常用於證明余額非負。

// circuit_range_proof.circom
pragma circom 2.1.6;
include "../node_modules/circomlib/circuits/bitify.circom";

// 證明 value 在 [0, 2^n) 範圍內
template RangeProof(n) {
    signal input value;
    signal input bits[n];
    
    // 將 value 轉換為二進制表示
    component num2bits = Num2Bits(n);
    num2bits.in <== value;
    
    // 約束每個位元
    for (var i = 0; i < n; i++) {
        bits[i] <== num2bits.out[i];
    }
    
    // 額外的範圍檢查(可選)
    // 如果 value >= 2^n,則約束無法滿足
}

Merkle 樹驗證:證明某個元素是 Merkle 樹中某個葉子節點的成員,而不透露具體是哪個葉子。

// circuit_merkle_proof.circom
pragma circom 2.1.6;
include "../node_modules/circomlib/circuits/poseidon.circom";
include "../node_modules/circomlib/circuits/bitify.circom";

// Merkle 樹驗證器
template MerkleTreeChecker(levels) {
    signal input leaf;
    signal input root;
    signal input pathElements[levels];
    signal input pathIndices[levels];
    
    component hashers[levels];
    component mux[levels];
    
    signal computedHash[levels + 1];
    computedHash[0] <== leaf;
    
    for (var i = 0; i < levels; i++) {
        // 使用 Poseidon 哈希(適用於 Groth16)
        hashers[i] = Poseidon(2);
        
        // 選擇左/右節點
        hashers[i].inputs[0] <== pathIndices[i] == 0 ? computedHash[i] : pathElements[i];
        hashers[i].inputs[1] <== pathIndices[i] == 0 ? pathElements[i] : computedHash[i];
        
        computedHash[i + 1] <== hashers[i].out;
    }
    
    // 約束根節點匹配
    root === computedHash[levels];
}

3.2 複雜電路設計原則

設計複雜零知識電路時,需要遵循一些關鍵原則來確保電路的正確性、安全性和效率。

原則一:最小化約束數量。約束數量直接影響電路的證明生成和驗證時間。在設計電路時,應盡量減少約束數量。一個常見的優化技巧是:使用信號賦值(<==-->)代替顯式約束(===),因為賦值運算會自動生成約束,但某些賦值(如簡單乘法)可以被約束系統識別為「不需要生成約束」的情況。

原則二:避免非確定性。電路的每個約束都必須是確定性的——給定相同的見證值,約束要么被滿足,要么不被滿足,不存在模糊狀態。避免在約束中使用未初始化的信號或依賴執行順序的邏輯。

原則三:保護隱私輸入。所有不希望被驗證者知道的信號都應標記為私有(不添加到 component main {public [...]} 聲明中)。注意,某些操作(如循環計數器)在某些情況下可能會泄露信息,需要特別處理。

原則四:防範簡化攻擊(Circom Simplifier Attack)。某些電路可能存在「繞過約束」的漏洞。例如,如果一個乘法約束為 out <== a * b,攻擊者可能構造一個「假的」a、b、out 值,使得 out = a * b 成立,但這些值並非來自真實計算。防範這種攻擊的方法是在電路中添加額外的約束或使用「附加約束」語法 ===

3.3 電路調試技巧

零知識電路調試是出了名的困難,因為電路一旦編譯完成,很難定位問題的根源。以下是一些實用的調試技巧:

使用調試信號。在開發階段,可以在電路中添加「調試信號」,這些信號可以被賦予任何值而不影響約束系統。當電路無法滿足約束時,調試信號可以幫助定位問題。

// 添加調試信號
signal debugIntermediate <== intermediateValue;
// 在 witness 計算完成後,可以打印 debugIntermediate 的值

分步驗證。將複雜電路拆分為多個子電路,分別測試每個子電路的正確性,最後再組合在一起。這種方法可以顯著縮小問題範圍。

使用 snarkjs 進行本地測試。在正式部署前,使用 snarkjs 在本地環境中生成和驗證證明,確保電路邏輯正確。

// test_circuit.js
const { prove, verify } = require('snarkjs');

async function test() {
    // 生成見證
    const input = { a: 3, b: 5 };
    const { wtns } = await calculateWitness("build/simple_multiplier.wasm", input);
    
    // 生成證明
    const { proof, publicSignals } = await prove(
        "build/simple_multiplier_final.zkey",
        "build/simple_multiplier.wtns"
    );
    
    // 驗證證明
    const vKey = JSON.parse(fs.readFileSync("build/simple_multiplier_verification_key.json"));
    const verified = await verify(vKey, publicSignals, proof);
    
    console.log("Verification result:", verified);
}

第四章:從電路到智能合約

4.1 完整的開發工作流

將零知識電路部署到以太坊需要一個標準化的工作流程。這個流程包括:電路設計與編譯、信任設置(Trusted Setup)、證明生成、部署驗證合約、以及鏈上驗證。

以下是這個流程的概述,詳細步驟將在後續章節中介紹。

第一步:設計電路。根據應用需求,設計零知識電路的邏輯。這是最核心的步驟,需要在隱私性、效率和正確性之間取得平衡。

第二步:編譯電路。使用 Circom 編譯器將 .circom 源文件編譯為 R1CS 約束文件和 WASM 程序。

第三步:執行信任設置。對於 Groth16 證明系統,需要執行一個「信任設置」儀式,生成 proving key 和 verification key。對於 Plonk 或 Halo2 等通用證明系統,需要執行 Powers of Tau 儀式。

第四步:生成證明。使用編譯後的 WASM 程序和 proving key 生成零知識證明。

第五步:部署驗證合約。將 verification key 和驗證邏輯部署到以太坊區塊鏈上作為智能合約。

第六步:鏈上驗證。用戶提交證明,智能合約執行驗證邏輯,決定接受或拒絕。

4.2 信任設置詳解

信任設置(Trusted Setup)是大多數 ZK-SNARK 協議的必要步驟。它的目的是生成一組「有毒廢物」(toxic waste)—— 一組秘密的隨機數——用於構造證明和驗證密鑰。

信任設置的「信任」體現在:生成這些秘密數字的過程必須是可信的。一旦知道這些秘密數字,攻擊者就可以構造假證明,繞過驗證。因此,信任設置通常採用多方計算(MPC)的方式,讓多個獨立參與者共同生成密鑰,只要其中任何一個參與者是誠實的,整個系統就是安全的。

對於 Groth16 協議,信任設置分為兩個階段:

第一階段:通用 Powers of Tau。這是與電路無關的階段,任何電路都可以使用相同的 Powers of Tau 輸出。這個階段的輸出是一個「大聖物」(big Powers of Tau),可以供多個電路使用。

第二階段:電路特定階段。這個階段的輸出是特定電路的 proving key 和 verification key。它需要第一階段的輸出作為輸入。

使用 snarkjs 執行 Powers of Tau 的步驟:

# 第一階段:執行 Powers of Tau
# 選擇曲線(BN128 與以太坊兼容)
snarkjs powersoftau new bn128 25 powers_of_tau/pot25_final.ptau -v

# 對第一階段結果進行約束
snarkjs powersoftau prepare phase2 powers_of_tau/pot25_final.ptau powers_of_tau/pot25_final.ptau

# 第二階段:為特定電路貢獻隨機性
snarkjs groth16 setup build/simple_multiplier.r1cs powers_of_tau/pot25_final.ptau build/multiplier_0000.zkey

# 添加第二階段貢獻
snarkjs zkey contribute build/multiplier_0000.zkey build/multiplier_0001.zkey --name="First contribution" -v

# 驗證最終 zkey
snarkjs zkey verify build/multiplier_0001.zkey

# 導出最終的 zkey
snarkjs zkey export final build/multiplier_0001.zkey build/multiplier_final.zkey

4.3 Solidity 驗證合約生成

snarkjs 可以自動生成 Solidity 驗證合約。這個合約封裝了零知識證明的驗證邏輯,可以部署到以太坊區塊鏈上。

# 生成 Solidity 驗證合約
snarkjs zkey export solidityverifier build/multiplier_final.zkey src/MultiplierVerifier.sol

# 查看生成的合約
cat src/MultiplierVerifier.sol

以下是生成的驗證合約的核心結構:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MultiplierVerifier {
    // G1 點加法
    function pairing(
        bytes memory _pA,
        bytes memory _pAp,
        bytes memory _pB,
        bytes memory _pBp,
        bytes memory _pC,
        bytes memory _pCp,
        bytes memory _pH,
        bytes memory _pHp,
        bytes memory _pK,
        bytes memory _pKp,
        bytes memory _pPubSignals,
        address _verifierAddr
    ) internal view returns (bytes32) {
        // 配對檢查邏輯
        // ...
    }
    
    // 主要驗證函數
    function verifyProof(
        uint256[2] memory a,
        uint256[2][2] memory b,
        uint256[2] memory c,
        uint256[1] memory input
    ) public view returns (bool) {
        // 調用 Groth16 驗證算法
        // ...
    }
}

4.4 完整範例:私人轉帳

讓我們用一個更複雜的範例來演示完整的開發流程:實現一個簡化的「私人轉帳」電路。這個電路允許用戶在不透露餘額和轉帳金額的情況下,向區塊鏈證明其餘額足以支付轉帳。

首先,設計電路邏輯:

pragma circom 2.1.6;
include "../node_modules/circomlib/circuits/poseidon.circom";

template PrivateTransfer(levels) {
    // 公開輸入
    signal input root;           // Merkle 樹根
    signal input recipient;      // 收款人公鑰哈希
    signal input nullifier;      // 廢棄標記
    
    // 私有輸入
    signal input balance;         // 當前餘額(私密)
    signal input amount;          // 轉帳金額(私密)
    signal input secret;          // 秘密隨機數(私密)
    signal input merklePath[levels];  // Merkle 證明路徑
    signal input merklePathIndices[levels];  // 路徑方向
    
    // 驗證餘額 >= 轉帳金額
    balance >= amount;
    
    // 計算新餘額
    signal output newBalance;
    newBalance <== balance - amount;
    
    // 驗證 Merkle 證明(省略詳細實現)
    // 確保余額存儲在 Merkle 樹中
    
    // 計算 nullifier(用於防止雙花)
    // nullifier = hash(secret, balance)
    component poseidonHasher = Poseidon(2);
    poseidonHasher.inputs[0] <== secret;
    poseidonHasher.inputs[1] <== balance;
    nullifier === poseidonHasher.out;
}

然後,編譯、執行信任設置、生成驗證合約,最後部署到區塊鏈上。

第五章:NOIR 語言介紹

5.1 NOIR 的設計理念

NOIR(No Object IR)是由 Aztec Network 開發的新一代零知識電路語言。它的設計目標是提供一種比 Circom 更易用、更安全的電路描述語言。

NOIR 的主要特點包括:

語法簡潔:NOIR 使用類似 Rust 的語法,對大多數開發者來說更直觀。

電路抽象:NOIR 提供更高層次的抽象,如循環和函數,簡化電路設計。

安全性優先:NOIR 的編譯器内置了多種安全檢查,防止常見的電路漏洞。

通用性:NOIR 程序可以被編譯到不同的後端(不僅是 Groth16),包括 Plonk 和 Honk 等。

5.2 NOIR 基本語法

以下是 NOIR 的基本語法示例:

// Basic arithmetic circuit
fn main(private_field a: Field, private_field b: Field) -> pub Field {
    // Return a * b as public output
    a * b
}

// Range proof example
fn range_check(value: Field, bits: u32) {
    assert(value < 2 ^ bits);
}

// Conditional logic
fn conditional_add(a: Field, b: Field, condition: Field) -> Field {
    let result = a + b;
    if condition == 1 {
        result * 2
    } else {
        result
    }
}

5.3 從 Circom 到 NOIR 的遷移

對於有 Circom 開發經驗的開發者,以下是一些遷移到 NOIR 的要點:

編譯命令:nargo check 用於檢查代碼,nargo compile 用於編譯電路。

標準庫:NOIR 的標準庫與 Rust 類似,提供 Vec、HashMap 等容器類型,以及 sha256、pedersen 等密碼學函數。

調試:NOIR 提供 assert 語句用於約束驗證,以及 println 用於調試輸出。

第六章:Halo2 開發指南

6.1 Halo2 的技術特點

Halo2 是由 Zcash Foundation 開發的零知識證明系統,它是 Groth16 的後續版本,解決了後者的一些根本性限制。

Halo2 的主要技術創新包括:

通用可信設置:不同於 Groth16 每個電路都需要專門的信任設置,Halo2 只需要一個通用的結構化參考字符串(structured reference string),可以重複用於任意電路。

遞歸證明:Halo2 原生支持遞歸證明——一個電路的證明可以被用作另一個電路的輸入。這打開了許多新應用場景的大門,如聚合驗證和分層電路。

開發者友好:Halo2 的 API 設計考慮了開發者體驗,提供了更高層次的抽象。

6.2 Halo2 電路開發示例

以下是 Halo2 電路開發的基本框架:

use halo2_proofs::{
    circuit::{Layouter, SimpleFloorplan, Region},
    plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Fixed, Instance, Selector},
    poly::Rotation,
    dev::MockProver,
};
use halo2curves::pasta::Fp;
use std::marker::PhantomData;

// 定義電路配置
#[derive(Clone, Copy)]
struct MyCircuitConfig {
    advice: [Column<Advice>; 2],
    instance: Column<Instance>,
    selector: Selector,
}

// 實現電路
struct MyCircuit {
    a: Option<Fp>,
    b: Option<Fp>,
}

impl Circuit<Fp> for MyCircuit {
    type Config = MyCircuitConfig;
    type FloorPlanning = SimpleFloorplan;
    
    fn without_witnesses(&self) -> Self {
        Self { a: None, b: None }
    }
    
    fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
        let advice = [meta.advice_column(), meta.advice_column()];
        let instance = meta.instance_column();
        let selector = meta.selector();
        
        // 添加約束
        meta.create_gate("mul", |meta| {
            let a = meta.query_advice(advice[0], Rotation::cur());
            let b = meta.query_advice(advice[1], Rotation::cur());
            let q = meta.query_selector(selector);
            let c = meta.query_instance(instance, Rotation::cur());
            
            vec![q * (a * b - c)]
        });
        
        Self::Config { advice, instance, selector }
    }
    
    fn synthesize(
        &self,
        config: Self::Config,
        mut layouter: impl Layouter<Fp>
    ) -> Result<(), Error> {
        layouter.assign_region(
            || "mul region",
            |mut region: Region<'_, Fp>| {
                config.selector.enable(&mut region, 0)?;
                
                region.assign_advice(|| "a", config.advice[0], 0, || self.a.ok_or(Error::Synthesis))?;
                region.assign_advice(|| "b", config.advice[1], 0, || self.b.ok_or(Error::Synthesis))?;
                region.assign_instance(|| "c", config.instance, 0, || self.a.ok_or(Error::Synthesis).and_then(|a| self.b.ok_or(Error::Synthesis).map(|b| a * b)))?;
                
                Ok(())
            },
        )
    }
}

// 使用 MockProver 進行本地驗證
fn test_circuit() {
    let k = 4; // 2^k = 16 行
    let a = Fp::from(3);
    let b = Fp::from(5);
    let c = a * b;
    
    let circuit = MyCircuit { a: Some(a), b: Some(b) };
    let prover = MockProver::run(k, &circuit, vec![vec![c]]).unwrap();
    prover.assert_satisfied();
}

結論

零知識電路開發是以太坊隱私技術的核心技能。通過本文的學習讀者應當掌握了:

零知識技術領域發展迅速讀者應當持續關注以下前沿方向:zkEVM 的發展將使得在 EVM 環境中原生支持 ZK 驗證成為可能;遞歸證明技術將使得聚合多個證明到單一驗證交易中;硬體加速將顯著降低 ZK 證明的生成時間。

參考文獻

  1. Gennaro, R., Gentry, C., Parno, B., & Raykova, M. (2013). "Quadratic Span Programs and Succinct NIZKs without PCPs." EUROCRYPT 2013.
  2. Groth, J. (2016). "On the Size of Pairing-based Non-interactive Arguments." EUROCRYPT 2016.
  3. Buterin, V. (2022). "Challenges in Blockchain Privacy." Ethereum Research.
  4. Aztec Network. (2023). "Aztec 2.0: A Private Rollup on Ethereum." Technical Documentation.
  5. Zcash Foundation. (2022). "Halo 2: A Zero-Knowledge Proof Library." GitHub Repository.
  6. Wackerow, P. (2023). "Zero-Knowledge Proofs: Starter Guide." ethereum.org.
  7. Circom Team. (2023). "Circom Documentation." Official Documentation.
  8. StarkWare. (2022). "STARKs: Scalable, Transparent Arguments of Knowledge." StarkWare Blog.
  9. Euclid Labs. (2023). "ZKProof Community Reference." ZKProof Standardization Effort.
  10. Maller, Bowe, Kohlweiss, & Meiklejohn. (2019). "Sonic: Small Layered Constructions for Succinct Non-Interactive Arguments." IACR Crypto.
  11. Ariel Gabizon, Zachary J. Williamson, & Oana Ciobotaru. (2019). "PLONK: Permutations over Lagrange-bases for Oecumenical Noninteractive Arguments of Knowledge." IACR ePrint.

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。

目前尚無評論,成為第一個發表評論的人吧!