第九章:高级密码学

学习目标

  • 理解零知识证明的原理和应用
  • 掌握多方安全计算的基本概念
  • 学习同态加密和门限密码学
  • 了解可验证随机函数(VRF)
  • 探索密码学在区块链隐私保护中的应用

本章关键词:零知识证明、zk-SNARK、zk-STARK、多方计算、同态加密、门限签名、VRF、隐私保护


9.1 零知识证明 (Zero-Knowledge Proof)

什么是零知识证明?

零知识证明 (ZKP) 允许证明者向验证者证明某个陈述是真的,而不透露任何额外信息

经典例子:阿里巴巴洞穴

零知识证明经典例子:阿里巴巴洞穴 证明者知道密码,但不透露密码内容 入口 路径 A 路径 B 🔒 魔法门(需要密码) P 证明者 (Prover) V 验证者 (Verifier) 🔄 协议流程: 1️⃣ P 进入洞穴,V 在入口等待 2️⃣ P 随机选择路径 A 或 B 进入 3️⃣ V 随机要求 P 从路径 A 或 B 出来 4️⃣ 如果 P 知道密码,总能从指定路径出来 5️⃣ 如果 P 不知道密码,只有 50% 概率成功 6️⃣ 重复 n 次,作弊概率降至 (1/2)^n ✅ 零知识性质: 完备性:知道密码的人总能证明 可靠性:不知道密码的人无法伪造 零知识:V 不知道密码是什么 V 只知道:P 确实知道密码 V 不知道:密码具体是什么 V 无法向他人证明:没有学到任何信息 💡 区块链应用:证明交易有效(余额足够、签名正确)但不透露具体余额、接收者等隐私信息

零知识证明的三个性质

  1. 完备性 (Completeness):

    • 如果陈述为真,诚实的证明者总能说服验证者
    • $P(\text{Verifier accepts} | \text{Statement is true}) = 1$
  2. 可靠性 (Soundness):

    • 如果陈述为假,作弊的证明者无法说服验证者(除了可忽略的概率)
    • $P(\text{Verifier accepts} | \text{Statement is false}) \approx 0$
  3. 零知识 (Zero-Knowledge):

    • 验证者除了"陈述为真"之外,不学到任何额外信息
    • 验证过程可被模拟,无法向他人转述证明

9.2 zk-SNARK 与 zk-STARK

zk-SNARK (零知识简洁非交互式知识论证)

zk-SNARK: Zero-Knowledge Succinct Non-Interactive Argument of Knowledge

zk-SNARK vs zk-STARK 对比 两种主流零知识证明系统 zk-SNARK Succinct Non-interactive ARgument of Knowledge 🔧 可信设置 (Trusted Setup) • 需要 CRS (Common Reference String) • 生成证明密钥 (pk) 和验证密钥 (vk) • 必须销毁"有毒废料" (toxic waste) • 风险:如果泄露可伪造证明 ✅ 优势 • 证明尺寸小:~200 字节 • 验证速度快:~5-10 毫秒 • Gas 成本低:以太坊上 ~240k gas • 技术成熟:Zcash、Tornado Cash • 支持通用计算 ⚠️ 劣势 • 需要可信设置(每个电路独立) • 不抗量子攻击(基于椭圆曲线) • 设置泄露风险 • 证明生成慢:几秒到几分钟 • Groth16: 最快但每电路需新设置 zk-STARK Scalable Transparent ARgument of Knowledge 🔓 无需可信设置 (Transparent) • 使用公开随机性 • 基于哈希函数(如 Rescue) • 无"有毒废料"风险 • 更去中心化和安全 ✅ 优势 • 无需可信设置 • 抗量子攻击(基于哈希) • 证明生成快:高度并行化 • 可扩展性好:处理大计算 • 项目:StarkNet、StarkEx ⚠️ 劣势 • 证明尺寸大:~100-200 KB • 验证时间长:~50-100 毫秒 • Gas 成本高:以太坊上 ~1-5M gas • 技术较新,生态发展中 • 链上验证成本昂贵 📊 zk-SNARK 应用:Zcash, Tornado Cash, Polygon zkEVM 📊 zk-STARK 应用:StarkNet, StarkEx (dYdX, Sorare)

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) 示例:百万富翁问题 Alice 和 Bob 想知道谁更富有,但不想透露各自的财富值 👨 Alice 财富:$2M 🔒 私密输入 👩 Bob 财富:$3M 🔒 私密输入 MPC 协议 安全计算函数: f(x₁, x₂) = (x₁ > x₂) 输出:Bob 更富有 🔄 MPC 协议步骤 1️⃣ Alice 将财富 $2M 秘密分享成多个份额:s₁, s₂, s₃ 2️⃣ Bob 将财富 $3M 秘密分享成多个份额:t₁, t₂, t₃ 3️⃣ 双方交换部分份额,共同计算比较电路 ✅ Alice 学到: • Bob 更富有 ✓ • 不知道 Bob 有多少钱 ✓ • 不知道差距是多少 ✓ 仅知道计算结果,不知道对方输入 ✅ Bob 学到: • Bob 更富有 ✓ • 不知道 Alice 有多少钱 ✓ • 不知道差距是多少 ✓ 双方获得相同结果,但隐私受保护

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
// 3-of-5 门限签名
// 5 个参与方共享私钥,任意 3 方可生成签名

// 密钥生成阶段
KeyGen(n=5, t=3) → (pk, sk_shares[5])
// 每方持有 sk_shares[i],无人知道完整 sk

// 签名阶段(3 方参与)
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
// Secret Network 使用 MPC + TEE
// 在加密状态下执行智能合约

