零知识证明与 ZK Rollups 详解 🔐
1. 零知识证明基础
1.1 什么是零知识证明?
零知识证明(ZKP)允许证明者向验证者证明一个陈述的真实性,而无需透露除了该陈述是真实的这一事实之外的任何信息。
1.2 核心特性
- 完整性:真实陈述总能被证明
- 可靠性:虚假陈述无法被证明
- 零知识:除了陈述的真实性外不泄露其他信息
2. ZK-SNARK 实现
2.1 电路构建
pragma circom 2.0.0;
template Multiplier() {
// 声明信号
signal input a;
signal input b;
signal output c;
// 约束
c <== a * b;
}
component main = Multiplier();
2.2 证明生成
const snarkjs = require("snarkjs");
async function generateProof(input, circuitPath, provingKeyPath) {
// 生成证明
const { proof, publicSignals } = await snarkjs.groth16.fullProve(
input,
circuitPath,
provingKeyPath
);
// 转换为可验证格式
const calldata = await snarkjs.groth16.exportSolidityCallData(
proof,
publicSignals
);
return {
proof,
publicSignals,
calldata
};
}
3. ZK Rollup 实现
3.1 智能合约
contract ZKRollup {
struct Transaction {
address from;
address to;
uint256 amount;
uint256 nonce;
}
struct Batch {
bytes32 oldStateRoot;
bytes32 newStateRoot;
Transaction[] transactions;
bytes32 withdrawalRoot;
}
mapping(bytes32 => bool) public processedBatches;
bytes32 public currentStateRoot;
function verifyAndApplyBatch(
Batch calldata batch,
bytes calldata proof
) external {
require(
batch.oldStateRoot == currentStateRoot,
"Invalid old state root"
);
// 验证零知识证明
require(
verifyProof(
proof,
batch.oldStateRoot,
batch.newStateRoot,
batch.withdrawalRoot
),
"Invalid proof"
);
// 更新状态
currentStateRoot = batch.newStateRoot;
emit BatchProcessed(batch.newStateRoot);
}
}
3.2 状态管理
contract StateManager {
struct Account {
uint256 balance;
uint256 nonce;
mapping(bytes32 => bool) withdrawals;
}
mapping(address => Account) public accounts;
function updateState(
address[] calldata addresses,
uint256[] calldata balances,
uint256[] calldata nonces
) internal {
require(
addresses.length == balances.length &&
balances.length == nonces.length,
"Length mismatch"
);
for (uint i = 0; i < addresses.length; i++) {
accounts[addresses[i]].balance = balances[i];
accounts[addresses[i]].nonce = nonces[i];
}
}
}
4. 电路设计
4.1 基础电路组件
pragma circom 2.0.0;
template MerkleTreeVerifier(levels) {
signal input leaf;
signal input path_elements[levels];
signal input path_indices[levels];
signal output root;
component hashers[levels];
signal intermediate[levels + 1];
intermediate[0] <== leaf;
for (var i = 0; i < levels; i++) {
hashers[i] = HashLeft();
hashers[i].left <== intermediate[i];
hashers[i].right <== path_elements[i];
intermediate[i + 1] <== hashers[i].hash;
}
root <== intermediate[levels];
}
4.2 交易验证电路
template TransactionVerifier() {
// 公开输入
signal input oldStateRoot;
signal input newStateRoot;
// 私有输入
signal input sender;
signal input recipient;
signal input amount;
signal input nonce;
signal input signature;
// 验证签名
component sigVerifier = SignatureVerifier();
sigVerifier.message <== hash(sender, recipient, amount, nonce);
sigVerifier.signature <== signature;
sigVerifier.pubkey <== sender;
// 验证状态转换
component stateUpdater = StateUpdater();
stateUpdater.oldRoot <== oldStateRoot;
stateUpdater.sender <== sender;
stateUpdater.amount <== amount;
stateUpdater.newRoot === newStateRoot;
}
5. 优化技术
5.1 批量处理优化
contract BatchOptimizer {
struct ProofBatch {
bytes32[] oldStateRoots;
bytes32[] newStateRoots;
bytes[] proofs;
}
function processBatchProofs(ProofBatch calldata batch) external {
uint256 batchSize = batch.proofs.length;
require(
batchSize == batch.oldStateRoots.length &&
batchSize == batch.newStateRoots.length,
"Batch size mismatch"
);
for (uint i = 0; i < batchSize; i++) {
require(
verifyProof(
batch.proofs[i],
batch.oldStateRoots[i],
batch.newStateRoots[i]
),
"Invalid proof in batch"
);
}
// 批量更新状态
updateStateBatch(batch.newStateRoots);
}
}
5.2 电路优化
template OptimizedHasher() {
signal input left;
signal input right;
signal output hash;
// 使用预编译的哈希函数
hash <== PoseidonHash(left, right);
}
template OptimizedVerifier() {
// 减少约束数量
signal input data;
signal output valid;
component hasher = OptimizedHasher();
hasher.left <== data;
hasher.right <== 0;
valid <== hasher.hash;
}
6. 安全考虑
6.1 可信设置
async function performTrustedSetup(circuit) {
// 生成证明密钥和验证密钥
const { provingKey, verifyingKey } = await snarkjs.zKey.newZKey(
circuit,
"pot12_final.ptau",
"circuit_final.zkey"
);
// 验证设置
const verified = await snarkjs.zKey.verifyFromInit(
"circuit_final.zkey",
"pot12_final.ptau",
"verification_key.json"
);
if (!verified) {
throw new Error("Trusted setup verification failed");
}
return { provingKey, verifyingKey };
}
6.2 电路验证
async function verifyCircuit(circuit) {
// 检查电路完整性
const constraints = await snarkjs.r1cs.info(circuit);
// 验证约束系统
const verification = await snarkjs.r1cs.verify(
circuit,
"verification_key.json"
);
return {
constraintCount: constraints.nConstraints,
isValid: verification
};
}
7. 性能监控
7.1 证明生成性能
class ProofPerformanceMonitor {
constructor() {
this.metrics = new Map();
}
async measureProofGeneration(input, circuit) {
const startTime = process.hrtime();
try {
const proof = await generateProof(input, circuit);
const [seconds, nanoseconds] = process.hrtime(startTime);
this.metrics.set('proofTime', seconds + nanoseconds / 1e9);
this.metrics.set('proofSize', JSON.stringify(proof).length);
return proof;
} catch (error) {
this.metrics.set('error', error.message);
throw error;
}
}
getMetrics() {
return Object.fromEntries(this.metrics);
}
}
7.2 验证性能
async function benchmarkVerification(proof, verifyingKey) {
const samples = 100;
const times = [];
for (let i = 0; i < samples; i++) {
const start = performance.now();
await snarkjs.groth16.verify(verifyingKey, proof);
times.push(performance.now() - start);
}
return {
averageTime: times.reduce((a, b) => a + b) / samples,
minTime: Math.min(...times),
maxTime: Math.max(...times)
};
}