零知识电路开发Skill zk-circuits

本技能专注于使用 Circom 和 Noir 语言进行零知识证明(ZKP)电路开发,用于构建隐私保护应用和 zkRollups。核心内容包括编写高效电路模板、优化约束数量、集成 ZK 友好型密码学原语(如 Poseidon、MiMC 哈希)、生成 Groth16/PLONK 证明,以及实现默克尔树成员证明等关键功能。适用于区块链隐私增强、可扩展性解决方案(Layer 2)和需要验证计算而不泄露输入数据的场景。 关键词:零知识证明,ZK 电路,Circom,Noir,zkRollup,隐私计算,密码学原语,约束优化,Groth16,PLONK,默克尔树

加密算法 1 次安装 33 次浏览 更新于 2/23/2026

name: zk-circuits description: 使用 Circom 和 Noir 语言进行零知识电路开发。支持约束优化、ZK友好型密码学原语、证明生成(Groth16、PLONK)以及默克尔树实现。 allowed-tools: Read, Grep, Write, Bash, Edit, Glob, WebFetch

ZK 电路开发技能

使用 Circom 和 Noir 进行零知识电路开发,用于隐私保护应用和 zkRollups。

能力

  • Circom 电路:编写 Circom 模板和组件
  • Noir 程序:开发 Noir ZK 应用
  • 约束优化:最小化电路约束
  • ZK 原语:使用 Poseidon、MiMC 和 Pedersen 哈希
  • 证明系统:生成 Groth16 和 PLONK 证明
  • 信号设计:设计高效的电路输入/输出
  • 默克尔树:实现成员资格和非成员资格证明
  • 见证生成:创建高效的见证计算器

Circom 开发

安装

# 安装 Circom
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
git clone https://github.com/iden3/circom.git
cd circom
cargo build --release
cargo install --path circom

# 安装 snarkjs
npm install -g snarkjs

# 验证
circom --version
snarkjs --version

基础电路

pragma circom 2.1.6;

// 简单加法电路
template Addition() {
    // 公共输入
    signal input a;
    signal input b;

    // 输出(默认为公共)
    signal output c;

    // 约束
    c <== a + b;
}

component main = Addition();

乘法器电路

pragma circom 2.1.6;

template Multiplier(n) {
    signal input in[n];
    signal output out;

    signal intermediate[n];

    intermediate[0] <== in[0];
    for (var i = 1; i < n; i++) {
        intermediate[i] <== intermediate[i-1] * in[i];
    }

    out <== intermediate[n-1];
}

component main {public [in]} = Multiplier(3);

哈希电路(Poseidon)

pragma circom 2.1.6;

include "circomlib/circuits/poseidon.circom";

template HashPreimage() {
    signal input preimage;
    signal input hash;

    component hasher = Poseidon(1);
    hasher.inputs[0] <== preimage;

    // 验证哈希
    hash === hasher.out;
}

component main {public [hash]} = HashPreimage();

默克尔树成员资格证明

pragma circom 2.1.6;

include "circomlib/circuits/poseidon.circom";
include "circomlib/circuits/mux1.circom";

template MerkleProof(levels) {
    signal input leaf;
    signal input root;
    signal input pathElements[levels];
    signal input pathIndices[levels];

    component hashers[levels];
    component mux[levels];

    signal levelHashes[levels + 1];
    levelHashes[0] <== leaf;

    for (var i = 0; i < levels; i++) {
        hashers[i] = Poseidon(2);
        mux[i] = Mux1();

        mux[i].c[0] <== levelHashes[i];
        mux[i].c[1] <== pathElements[i];
        mux[i].s <== pathIndices[i];

        hashers[i].inputs[0] <== mux[i].out;
        hashers[i].inputs[1] <== levelHashes[i] + pathElements[i] - mux[i].out;

        levelHashes[i + 1] <== hashers[i].out;
    }

    root === levelHashes[levels];
}

