学习目标:
- 理解零知识证明的原理和应用
- 掌握多方安全计算的基本概念
- 学习同态加密和门限密码学
- 了解可验证随机函数(VRF)
- 探索密码学在区块链隐私保护中的应用
本章关键词:零知识证明、zk-SNARK、zk-STARK、多方计算、同态加密、门限签名、VRF、隐私保护
9.1 零知识证明 (Zero-Knowledge Proof)
什么是零知识证明?
零知识证明 (ZKP) 允许证明者向验证者证明某个陈述是真的,而不透露任何额外信息。
经典例子:阿里巴巴洞穴
零知识证明的三个性质:
-
完备性 (Completeness):
- 如果陈述为真,诚实的证明者总能说服验证者
- $P(\text{Verifier accepts} | \text{Statement is true}) = 1$
-
可靠性 (Soundness):
- 如果陈述为假,作弊的证明者无法说服验证者(除了可忽略的概率)
- $P(\text{Verifier accepts} | \text{Statement is false}) \approx 0$
-
零知识 (Zero-Knowledge):
- 验证者除了"陈述为真"之外,不学到任何额外信息
- 验证过程可被模拟,无法向他人转述证明
9.2 zk-SNARK 与 zk-STARK
zk-SNARK (零知识简洁非交互式知识论证)
zk-SNARK: Zero-Knowledge Succinct Non-Interactive Argument of Knowledge
zk-SNARK 工作流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 步骤 1️⃣:可信设置 (Setup) 电路 C → Setup(C) → (pk, vk) - pk: 证明密钥 (proving key) - vk: 验证密钥 (verification key) - 销毁随机数 τ (toxic waste)
步骤 2️⃣:生成证明 (Prove) 证明者 P: - 输入:公开输入 x, 私密见证 w, pk - 计算:π = Prove(pk, x, w) - 输出:证明 π (~200 bytes)
步骤 3️⃣:验证证明 (Verify) 验证者 V: - 输入:公开输入 x, 证明 π, vk - 计算:Verify(vk, x, π) → {accept, reject} - 时间:~5-10 ms
|
Groth16 算法(最流行的 zk-SNARK):
$$
\begin{aligned}
&\text{证明包含 3 个群元素:} \
&\pi = (A, B, C) \in \mathbb{G}_1 \times \mathbb{G}_2 \times \mathbb{G}_1 \
\
&\text{验证等式:} \
&e(A, B) = e(\alpha, \beta) \cdot e(L, \gamma) \cdot e(C, \delta)
\end{aligned}
$$
其中 $e$ 是双线性配对函数。
应用案例
1. Zcash (隐私货币):
1 2 3 4 5 6 7 8 9 10 11 12 13
|
proof = GenerateProof({ public_input: nullifier, private_witness: { value: 100, sender_key: sk, receiver_addr: addr } });
VerifyProof(proof) → true/false
|
2. Tornado Cash (隐私混币):
- 用户存款时生成秘密 (secret + nullifier)
- 存款哈希 commitment = Hash(secret, nullifier) 记录到链上
- 提款时提供 ZK 证明:知道某个 commitment 的原像
- 无法关联存款和提款地址
3. zkSync Era (Layer 2 扩容):
- 将数千笔交易打包到一个区块
- 生成单个 zk-SNARK 证明
- 以太坊只需验证一个证明 → 节省 Gas
9.3 多方安全计算 (MPC)
MPC 基本概念
多方安全计算 (Secure Multi-Party Computation) 允许多方在不泄露各自私密输入的情况下,共同计算一个函数。
MPC 核心技术
1. 秘密分享 (Secret Sharing):
Shamir 秘密分享方案:
- 将秘密 $s$ 分割成 $n$ 个份额
- 任意 $t$ 个份额可恢复秘密
- 少于 $t$ 个份额无法获得任何信息
$$
\begin{aligned}
&\text{多项式构造:} \
&f(x) = s + a_1 x + a_2 x^2 + \cdots + a_{t-1} x^{t-1} \
&\text{份额:} s_i = f(i) \quad (i = 1, 2, \ldots, n)
\end{aligned}
$$
2. 混淆电路 (Garbled Circuits - Yao’s Protocol):
- 将计算表示为布尔电路
- 加密每个逻辑门的真值表
- 一方生成电路,另一方执行
- 执行过程中不知道中间值含义
3. 不经意传输 (Oblivious Transfer, OT):
1 2 3 4 5 6 7 8
| 1-out-of-2 OT 协议: 发送者:持有两个消息 (m₀, m₁) 接收者:想获取 m_b,不让发送者知道 b
结果: - 接收者获得 m_b - 发送者不知道 b 的值 - 接收者不知道 m_{1-b}
|
区块链中的 MPC 应用
1. 门限签名 (Threshold Signature):
多方协作生成签名,无需重构私钥。
1 2 3 4 5 6 7 8 9 10 11 12
|
KeyGen(n=5, t=3) → (pk, sk_shares[5])
MPC_Sign(msg, {sk_shares[1], sk_shares[3], sk_shares[5]}) → signature
Verify(pk, msg, signature) → true
|
应用案例:
- 钱包安全:ZenGo、Fireblocks(2-of-2 或 2-of-3 MPC 钱包)
- 托管服务:交易所热钱包,多方共管资产
- 去中心化验证者:以太坊验证者密钥分布式管理
2. 链上隐私计算:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
contract PrivateAuction { function submitBid(bytes encryptedBid) public { }
function revealWinner() public { } }
|
9.4 同态加密 (Homomorphic Encryption)
什么是同态加密?
同态加密允许在加密数据上直接进行计算,解密后得到正确结果。
同态加密类型
| 类型 |
支持操作 |
代表算法 |
性能 |
| 部分同态 |
仅加法 或 仅乘法 |
Paillier (加法), RSA (乘法) |
快 ⚡⚡⚡ |
| 层次同态 (LHE) |
有限次数的加法和乘法 |
BGV, BFV |
中 ⚡⚡ |
| 全同态 (FHE) |
任意电路(无限次加法和乘法) |
CKKS, TFHE, FHEW |
慢 ⚡ |
全同态加密的挑战:
- 性能开销大:计算速度慢 1000-1000000 倍
- 密文膨胀:加密后数据变大(如 1KB → 1MB)
- 噪声累积:每次运算增加噪声,需 bootstrapping 清理
区块链应用
Zama (TFHE-based) - 支持智能合约全同态加密计算:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import "fhevm/lib/TFHE.sol";
contract PrivateAuction { mapping(address => euint32) encryptedBids;
function submitBid(bytes calldata encryptedBid) public { encryptedBids[msg.sender] = TFHE.asEuint32(encryptedBid); }
function findWinner() public view returns (address) { euint32 maxBid = TFHE.asEuint32(0); address winner;
for (address bidder : bidders) { euint32 bid = encryptedBids[bidder]; ebool isGreater = TFHE.gt(bid, maxBid); maxBid = TFHE.cmux(isGreater, bid, maxBid); }
return winner; } }
|
9.5 门限密码学与 VRF
门限签名 (Threshold Signature)
t-of-n 门限签名:n 个参与方共享私钥,任意 t 个参与方可生成有效签名。
ECDSA 门限签名(最流行):
- 用于比特币、以太坊等 ECDSA 链
- 算法:GG20, CGGMP21
- 应用:Fireblocks, ZenGo, Coinbase Prime
BLS 门限签名:
- 签名可聚合:多个签名合并为一个
- 用于以太坊 2.0 验证者
- 算法:基于配对的 BLS 签名
可验证随机函数 (VRF)
VRF (Verifiable Random Function) 生成可验证的伪随机数。
性质:
- 伪随机性:输出看起来随机
- 唯一性:对于给定输入和密钥,输出唯一
- 可验证性:任何人可验证输出正确性
工作流程:
1 2 3 4 5 6 7 8
| 密钥生成:(pk, sk) ← KeyGen()
随机数生成: 输入:seed (如区块高度) 输出:(randomness, proof) ← VRF_Prove(sk, seed)
验证: VRF_Verify(pk, seed, randomness, proof) → {true, false}
|
Chainlink VRF 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
contract DiceGame is VRFConsumerBase { bytes32 internal keyHash; uint256 internal fee;
function rollDice() public returns (bytes32 requestId) { require(LINK.balanceOf(address(this)) >= fee); return requestRandomness(keyHash, fee); }
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override { uint256 diceRoll = (randomness % 6) + 1; } }
|
应用场景:
- 随机抽奖:NFT Mint、空投白名单
- 游戏:掷骰子、抽卡
- 共识:随机选择验证者(Algorand)
9.6 隐私保护技术对比