contract PrivateAuction {
// 密封竞价:所有人提交加密的竞价
function submitBid(bytes encryptedBid) public {
// 存储加密竞价,无人知道具体金额
}

// MPC 计算最高竞价,不泄露其他竞价
function revealWinner() public {
// 使用 MPC 协议找出最高竞价者
// 只公开获胜者和价格,其他竞价保密
}
}

9.4 同态加密 (Homomorphic Encryption)

什么是同态加密?

同态加密允许在加密数据上直接进行计算,解密后得到正确结果。

同态加密 (Homomorphic Encryption) 工作原理 在加密数据上计算,解密后得到正确结果 🔢 明文数据 a = 5 b = 3 客户端持有 Encrypt(pk) 🔒 密文数据 E(5) = 0x7a3f... E(3) = 0x9b2c... 发送到服务器 ⚙️ 密文计算 E(5) ⊕ E(3) = E(5 + 3) 服务器不知道明文 返回密文结果 🔓 解密结果 Decrypt(sk, E(8)) = 8 ✓ 客户端解密验证 同态性质 加法同态 E(a) ⊕ E(b) = E(a + b) 乘法同态 E(a) ⊗ E(b) = E(a × b) 全同态 (FHE): 支持任意计算电路 f(E(a), E(b)) = E(f(a, b)) 算法:Paillier (加法), RSA (乘法), CKKS, TFHE (全同态) 🌐 区块链应用场景 隐私投票:加密选票,同态计数,公开结果 私密竞价:加密竞价,同态比较,找出最高价

同态加密类型

类型 支持操作 代表算法 性能
部分同态 仅加法 或 仅乘法 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
// fhEVM: 同态加密 EVM
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);
// cmux: 同态条件选择
}

return winner; // 只公开获胜者
}
}

9.5 门限密码学与 VRF

门限签名 (Threshold Signature)

t-of-n 门限签名:n 个参与方共享私钥,任意 t 个参与方可生成有效签名。

门限签名 (Threshold Signature) - 3-of-5 示例 5 个参与方共享私钥,任意 3 方可生成签名 阶段 1️⃣:分布式密钥生成 (DKG) P₁ P₂ P₃ P₄ P₅ sk_share₁ sk_share₂ sk_share₃ sk_share₄ sk_share₅ 公钥 pk(所有人共享同一个公钥) 阶段 2️⃣:门限签名生成(3 方参与:P₁, P₃, P₅) P₁ ✓ 参与 P₂ ✗ 离线 P₃ ✓ 参与 P₄ ✗ 拒绝 P₅ ✓ 参与 🔏 最终签名 σ = Sign(msg, {sk₁, sk₃, sk₅}) 💡 关键特性:无需重构完整私钥 sk,参与方协作生成签名份额,聚合后得到有效签名

ECDSA 门限签名(最流行):

  • 用于比特币、以太坊等 ECDSA 链
  • 算法:GG20, CGGMP21
  • 应用:Fireblocks, ZenGo, Coinbase Prime

BLS 门限签名

  • 签名可聚合:多个签名合并为一个
  • 用于以太坊 2.0 验证者
  • 算法:基于配对的 BLS 签名

可验证随机函数 (VRF)

VRF (Verifiable Random Function) 生成可验证的伪随机数。

性质

  1. 伪随机性:输出看起来随机
  2. 唯一性:对于给定输入和密钥,输出唯一
  3. 可验证性:任何人可验证输出正确性

工作流程

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);
}

// Chainlink VRF 回调
function fulfillRandomness(bytes32 requestId, uint256 randomness)
internal override
{
uint256 diceRoll = (randomness % 6) + 1; // 1-6
// 使用骰子结果...
}
}

应用场景

  • 随机抽奖:NFT Mint、空投白名单
  • 游戏:掷骰子、抽卡
  • 共识:随机选择验证者(Algorand)

9.6 隐私保护技术对比

区块链隐私保护技术对比 各种密码学技术的特点、性能与应用场景 技术 隐私保护 性能 证明大小 典型应用 zk-SNARK (Groth16) 完全隐藏 零知识 验证快 ⚡⚡⚡ ~5-10 ms 证明慢 ⏱️⏱️ 极小 ~200 bytes Zcash, Tornado Polygon zkEVM zkSync, Aztec zk-STARK 完全隐藏 零知识 验证中 ⚡⚡ ~50-100 ms 证明快 ⏱️ ~100-200 KB StarkNet StarkEx (dYdX) Mina Protocol MPC (门限签名) 输入隐藏 协作计算 中 ⚡⚡ 需多轮交互 签名 ~64 bytes Fireblocks, ZenGo 多签钱包 托管服务 同态加密 (FHE) 完全隐藏 密文计算 慢 ⚡ 1000-10000x 极大 膨胀 100-1000x Zama (fhEVM) Secret Network 隐私投票 VRF (可验证随机) 不可预测 随机性保证 快 ⚡⚡⚡ ~1-5 ms ~200 bytes Chainlink VRF Algorand 随机抽奖、游戏 混币器 (Mixer) 去关联 地址匿名 快 ⚡⚡⚡ 链上操作 标准交易 ~200 bytes Tornado Cash Railgun 隐私转账 技术选择建议 隐私转账:zk-SNARK (Tornado Cash 模式) - 小证明、低成本 扩容 + 隐私:zk-STARK (StarkNet) - 无需可信设置、抗量子 密钥管理:MPC 门限签名 - 去中心化托管、无单点故障 密文计算:同态加密 - 隐私投票、竞价(性能慢但完全隐私)

0%