component main {public [root]} = MerkleProof(20);

Circom 构建流程

# 编译电路
circom circuit.circom --r1cs --wasm --sym -o build

# 生成见证
node build/circuit_js/generate_witness.js build/circuit_js/circuit.wasm input.json witness.wtns

# Powers of Tau 仪式(一次性)
snarkjs powersoftau new bn128 14 pot14_0000.ptau
snarkjs powersoftau contribute pot14_0000.ptau pot14_0001.ptau
snarkjs powersoftau prepare phase2 pot14_0001.ptau pot14_final.ptau

# 生成证明密钥(Groth16)
snarkjs groth16 setup build/circuit.r1cs pot14_final.ptau circuit_0000.zkey
snarkjs zkey contribute circuit_0000.zkey circuit_final.zkey

# 导出验证密钥
snarkjs zkey export verificationkey circuit_final.zkey verification_key.json

# 生成证明
snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json

# 验证证明
snarkjs groth16 verify verification_key.json public.json proof.json

# 生成 Solidity 验证器
snarkjs zkey export solidityverifier circuit_final.zkey Verifier.sol

Noir 开发

安装

# 安装 Noir(Nargo)
curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
noirup

# 验证
nargo --version

基础 Noir 程序

// src/main.nr
fn main(x: Field, y: pub Field) {
    assert(x != y);
}

哈希验证

use dep::std::hash::pedersen_hash;

fn main(preimage: Field, hash: pub Field) {
    let computed_hash = pedersen_hash([preimage]);
    assert(computed_hash == hash);
}

Noir 中的默克尔证明

use dep::std::hash::poseidon;
use dep::std::merkle::compute_merkle_root;

fn main(
    leaf: Field,
    index: Field,
    hash_path: [Field; 20],
    root: pub Field
) {
    let computed_root = compute_merkle_root(leaf, index, hash_path);
    assert(computed_root == root);
}

Noir 构建流程

# 创建项目
nargo new my_circuit
cd my_circuit

# 编辑 src/main.nr
# 编辑 Prover.toml 输入

# 编译
nargo compile

# 生成见证
nargo execute

# 生成证明
nargo prove

# 验证证明
nargo verify

优化技术

约束减少

// 不好:创建额外约束
template Bad() {
    signal input a;
    signal output b;
    b <== a * a * a * a; // 多个中间约束
}

// 好:单一约束
template Good() {
    signal input a;
    signal output b;
    signal a2;
    a2 <== a * a;
    b <== a2 * a2; // 更少约束
}

域算术

// 高效使用域算术
template FieldOps() {
    signal input a;
    signal input b;
    signal output c;

    // 加法是免费的(无约束)
    signal sum;
    sum <== a + b;

    // 乘法增加约束
    c <== a * b;
}

查找表

// 使用查找表进行范围检查
template RangeCheck(n) {
    signal input in;

    component bits = Num2Bits(n);
    bits.in <== in;
    // 隐式约束 in < 2^n
}

ZK 友好型原语

原语 约束数 使用场景
Poseidon ~300/哈希 通用哈希
MiMC ~700/哈希 默克尔树
Pedersen ~1000/哈希 承诺
ECDSA ~10000/签名 签名
EdDSA ~3000/签名 签名

流程集成

流程 目的
zk-circuit-development.js 电路开发
zk-snark-application.js ZK 应用构建
zk-rollup-development.js Rollup 电路
privacy-token-implementation.js 隐私协议

最佳实践

  1. 最小化约束以提高证明效率
  2. 使用 ZK 友好型哈希函数
  3. 审计电路的完备性
  4. 使用边界情况测试
  5. 尽可能使用形式化验证
  6. 清晰地记录信号流

另请参阅

  • skills/crypto-primitives/SKILL.md - 密码学原语
  • agents/zk-cryptographer/AGENT.md - ZK 专家智能体
  • Circom 文档
  • Noir 文档