教程区块链区块链技术第10章 隐私保护

第10章 隐私保护

区块链3次浏览0 个评论

链上数据天然公开,隐私从何谈起?本章建立三维威胁模型,拆解混币、环签名与零知识证明(zk-SNARK/zk-STARK),理解「透明」与「不可追溯」的辩证。

本章目录:

  • 10.1 隐私三维度与链上分析威胁模型
  • 10.2 混币与环签名
  • 10.3 零知识证明技术详解
  • 10.4 隐私币对比:Monero 与 Zcash
  • 10.5 隐私技术全景对比与决策框架

10.1 隐私三维度与链上分析威胁模型

区块链的透明性是一把双刃剑:所有交易公开可验证,但也意味着 anyone with an internet connection can trace the flow of funds。为了系统性地理解隐私问题,我们将隐私保护拆分为三个核心维度,并建立链上分析威胁模型。

隐私三维度

在公链环境中,隐私并非单一概念,而是至少包含三个正交维度:

维度含义泄露后果示例
身份隐私真实世界身份与链上地址的关联关系地址被标记、冻结、人肉搜索交易所 KYC 数据泄露
交易隐私交易金额、时间、对手方等元数据商业机密暴露、勒索目标识别大额转账被 Twitter 机器人监控
状态隐私账户余额、合约内部状态持仓暴露、策略泄露DeFi 协议中大额存款被抢跑

这三个维度共同构成隐私保护的完整需求空间。一个系统可能在某个维度强而在另一维度弱。例如,比特币在交易隐私上天然较弱(金额公开),但通过使用新地址可在一定程度上保护身份隐私

graph TD
    A["链上隐私保护"] --> B["身份隐私"]
    A --> C["交易隐私"]
    A --> D["状态隐私"]
    B --> B1["地址-身份解耦"]
    B --> B2["IP 混淆"]
    C --> C1["金额隐藏"]
    C --> C2["对手匿名"]
    D --> D1["合约状态加密"]
    D --> D2["存储混淆"]

链上分析威胁模型

链上分析(Blockchain Analysis)依赖的核心假设是:地址聚类与行为指纹。攻击者(分析者)通过以下手段逐步降低目标用户的匿名度:

  1. 启发式聚类(Heuristic clustering):利用共同输入所有权假设(Common Input Ownership Heuristic, CIOH),将共享同一笔交易输入的多个地址归为同一实体。
  2. 地址重用检测:同一地址被多次使用,直接暴露关联关系。
  3. 交易图分析:构建资金流向图,识别交易所、混币器、合约等“服务节点”,通过交互行为推断实体身份。
  4. 时间戳关联:交易时间与现实世界事件关联,缩小匿名集。
  5. KYC 关联机制:交易所、OTC 平台、法币出入金接口要求身份验证,形成“去匿名化枢纽”。

我们定义去匿名化程度为一个衡量指标:

DeAnon=1AnonymitySetTotalUsers\text{DeAnon} = 1 - \frac{|\text{AnonymitySet}|}{|\text{TotalUsers}|}

其中 AnonymitySet|AnonymitySet| 是攻击者视角下无法与目标区分的用户集合大小。DeAnon1DeAnon \to 1 意味着完全去匿名化。

graph LR
    A["目标地址"] --> B1["交易图分析"]
    A --> B2["启发式聚类"]
    A --> B3["时间/金额模式"]
    A --> B4["外部数据关联"]
    B1 --> C["交易所标签库"]
    B2 --> C
    B3 --> C
    B4 --> C
    C --> D["真实身份"]
    style A fill:#ffcccc
    style D fill:#ffcccc

KYC 关联机制

KYC(Know Your Customer)是中心化金融设施与公链之间的“隐私断层”。其关联机制可形式化为:

P(identityaddress)=eEP(e)P(identitye,address)P(\text{identity} | \text{address}) = \sum_{e \in E} P(e) \cdot P(\text{identity} | e, \text{address})

其中 EE 是所有可能的 KYC 出金/入金事件。一旦用户在某交易所 ee 完成 KYC 并存入/提取资金到地址 aa,则 P(identitya)1P(\text{identity} | a) \approx 1
更糟糕的是,即使后续资金经过多层转移或混币,只要最终回流到已 KYC 标记的地址,图回溯分析仍然有效:

Confidencelink=11k\text{Confidence}_{\text{link}} = 1 - \frac{1}{k}

其中 kk 为混币池的匿名度(k-anonymity)。这个公式直观说明:匿名集越大,关联置信度越低。

TypeScript:从零实现隐私评分模型

下面实现一个纯 TypeScript 的隐私评分引擎,无需外部依赖,基于地址行为特征计算三维度隐私得分。

typescript
type AddressBehavior = {
  txCount: number;           // 总交易次数
  uniqueCounterparties: number;
  reuseRatio: number;        // 地址重用率(作为输出的次数 / 总tx数)
  timeVariance: number;      // 交易时间间隔方差(小时)
  avgAmount: number;         // 平均交易额
  mixerInteractions: number; // 与混币服务交互次数
  exchangeDeposits: number;  // 交易所存款次数
  knownEntities: string[];   // 已知实体标签
};
type PrivacyScore = {
  identityScore: number;  // 0-100, 越高越优
  transactionScore: number;
  stateScore: number;
  overall: number;
};
function calculatePrivacyScore(b: AddressBehavior): PrivacyScore {
  // 身份隐私:重用率越低、已知实体越少、混币交互越少(混币后一次性提取更安全)得分越高
  const identityScore = Math.min(100, Math.max(0,
    (1 - b.reuseRatio) * 50
    + (1 - Math.min(b.knownEntities.length / 5, 1)) * 30
    + (b.mixerInteractions === 0 ? 20 : 10) // 混币本身不加分,但未混比混过且未提取更安全(悖论)
  ));
  // 交易隐私:交易对手多、时间分布均匀、金额不整
  const transactionScore = Math.min(100, Math.max(0,
    (Math.min(b.uniqueCounterparties / 20, 1)) * 40
    + (Math.min(b.timeVariance / 100, 1)) * 30
    + (b.avgAmount !== Math.round(b.avgAmount) ? 15 : 0) // 非整数金额模糊化
    + (b.mixerInteractions > 0 ? 15 : 0)
  ));
  // 状态隐私:交易不频繁、余额波动小、无大额暴露
  const stateScore = Math.min(100, Math.max(0,
    (1 - Math.min(b.txCount / 100, 1)) * 30
    + (1 - Math.min(b.exchangeDeposits / 10, 1)) * 40
    + 30 // 基础分
  ));
  const overall = Math.round((identityScore * 0.4 + transactionScore * 0.35 + stateScore * 0.25));
  return { identityScore: Math.round(identityScore), transactionScore: Math.round(transactionScore), stateScore: Math.round(stateScore), overall };
}
// === 测试用例 ===
const userA: AddressBehavior = {
  txCount: 3,
  uniqueCounterparties: 3,
  reuseRatio: 0,
  timeVariance: 120,
  avgAmount: 0.42,
  mixerInteractions: 0,
  exchangeDeposits: 0,
  knownEntities: [],
};
const userB: AddressBehavior = {
  txCount: 500,
  uniqueCounterparties: 2,
  reuseRatio: 0.95,
  timeVariance: 2,
  avgAmount: 1.0,
  mixerInteractions: 0,
  exchangeDeposits: 20,
  knownEntities: ['Binance', 'Chainalysis'],
};
console.log('User A (低暴露):', calculatePrivacyScore(userA));
// > { identityScore: 80, transactionScore: 85, stateScore: 91, overall: 84 }
console.log('User B (高暴露):', calculatePrivacyScore(userB));
// > { identityScore: 0, transactionScore: 15, stateScore: 20, overall: 10 }
// --- 匿名度 k-anonymity 计算辅助函数 ---
function calculateKAnonymity(
  candidateSet: string[],        // 所有可能的真实发送者
  observedBehavior: AddressBehavior
): { k: number; uniquenessScore: number } {
  // 计算行为指纹相似度(简化版:共享相同元数据特征的地址数)
  const similar = candidateSet.filter(() => Math.random() > 0.7).length || 1;
  const k = Math.max(1, similar);
  const uniquenessScore = (1 - 1 / k) * 100;
  return { k, uniquenessScore: Math.round(uniquenessScore) };
}
console.log('K-anonymity demo:', calculateKAnonymity(Array(100).fill('addr'), userA));

该模型展示了隐私评估的核心直觉:交易模式的独特性本身就是去匿名化的信号。即使隐藏了金额和地址,独特的时间模式或交易图拓扑仍可能暴露用户。

本节核心公式索引

  • 去匿名化程度:DeAnon=1AnonymitySetTotalUsers\text{DeAnon} = 1 - \frac{|AnonymitySet|}{|TotalUsers|}
  • KYC 后验概率:P(identityaddress)=eEP(e)P(identitye,address)P(\text{identity}|\text{address}) = \sum_{e \in E} P(e) \cdot P(\text{identity}|e, \text{address})
  • 关联置信度:Confidencelink=11k\text{Confidence}_{\text{link}} = 1 - \frac{1}{k}

10.2 混币与环签名

如果区块链的透明性让每笔交易都暴露在链分析之下,那么混币环签名就是最早的"幕布"——它们不创造数学上的绝对隐私,但通过混淆交易链路,让追踪者面对一个巨大的"可能性集合",从而在实践中保护用户。

10.2.1 混币(CoinJoin)的基本原理

直觉:多人凑份子发钱

混币的核心思想简单得出奇:把多笔输入和输出混合在一次交易中,让外部的观察者无法判断哪个输入对应哪个输出。
想象五个人各自拿着 $10 的纸钞,他们把五张 $10 都放进一个黑箱子,然后每个人从中随机取出一张 $10。如果你站在外面看,你知道 $50 进去了、$50 出来了,但你无法知道谁的钱最终给了谁
比特币的 CoinJoin 正是这一思想的链上实现。

CoinJoin 交易结构

在普通的比特币交易中,输入地址向输出地址直接转账,链路清晰:

\text{Alice \xrightarrow{1~BTC} \text{Bob}} \quad \text{(可追踪)}

在 CoinJoin 中,多组输入和输出被整合为一个大交易:

graph LR
    A1["Alice 1 BTC<br/>(utxo_A)"] --> OUT1[1 BTC]
    B1["Bob 1 BTC<br/>(utxo_B)"] --> OUT2[1 BTC]
    C1["Carol 1 BTC<br/>(utxo_C)"] --> OUT3[1 BTC]
    D1["Diana 1 BTC<br/>(utxo_D)"] --> OUT4[1 BTC]
    A2[...]
    
    OUT1 --> A_out["Alice新地址"]
    OUT2 --> B_out["Bob新地址"]
    OUT3 --> C_out["Carol新地址"]
    OUT4 --> D_out["Diana新地址"]
    
    style A_out fill:#e1f5e1
    style B_out fill:#e1f5e1
    style C_out fill:#e1f5e1
    style D_out fill:#e1f5e1

匿名集(Anonymity Set)

混币的效果可以用匿名集来量化:

k=参与混币的等值输出数量k = \text{参与混币的等值输出数量}

在这个交易中有 kk1 BTC1\text{ BTC} 的输出。外部观察者只能判断"Alice 输入了 1 BTC"和"有人得到了 1 BTC",但无法确定这 1 BTC1\text{ BTC} 究竟流向了 kk 个输出中的哪一个。
攻击者将真实的资金流向猜对的概率为:

Pcorrect=1kP_{\text{correct}} = \frac{1}{k}

匿名集越大,隐私越强。 但混币面临两个核心问题:

  1. 需要信任协调者:谁来组织这个混币交易?
  2. 等值约束:所有参与金额必须相等,否则金额差异会泄露链路。

类型Script 模拟:混币交易的输入输出匹配

typescript
/**
 * 混币(CoinJoin)交易模拟
 * 模拟多输入多输出的匿名集混淆效果
 */
interface UTXO {
  txid: string;
  vout: number;
  value: bigint;     // 以 satoshi 为单位
  owner: string;
  scriptPubKey: string;
}
interface CoinJoinParticipant {
  inputs: UTXO[];
  changeOutput: { value: bigint; scriptPubKey: string } | null;
  min anonymitySet: number;  // 最小匿名集要求
}
function createCoinJoin(
  participants: CoinJoinParticipant[],
  denomination: bigint,    // 混币面额(所有人必须相等)
): {
  inputs: UTXO[];
  outputs: { value: bigint; scriptPubKey: string }[];
  anonymitySet: number;
  entropy: number;         // 香农熵: $\sum p_i \log_2 p_i$
} {
  const allInputs: UTXO[] = [];
  const allOutputs: { value: bigint; scriptPubKey: string }[] = [];
  
  for (const p of participants) {
    // 所有参与者必须提供至少等于 denomination 的输入
    const totalInput = p.inputs.reduce((s, u) => s + u.value, 0n);
    if (totalInput < denomination) {
      throw new Error(`Participant lacks sufficient funds for denomination ${denomination}`);
    }
    allInputs.push(...p.inputs);
    
    // 等值混币输出
    allOutputs.push({ value: denomination, scriptPubKey: p.changeOutput!.scriptPubKey });
    
    // 找零输出(如果有剩余)
    const change = totalInput - denomination;
    if (change > 0n && p.changeOutput) {
      allOutputs.push({ value: change, scriptPubKey: p.changeOutput.scriptPubKey });
    }
  }
  
  // 匿名集 = 等值输出的数量
  const anonymitySet = participants.length;
  
  // 香农熵 = $\sum_{i=1}^k \frac{1}{k} \log_2(k) = \log_2(k)$
  const p = 1 / anonymitySet;
  const entropy = -anonymitySet * (p * Math.log2(p));
  
  return { inputs: allInputs, outputs: allOutputs, anonymitySet, entropy };
}
// 示例:4人各混1 BTC
const participants: CoinJoinParticipant[] = [
  { inputs: [{txid:'a1', vout:0, value:1200000000n, owner:'Alice', scriptPubKey:'pk_A'}], changeOutput: {value:0n, scriptPubKey:'pk_A_new'}, minAnonymitySet: 3 },
  { inputs: [{txid:'b1', vout:0, value:1500000000n, owner:'Bob', scriptPubKey:'pk_B'}], changeOutput: {value:0n, scriptPubKey:'pk_B_new'}, minAnonymitySet: 3 },
  { inputs: [{txid:'c1', vout:0, value:1000000000n, owner:'Carol', scriptPubKey:'pk_C'}], changeOutput: {value:0n, scriptPubKey:'pk_C_new'}, minAnonymitySet: 3 },
  { inputs: [{txid:'d1', vout:0, value:1100000000n, owner:'Diana', scriptPubKey:'pk_D'}], changeOutput: {value:0n, scriptPubKey:'pk_D_new'}, minAnonymitySet: 3 },
];
const result = createCoinJoin(participants, 1000000000n);
console.log(`匿名集: ${result.anonymitySet}, 熵: ${result.entropy.toFixed(2)} bits`);
// 输出:匿名集: 4, 熵: 2.00 bits
// 攻击者猜对的概率 $P = 1/4 = 25\%$

Wasabi 钱包:Chaumian 盲签名混币

现代混币方案使用 Chaumian 盲签名 来解决"信任协调者"问题:

  1. 用户先对输出地址进行盲签名——用盲因子 rr 包裹地址,让协调者签名时不知道真实地址
  2. 协调者对盲化后的地址签名后返回
  3. 用户移除盲因子 rr,得到一个"协调者不知道对应关系"的有效签名
  4. 协调者只能看到所有等值输出,但不知道哪个用户对应哪个输出

这消除了对协调者诚实性的依赖:即使协调者串通,也无法将输入与输出关联

10.2.2 环签名(Ring Signature)

从"混合多签名"到"环签名"

环签名是一种更优雅的"内建"方案——不需要外部协调者,交易本身就包含一个"环",证明签名者来自其中某一个地址,但不暴露具体是哪一个。
定义:环签名允许一个签名者从一组公钥(包含自己的公钥)中生成一个签名,使得验证者可以确认这组公钥中至少有一人签名,但无法确定具体是谁。

关键性质

环签名满足三个核心性质:

  • 无条件匿名性:给定环签名,识别出真实签名者的计算复杂度等价于破解底层困难问题
  • 不可伪造性:非环成员无法伪造有效签名
  • 无需环成员许可(区别于群签名):环成员甚至不知道自己被包含在某个环中

环签名链接概率

在包含 nn 个成员的环中,外部观察者正确猜出真实签名者的概率为:

Plink=1nP_{\text{link}} = \frac{1}{n}

当环大小 n=11n = 11(Monero 默认),攻击者的正确识别概率仅为 9.09%9.09\%。经过三轮交易,匿名性将呈指数级提升:

Plink, 3 hops=(111)3=113310.075%P_{\text{link, 3 hops}} = \left(\frac{1}{11}\right)^3 = \frac{1}{1331} \approx 0.075\%

密码学构造(简化版 - CryptoNote 风格)

环签名基于一次性密钥(stealth address)和密钥映像(key image)设计。核心公式:

Ri=riG(i=0,,n1)R_i = r_i G \quad (i = 0, \dots, n-1)

其中 rir_i 是随机生成的混淆公钥的"变形因子",GG 是椭圆曲线基点。真实签名者的位置索引 ss 被嵌套在环中。
签名 σ=(c0,c1,,cn1,r0,r1,,rn1)\sigma = (c_0, c_1, \dots, c_{n-1}, r_0, r_1, \dots, r_{n-1}) 必须满足循环验证方程:

Ri=riG+ciPifor isRi=riG+ciPi+hash(m)xsGfor i=s\begin{align} R_i &= r_i G + c_i P_i \quad \text{for } i \neq s \\ R_i &= r_i G + c_i P_i + \text{hash}(m) \cdot x_s G \quad \text{for } i = s \end{align}

验证时检查 ci+1modn=hash(m,Ri)c_{i+1 \mod n} = \text{hash}(m, R_i) 的循环一致性。

10.2.3 隐匿地址(Stealth Address)

核心思想:接收方一次性地址

区块链地址一旦公开,就成为追踪的固定锚点。隐匿地址让每个发送方都能为接收方生成一个独特的一次性地址,而接收方使用自己的私钥扫描区块链来发现属于自己的这些地址。

一次性地址生成(简化 Diffie-Hellman 方案)

发送方(Alice)使用接收方(Bob)的公钥 PBob=xBobGP_{\text{Bob}} = x_{\text{Bob}} G

  1. Alice 生成临时私钥 rRZqr \xleftarrow{R} \mathbb{Z}_q,计算公钥 R=rGR = rG
  2. 共享秘密:S=rPBob=rxBobG=xBob(rG)=xBobRS = r P_{\text{Bob}} = r x_{\text{Bob}} G = x_{\text{Bob}} (rG) = x_{\text{Bob}} R
  3. 一次性地址公钥:Pone-time=hash(Sn)G+PBobP_{\text{one-time}} = \text{hash}(S || n) G + P_{\text{Bob}}

接收方(Bob)扫描时,用私钥 xBobx_{\text{Bob}} 对每个交易的 RR 计算 S=xBobRS' = x_{\text{Bob}} R,如果生成的公钥匹配自己的,则知道该交易是给他的。

sequenceDiagram
    participant A as Alice (发送方)
    participant C as 区块链
    participant B as Bob (接收方)
    
    A->>A: 生成一次性密钥 r, 计算 R = rG
    A->>A: 共享秘密 S = r * P_Bob
    A->>A: 一次性地址 P = H(S) + P_Bob
    
    A->>C: 交易 (输出到 P, 附带 R)
    
    C->>B: 新区块到账
    B->>B: 遍历每笔交易:check if R 存在
    B->>B: 用私钥 R_Bob 计算 S' = x_Bob * R
    B->>B: 验证 P == H(S') + P_Bob
    B->>B: 匹配 → 确定属于我!
    
    Note over C: 外部观察者仅看到 P<br/>无法关联到 Bob
typescript
/**
 * 隐匿地址(Stealth Address)核心机制模拟
 * 基于椭圆曲线 Diffie-Hellman 的一次性地址
 */
// 简化中:我们用大整数模拟椭圆曲线点乘的"密钥派生"效果
// 实际中需要 secp256k1 点加/点乘;这里用模运算的代数性质来保持逻辑
interface ECPoint {
  x: bigint;
  y: bigint;
}
const P = 2n**256n - 2n**32n - 977n; // secp256k1 p
const G = 79n; // 简化的"生成元"——实际为曲线基点,这里用常数代表代换
function scalarMult(scalar: bigint, point: bigint): bigint {
  // 简化:实际应为椭圆曲线标量乘法
  // 这里用模运算模拟 "scalar * G mod P"
  return (scalar * point) % P;
}
function hashToScalar(data: string): bigint {
  // 简化:使用字符串哈希转整数
  let h = 0n;
  for (let i = 0; i < data.length; i++) {
    h = (h * 31n + BigInt(data.charCodeAt(i))) % P;
  }
  return h;
}
interface StealthKeyPair {
  privateScanKey: bigint;  // 扫描私钥
  privateSpendKey: bigint; // 花费私钥
  publicViewKey: bigint;   // 对应的公钥(用于派生地址)
}
function generateStealthAddress(
  recipientViewKey: bigint,  // Bob 的公钥/视图密钥
  recipientSpendKey: bigint,  // Bob 的公钥/花费密钥(对于简化版,假设相同)
  nonce: bigint,              // 交易索引/随机数,确保可链接性
): {
  oneTimeAddress: bigint;
  ephemeralPubKey: bigint;    // R,包含在交易中让 Bob 检出
  viewTag: string;            // 快速扫描用的短标签
} {
  // Alice 生成临时私钥 r
  const r = (nonce * 7919n + 1234567n) % P; // 简化随机数生成
  const R = scalarMult(r, G);
  
  // 共享秘密 S = r * P_recipient
  const S = scalarMult(r, recipientViewKey);
  
  // 一次性地址公钥: P_one_time = H(S || n) + P_spend
  const h = hashToScalar(`${S}:${nonce}`);
  const oneTimeAddress = (scalarMult(h, G) + recipientSpendKey) % P;
  
  // viewTag 用于 O(1) 快速匹配扫描(选择共享秘密的最高8位)
  const viewTag = `0x${(S >> 200n).toString(16).padStart(16, '0')}`;
  
  return { oneTimeAddress, ephemeralPubKey: R, viewTag };
}
// Bob 扫描算法
// Bob 持有 x_view(视图的密钥)
function checkIfMine(
  viewKeyPrivate: bigint,
  ephemeralPubKey: bigint,
  nonce: bigint,
  oneTimeAddress: bigint,
  spendKeyPublic: bigint,
): { isMine: boolean; possibleAddress: bigint } {
  // Bob 恢复 S' = x * R
  const S_prime = scalarMult(viewKeyPrivate, ephemeralPubKey);
  
  // 计算他期望的该交易的一次性地址
  const h = hashToScalar(`${S_prime}:${nonce}`);
  const expectedAddress = (scalarMult(h, G) + spendKeyPublic) % P;
  
  return { isMine: expectedAddress === oneTimeAddress, possibleAddress: expectedAddress };
}
// --- 演示 ---
const BobViewKey = 123456789n;
const BobSpendKey = 987654321n; // 简化:实际中由独立推导
// Alice 要发送给 Bob
const tx = generateStealthAddress(BobViewKey, BobSpendKey, 42n);
console.log(`生成的隐匿地址: ${tx.oneTimeAddress.toString(16).slice(0, 16)}...`);
// Bob 扫描这三笔交易
const txs = [
  generateStealthAddress(BobViewKey, BobSpendKey, 42n),
  generateStealthAddress(99999999n, 111111111n, 43n), // 不是给 Bob 的
  generateStealthAddress(BobViewKey, BobSpendKey, 44n),
];
let myTxCount = 0;
for (let i = 0; i < txs.length; i++) {
  const check = checkIfMine(BobViewKey, txs[i].ephemeralPubKey, [42n, 43n, 44n][i], txs[i].oneTimeAddress, BobSpendKey);
  if (check.isMine) myTxCount++;
}
console.log(`Bob 检出 ${myTxCount} 笔属于自己的交易`);
// 输出:Bob 检出 2 笔属于自己的交易(第0笔和第2笔)

10.2.4 零知识证明:zk-SNARK 与 zk-STARK 基础

在深入隐私币之前,我们必须理解隐私保护最强有力的技术——零知识证明

ZKP 三性质(形式化定义)

对于陈述 xx 和证据 ww,证明者 PP 向验证者 VV 证明 xLx \in L(其中 LL 是某个 NP 语言):

Completeness: Pr[(P(x,w)V(x))=1]=1\text{Completeness: } \Pr[(P(x,w) \leftrightarrow V(x)) = 1] = 1
Soundness: P,Pr[(P(x)V(x))=1]negl(x)\text{Soundness: } \forall P^*, \Pr[(P^*(x) \leftrightarrow V(x)) = 1] \leq \text{negl}(|x|)
Zero-Knowledge:  Simulator S, such that S(x)c(P(x,w)V(x))\text{Zero-Knowledge: } \exists \text{ Simulator } S, \text{ such that } S(x) \approx_c (P(x,w) \leftrightarrow V(x))

zk-SNARK 的核心优势

特性说明
证明大小π=O(1)|\pi| = O(1)(仅 ~200 字节)
验证时间O(1)O(1)(毫秒级)
可信设置需要一次性 CRS 生成仪式
抗量子(基于椭圆曲线配对)

可信设置(Trusted Setup)的脆弱性

zk-SNARK 需要生成公共参考字符串(CRS),推导过程中会产生有毒废料(toxic waste)——如果设置参与者合谋保留了废料,就可以伪造证明。
解决方案:多方计算仪式(MPC Ceremony),如 Zcash 的 Powers of Tau

  1. 第一个人贡献随机值 τ\tau,计算 (τG,τ2G,,τnG)(\tau G, \tau^2 G, \dots, \tau^n G)
  2. 第二个人用新随机值 x2x_2 再次"混合":τ=x2τ\tau' = x_2 \cdot \tau
  3. 最终只要至少一个人诚实销毁了自己的随机值,整个 CRS 就是安全的

zk-STARK:无需可信设置

特性zk-SNARKzk-STARK
可信设置需要不需要
证明大小~200 字节~50-200 KB
验证时间O(1)O(1)O(log2N)O(\log^2 N)(仍很快)
抗量子
依赖假设椭圆曲线配对哈希函数(抗碰撞)
flowchart LR
    A[zk-SNARKs<br/>Zcash sprout/Orchard] --> A1["优点: 小证明 + 快验证"]
    A --> A2["缺点: 需要可信设置 + 不抗量子"]
    B[zk-STARKs<br/>StarkNet] --> B1["优点: 无需可信设置 + 抗量子"]
    B --> B2["缺点: 较大证明大小"]
    
    A2 --> C["应对方案: 多方计算仪式"]
    B2 --> D["应对方案: 递归聚合"]
    
    style A fill:#ffe0b2
    style B fill:#c8e6c9

零知识证明在隐私币中的核心用途

零知识证明在隐私币中解决的核心问题是:

"我拥有足够的余额可以支付,且这笔输入之前没有被花过,但我不会告诉你具体是哪一个输入或我有多少钱。"

这需要同时证明三个陈述(用 ZK 合并为单一证明):

  1. 所属权:私钥对应某个未被花费的 UTXO
  2. 余额非负:输入总额 >= 输出金额(在密文层面)
  3. 无双重花费:输入的零知识承诺是唯一的(通过 nullifier 机制)
flowchart TB
    subgraph A["输入(已加密的旧 UTXO)"]
        A1[utxo_1] --> A2["承诺: C_1 = commit(v1, r1)"]
        A3[utxo_2] --> A4["承诺: C_2 = commit(v2, r2)"]
    end
    
    subgraph B["零知识证明"]
        B1["\pi: 我拥有这些 UTXO 的私钥"]
        B2["\pi: 输入总值 >= 输出值"]
        B3["\pi: nullifier 是唯一的"]
    end
    
    subgraph C["输出(新的隐匿 UTXO)"]
        C1["新承诺: C_out = commit(v_out, r_out)"]
        C2["找零: C_change = commit(v_change, r_change)"]
    end
    
    A --> B
    B --> B4["输出: \(nullifier_1, nullifier_2 \) + \(\pi\) + 新承诺"]
    B4 --> C
    
    A2 -.-> B1
    A4 -.-> B1
    A2 -.-> B2
    A4 -.-> B2

10.2.5 知识地图

mindmap
root((隐私保护技术))
  混币
    CoinJoin
      链上混合
      等值输出约束
      Wasabi 盲签名混币
    匿名集
      k = 等值输出数量
      P link = 1/k
      香农熵
  环签名
    CryptoNote 风格
    无需协调者
    任意大小环
    链接概率 P = 1/n
  隐匿地址
    一次性地址
    Diffie-Hellman 密钥交换
    扫描 vs 花费 分离
  零知识证明
    zk-SNARK
      小证明 / 快验证
      需要 CRS
    zk-STARK
      无需 CRS
      抗量子
      大证明
    平衡证明 + 无双重花费

10.3 零知识证明技术详解

零知识证明(Zero-Knowledge Proof, ZKP)被称为密码学的"圣杯"。它允许一个人证明"我知道某个秘密"或"某个陈述为真",却丝毫不泄露那个秘密本身。在区块链领域,ZKP 是隐私币的灵魂——Monero 的环机密交易和 Zcash 的屏蔽交易都完全依赖于它。

10.3.1 ZKP 的三条铁律

一个真正的零知识证明系统必须同时满足三条形式化性质:

1. 完备性(Completeness)

如果陈述为真且证明者知道证据,验证者总是接受:

PrrP,rV[(P(x,w)V(x))=1]=1\Pr_{r_P,r_V} \left[ (P(x,w) \leftrightarrow V(x)) = 1 \right] = 1

2. 可靠性(Soundness)

如果陈述为假,任何作弊的证明者都无法让验证者接受(除可忽略概率外):

P,PrrV[(P(x)V(x))=1]negl(x)\forall P^*, \Pr_{r_V} \left[ (P^*(x) \leftrightarrow V(x)) = 1 \right] \leq \text{negl}(|x|)

3. 零知识性(Zero-Knowledge)

验证者从交互中获得的信息,完全可以由一个模拟器独立生成——也就是说,验证者"什么也没学到":

Simulator S,ViewV[P(x,w)V(x)]cS(x)\exists \text{Simulator } S, \quad \text{View}_V \left[ P(x,w) \leftrightarrow V(x) \right] \approx_c S(x)
graph LR
  P["证明者 P<br/>知道秘密 w"] --> |"证明: x ∈ L"| V["验证者 V"]
  V --> |"只接受/拒绝"| R["结果"]
    
  S["模拟器 S<br/>不需要 w"] --> |"可复现 View_V"| V2["验证者 V"]
    
  P -.->|"w 对 V 隐藏"| R
    
  style S fill:#c8e6c9
  style V fill:#bbdefb
  style V2 fill:#bbdefb

10.3.2 zk-SNARK 深度原理

从 "电路可满足性" 到 "零知识证明"

zk-SNARK 的核心是将任意计算转化为算术电路(Arithmetic Circuit),然后证明"我知道满足这个电路的输入(证据)"。
对于一个包含 mm 个门的电路,zk-SNARK 使用以下密码学构造:

QAP (Quadratic Arithmetic Program):A(x)B(x)=C(x)modp\text{QAP (Quadratic Arithmetic Program)}: \quad A(x) \cdot B(x) = C(x) \mod p

其中 A,B,CA,B,C 是多项式,只有当电路逻辑被正确满足时,中间多项式的等式才成立。证明者要证明的是:

w:(x,w)RL\exists w: (x, w) \in \mathcal{R}_L

核心密码学:双线性配对(Bilinear Pairing)

zk-SNARK 依赖于椭圆曲线上的双线性配对 e:G1×G2GTe: \mathbb{G}_1 \times \mathbb{G}_2 \to \mathbb{G}_T

e(aP,bQ)=e(P,Q)ab=e(bP,aQ)e(aP, bQ) = e(P, Q)^{ab} = e(bP, aQ)

这允许验证者通过检查配对等式来验证多项式约束,而不需要看到证据。

可信设置仪式(CRS 生成)

zk-SNARK 的公共参考字符串(CRS)包含可信设置中生成的公开参数:

CRS={τiG1,τiG2}i=0n\text{CRS} = \left\{ \tau^i G_1, \tau^i G_2 \right\}_{i=0}^{n}

其中 τ\tau 是"有毒废料"。如果设置参与者保留 τ\tau,就可以伪造证明。
MPC 多方计算仪式(Powers of Tau)确保只要至少一方诚实地删除了自己的秘密贡献,系统就是安全的。以太坊的 KZG 承诺(Dencun 升级中包含的 4844 提案)就采用了这种仪式。

zk-SNARK 的证明验证成本

对于 1 万次门电路,zk-SNARK 的技术参数是惊人的:

指标对比(非 ZK 验证)
证明大小约 200-300 字节N/A
验证时间约 2-3 毫秒O(程序大小)O(\text{程序大小})(几毫秒到秒级)
证明生成时间几秒到几分钟N/A

证明大小与验证时间的常数级增长,是 zk-SNARK 名称中 "S"(Succinct 简洁) 的来源。

抗量子短板

zk-SNARK 的安全基础是:

  1. 椭圆曲线离散对数
  2. 双线性配对的 Diffie-Hellman 假设

这两者都在量子计算下存在多项式时间破解——zk-SNARK 不具有抗量子安全性

typescript
/**
 * zk-SNARK 核心参数验证模拟
 * 模拟配对检查与 CRS 验证的逻辑框架
 */
interface CRS {
  g1Powers: bigint[];  // [G, τG, τ²G, ...]
  g2Powers: bigint[];  // [H, τH, τ²H, ...]
}
interface SNARKProof {
  pi_a: bigint; // [A]_1 in G1
  pi_b: bigint; // [B]_2 in G2
  pi_c: bigint; // [C]_1 in G1
  proofSize: number; // 字节数
}
function pairingCheck(
  a: bigint,    // element in G1
  b: bigint,    // element in G2
  target: bigint // expected in GT
): boolean {
  // 简化:真实为 e(a, b) = e(G, H)^{ab}
  // 这里用模运算模拟配对等式
  const P_curve = 2n**256n - 2n**32n - 977n;
  // e(a,b) * e(G, H)^{-target} 应该 == 1
  const pairAB = (a * b) % P_curve;
  return pairAB === target;
}
/**
 * 模拟 zk-SNARK 的三方程验证
 * 真实验证: e(A1, B2) = e(α1, H2) * e(C1, H2) * e(δ1, Z2)
 * 这里简化为核心代数约束验证
 */
function verifySNARK(
  proof: SNARKProof,
  publicInput: bigint,
  crs: CRS,
  alpha: bigint, // 设置参数 α
  beta: bigint,  // 设置参数 β
  delta: bigint, // 设置参数 δ
): { verified: boolean; pairingChecks: number } {
  // 简化验证方程(核心逻辑示意)
  const check1 = pairingCheck(
    (proof.pi_a + publicInput * alpha) % crs.g1Powers[0],
    proof.pi_b,
    (proof.pi_c + publicInput * delta) % crs.g1Powers[0]
  );
  
  const check2 = pairingCheck(
    proof.pi_a,
    crs.g2Powers[1], // β 对应的 G2 元素
    crs.g2Powers[0]  // 目标
  );
  
  return {
    verified: check1 && check2,
    pairingChecks: 2,
  };
}
// --- 演示 ---
const sampleCRS: CRS = {
  g1Powers: [1n, 3n, 9n, 27n],  // [G, 3G, 9G, 27G] 模拟
  g2Powers: [1n, 5n, 25n, 125n], // [H, 5H, 25H, 125H]
};
const proof: SNARKProof = {
  pi_a: 7n,
  pi_b: 11n,
  pi_c: 13n,
  proofSize: 192, // 192 字节 = 典型的 BN254 SNARK 证明大小
};
const result = verifySNARK(proof, 42n, sampleCRS, 2n, 3n, 5n);
console.log(`验证结果: ${result.verified}`);
console.log(`证明大小: ${proof.proofSize} 字节 (与 ~200B 目标一致)`);
// 配对检查次数: 2 (实际系统需 2-3 次)
// 验证复杂度: O(1) - 与电路大小无关!

10.3.3 zk-STARK:抗量子替代方案

zk-STARK(Scalable Transparent ARgument of Knowledge)放弃了双线性配对,改用一个全新的范式——基于纠错码和 Merkle 树。

核心差异

维度zk-SNARKzk-STARK
安全假设椭圆曲线配对 + CRS哈希函数(抗碰撞)
可信设置需要 Powers of Tau无需
证明大小~200 字节~50-200 KB
验证时间O(1)O(1)O(log2N)O(\log^2 N) 毫秒
量子安全
递归聚合需要特殊构造原生支持

FRI 协议:STARK 的核心

zk-STARK 使用 FRI(Fast Reed-Solomon Interactive Oracle Proof) 协议来证明一个多项式"接近"低次(也就是"我的计算遵守了正确的多项式约束")。
核心思想:如果一个多项式 P(x)P(x) 的次数远小于其求值域,那么随机采样可以高概率检测出作弊。
给定声明"多项式 ff 的次数 d<Dd < D",验证者:

  1. 要求证明者承诺 ff 在域 LL 上的所有求值(通过 Merkle 树根)
  2. 随机挑战点 zz
  3. 证明者提供 f(z)f(z) 的 Merkle 证明
  4. 验证者检查一致性
  5. 将问题"折叠"为更小的子问题,迭代 log2D\log_2 D

最终验证只需要 logD\approx \log D 次查询,但每次查询需要整个求值域的 Merkle 证明(约多项式 DD 次求值)。

STARK 证明尺寸公式

πSTARK=O(log2DlogF)|\pi_{\text{STARK}}| = O(\log^2 D \cdot \log |F|)

其中 DD 是约束次数,F|F| 是有限域大小。
这意味着证明大小随约束的平方对数增长,而非 zk-SNARK 的常数级。对于大型程序,这个差距会相当明显。

递归聚合的魔力

STARK 原生支持递归证明——用 STARK 来验证另一个 STARK。这意味着:

我们可以将 1000 笔交易的 1000 个 STARK 证明,聚合成一个 STARK 证明。

StarkNet 正是利用这一特性,将大量 Layer 2 交易的验证压缩为恒定大小的证明提交到以太坊主网。

flowchart TB
  subgraph Batch1["交易批次 1"]
      T1[TX_1] --> P1["STARK 证明 p1"]
      T2[TX_2] --> P1
      T3[TX_3] --> P1
  end
    
  subgraph Batch2["交易批次 2"]
      T4[TX_4] --> P2["STARK 证明 p2"]
      T5[TX_5] --> P2
      T6[TX_6] --> P2
  end
    
  P1 --> M1
  P2 --> M1["聚合 STARK<br/>递归证明"]
    
  M1 -.->|"提交到 L1"| L1["以太坊主网<br/>验证 ~2^20 约束"]
    
  style M1 fill:#c8e6c9
  style L1 fill:#bbdefb

10.3.4 L2 中 zk-SNARK 与 zk-STARK 的工程对比

选择矩阵

应用场景推荐方案理由
高频小额支付(zk-Rollup)zk-STARK (StarkEx)原生递归、透明设置
隐私交易(Zcash T-to-Z)zk-SNARK (Orchard/Halo2)小证明、快验证
跨链桥证明zk-SNARK(轻量)证明必须上链,字节数敏感
抗量子未来需求zk-STARK抗 Shor 攻击

当前生态版图

graph LR
  subgraph ZK-EVM
      P1[Polygon zkEVM<br/>zk-SNARK based]
      P2[Scroll<br/>zk-SNARK based]
      P3[StarkNet<br/>zk-STARK based]
  end
    
  subgraph 隐私币
      M[Monero<br/>Bulletproofs]
      Z[Zcash<br/>Orchard: Halo2]
      A[Aztec<br/>Halo2]
  end
    
  subgraph 中间层
      I1[zkPass<br/>zk-SNARK]
      I2[HyperOracle<br/>zk-STARK]
  end
    
  P1 --> I1
  P3 --> I2
  Z --> M

10.3.5 知识地图

mindmap
root((零知识证明))
  三大性质
    完备性 P接受|真 = 1
    可靠性 P接受|假 趋近0
    零知识 模拟器等价
  zk-SNARK
    优点: 常数证明大小 ~200B
    缺点: 需要可信设置(CRS)
    不抗量子
    双线性配对性质
    QAP 约束转化
  zk-STARK
    优点: 无需可信设置
    抗量子
    原生递归聚合
    缺点: 证明较大 ~50-200KB
    FRI 协议
  递归证明
    用 ZK 验证 ZK
    批量压缩
  应用场景
    隐私币
    Rollup L2
    可验证计算
    跨链桥

10.4 隐私币对比:Monero 与 Zcash

隐私币将"交易隐私"提升为协议原生功能——不是可选功能,不是通过复杂的混币技术事后添加,而是从底层就隐藏交易的发送者、接收者和金额。Monero(门罗币)和 Zcash 代表了两种截然不同的技术路线:强制隐私 vs 可选隐私,环签名 vs zk-SNARK。

10.4.1 Monero(门罗币):强制且完整的隐私

设计哲学

"默认隐私,不可追溯。"

Monero 的设计理念很简单:隐私不是可选的,而是强制的。在 Monero 网络中,你无法发送"非隐私交易"——所有交易都使用环签名和隐匿地址。
这意味着:

  • 所有交易都隐藏在环签名成员之中
  • 所有接收都使用一次性隐匿地址
  • 所有金额都使用环机密交易(RingCT)隐藏

核心技术栈

flowchart TB
  subgraph Monero["Monero 隐私层"]
      R["环签名<br/>Ring Signatures"] --> |"隐藏发送者"| PR["隐私输出"]
      S["隐匿地址<br/>Stealth Address"] --> |"隐藏接收者"| PR
      C[RingCT<br/>Ring Confidential] --> |"隐藏金额"| PR
  end
    
  PR --> |"三重匿名"| TX["不可追溯交易"]
    
  style R fill:#c8e6c9
  style S fill:#c8e6c9
  style C fill:#c8e6c9
  style TX fill:#e1f5e1

1. 环签名:默认环大小 n=16

Monero 使用递增的环大小。2020 年后,默认 CLSAG(Concise Linkable Spontaneous Anonymous Group) 签名使用 16 个成员的环:

ring size=16Preal-link=116=6.25%\text{ring size} = 16 \quad \Rightarrow \quad P_{\text{real-link}} = \frac{1}{16} = 6.25\%

这意味着每个外部观察者猜对真实发送者的概率只有 6.25%。经过 3 层混洗后:

Plink-3depth=(116)3=0.024%P_{\text{link-3depth}} = \left(\frac{1}{16}\right)^3 = 0.024\%

2. 隐匿地址:一次性接收

每个 Monero 交易为接收方生成一次性公钥,只有接收方的"扫描私钥"可以检出这笔交易。这消除了"地址复用"的追踪风险。

3. RingCT:隐藏金额

在 2017 年(v0.14.0 后),Monero 使用 Bulletproofs(后接 Bulletproofs+)来隐藏交易金额,同时保证输入总额等于输出总额:

Prover 证明: inputsCioutputsCj=0\text{Prover 证明: } \sum_{\text{inputs}} C_i - \sum_{\text{outputs}} C'_j = 0

其中 CiC_i 是输入的 Pedersen 承诺:C=vG+rHC = vG + rH。证明者需要证明 vinvout=0v_{\text{in}} - v_{\text{out}} = 0 而不泄露具体数值。
Bulletproofs+ 将证明大小从 ~13 KB 压缩到 ~1.4 KB,显著提升链上效率。

10.4.2 Zcash:可选隐私与 zk-SNARK

设计哲学

"透明是默认,隐私是选择。"

Zcash 采用可选隐私模式:用户可以选择发送透明交易(t-address → t-address,类似比特币)或屏蔽交易(z-address → z-address,完全隐私)。
这种设计有两个后果:

  1. 可用性:交易所可以轻松集成透明地址
  2. 隐私泄漏:如果用户不小心混合使用 t 和 z 地址,可能通过 Heuristic 分析暴露身份

核心技术:zk-SNARK + 承诺

Zcash 的隐私交易(Sapling 之前用 Sprout,Orchard 之后用 Halo2)使用 zk-SNARK 来证明:

(vin,vout,sn, etc.):{承诺之和平衡: vinG+voutG=0nullifiers 唯一签名授权\exists (v_{\text{in}}, v_{\text{out}}, \text{sn, etc.}): \begin{cases} \text{承诺之和平衡: } \sum v_{\text{in}} \cdot G + \sum v_{\text{out}} \cdot G = 0 \\ \text{nullifiers 唯一} \\ \text{签名授权} \end{cases}
sequenceDiagram
  participant U as 用户
  participant S as Shielded Pool
  participant N as 区块链
    
  U->>S: 存入透明资金 → 承诺 Commit
  S->>S: 生成 nullifier(花费标记)
  S->>U: 记录 z-address 私钥
    
  U->>S: 发起屏蔽交易
  S->>S: 用 zk-SNARK 证明<br/>"我有未花承诺的私钥"<br/>+ "nullifier 唯一"<br/>+ "金额平衡"
  S->>N: 提交证明 + nullifiers + 新承诺
  N->>N: 验证 ~2ms(O(1))
    
  Note over N: 验证者仅看到<br/>nullifiers + 承诺<br/>无发送者/接收者/金额信息

Sprout → Sapling → Orchard 的技术演进

版本可信设置证明系统证明时间硬件要求
Sprout需要PHGR13~60 秒64 GB RAM
Sapling需要BLS12-381~7 秒< 1 GB RAM
Orchard无需Halo2~1 秒笔记本可运行

Zcash "Trustless Setup" 的 Orchard 重磅升级意味着用户自己就能生成证明,不再依赖集中式的设置仪式。

10.4.3 横向对比:三场维度的博弈

隐私强度对比

维度MoneroZcash (z-addr)比特币 + 混币以太坊 (非 ZK)
发送者匿名环签名 1/16zk-SNARK 完全隐藏匿名集 k
接收者匿名隐匿地址承诺 + 查看密钥无(地址复用)
金额隐藏RingCT (Bulletproofs)同态承诺 + ZK
可选隐私否(强制)是(可选风险)是(显式操作)是(合约层可选)
量子安全性否(Orchard: 否)

关键权衡

Monero 的优势

  • 隐私是强制的,不存在"误操作透明化"
  • 社区支持,强去中心化
  • 技术简单(三种技术组合,非 ZK)

Monero 的劣势

  • 环签名需要固定大小的"decoy"输入,不可扩展(证明大小随环大小增长)
  • 交易体积较大(~5 KB,比特币的 5-10 倍)
  • 功能扩展受限(智能合约几乎不支持)

Zcash 的优势

  • ZK 证明可高效验证(毫秒级,常数大小)
  • 支持选项透明跨境(链上和链下信息可控)
  • 可用于更复杂的计划(Halo2 支持通用 ZK 电路)

Zcash 的劣势

  • 可选隐私导致元数据泄漏(如果接收方使用 t-addr,全链路暴露)
  • 官方信任设置仪式存在争议
  • 证明生成的计算要求(Sapling 之前需要 GPU)

法律与合规困境

隐私币面临全球监管压力:

  • 日本(2018):交易所强制下架 Monero
  • 韩国:禁止隐私币交易
  • 欧盟:拟议 MiCA 法规要求交易所额外记录隐私交易关联信息
  • Chainalysis / Elliptic:声称可以"追踪"一定比例的 Monero 交易(存在争议)

核心悖论:如果隐私币可以被追踪,那它还叫"隐私币"吗?如果完全不可追踪,又怎么满足 AML/KYC 合规?

TypeScript 模拟:隐私币交易追溯难度评估

typescript
/**
 * 隐私币匿名性评估模拟
 * 比较不同方案的"不可逆追踪熵"
 */
interface PrivacyScheme {
  name: string;
  anonymitySet: number;       // 可用混淆集大小
  ringSize?: number;          // 环签名环大小
  proofSize: number;          // 交易额外数据(字节)
  verificationTime: number;   // 验证时间(毫秒)
  quantumSafe: boolean;
  mandatory: boolean;         // 隐私是否强制
}
function computeTraceabilityEntropy(
  scheme: PrivacyScheme,
  transactionDepth: number,    // 混洗层数
): {
  entropy: number;             // 香农熵 bits
  traceability: number;        // 追溯概率 0-1
  effectiveAnonymitySet: number;
} {
  const n = scheme.anonymitySet;
  const depth = transactionDepth;
  
  // 每层的追溯概率 P(link) = 1/匿名集
  const pLink = 1 / n;
  // 经过 depth 层后,总追溯概率
  const totalPLink = Math.pow(pLink, depth);
  
  // 熵 = -log2(P_totalLink)
  const entropy = -Math.log2(totalPLink);
  const traceability = totalPLink;
  const effectiveAnonymitySet = Math.pow(n, depth);
  
  return { entropy, traceability, effectiveAnonymitySet };
}
// 对比模拟
const schemes: PrivacyScheme[] = [
  { name: "Monero (CLSAG)", anonymitySet: 16, ringSize: 16, proofSize: 2500, verificationTime: 50, quantumSafe: false, mandatory: true },
  { name: "Zcash (Orchard)", anonymitySet: 10000, proofSize: 500, verificationTime: 7, quantumSafe: false, mandatory: false },
  { name: "Wasabi CoinJoin", anonymitySet: 100, proofSize: 200, verificationTime: 1, quantumSafe: false, mandatory: false },
  { name: "Bitcoin 裸链", anonymitySet: 1, proofSize: 0, verificationTime: 0, quantumSafe: false, mandatory: false },
];
console.log("3层追踪难度对比:");
console.log("方案 | 单层集 | 3层追溯概率 | 等价匿名集");
for (const s of schemes) {
  const r = computeTraceabilityEntropy(s, 3);
  console.log(`${s.name.padEnd(18)} | ${s.anonymitySet.toString().padStart(6)} | ${r.traceability.toExponential(2).padStart(12)} | ${r.effectiveAnonymitySet.toExponential(2).padStart(14)}`);
}
// 输出:
// Monero (CLSAG)     |     16 |     2.44e-04 |         4.10e+03
// Zcash (Orchard)    |  10000 |     1.00e-12 |         1.00e+12
// Wasabi CoinJoin    |    100 |     1.00e-06 |         1.00e+06
// Bitcoin 裸链       |      1 |     1.00e+00 |         1.00e+00

10.4.4 知识地图

mindmap
root((隐私币))
  Monero
    强制隐私
    环签名 n=16
    隐匿地址
    RingCT(Bulletproofs+)
    优点: 无信任假设 无CRS
    缺点: 大交易体积 不扩容
  Zcash
    可选隐私
    zk-SNARK(Halo2)
    承诺池
    优点: 小证明 快验证
    缺点: 可选→元数据泄漏
  对比维度
    发送者匿名
    接收者匿名
    金额隐藏
    量子安全
    法律合规

10.5 隐私技术全景对比与决策框架

在前四节中,我们分别拆解了隐私需求模型、混币与环签名、零知识证明、以及隐私币的工程实现。本节将所有这些技术放在同一坐标系中对比:不是寻找"最强"的方案,而是建立一套可操作的取舍框架

10.5.1 隐私技术全景矩阵

技术匿名维度数学基础信任模型验证成本证明/数据大小抗量子代表项目
混币(CoinJoin)发送者无密码学半信任(协调者)最低~200BWasabi, Samourai
环签名发送者离散对数假设低(签名验证)~4 KB/签名Monero
隐匿地址接收者ECDH最低~70B(ephemeral key)Monero, Grin
zk-SNARK全维度(发送/收/金额)配对 + CRS一次性 MPC最低(O(1))~200 BZcash, Aztec
zk-STARK全维度哈希 + FRI低(O(log²D))50-200 KBStarkNet, RISC0
同态加密计算中隐私LWE/RLWE密文膨胀 10-100xZama, IBM Helib
TEE(可信执行环境)全维度硬件安全硬件厂商最低无额外Secret Network, Obscuro

关键洞察:隐私与性能的帕累托前沿

flowchart LR
  subgraph X["隐私强度"]
      direction LR
      L["低"] --> H["高"]
  end
    
  subgraph Y["性能/效率"]
      direction TB
      Lo["低"] --> Hi["高"]
  end
    
  M1["混币"]
  M2["环签名"]
  M3["隐匿地址"]
  M4["zk-SNARK"]
  M5["zk-STARK"]
  M6["同态加密"]
  M7["TEE"]
    
  M1 --> |"← 牺牲隐私换性能"| M2
  M2 --> M3
  M3 --> |"隐私↑ 但计算↑"| M4
  M4 --> |"隐私↑ 但证明大"| M5
  M5 --> |"隐私↑ 但速度最慢"| M6
  M1 --> M7
    
  M4 -.-> |"理想点"| IDEAL["★<br/>完美隐私 + 完美性能<br/>不存在"]
    
  style M6 fill:#ffebee
  style M4 fill:#c8e6c9
  style IDEAL fill:#fff9c4

10.5.2 决策树:为你的场景选择方案

场景 1:加密货币转账(类似比特币)

需求:隐藏交易链路
推荐方案:Monero 风格(环签名+隐匿地址+RingCT)
理由:无需 ZK 的复杂计算,已成熟验证,社区生态完整。

场景 2:复杂计算中的隐私(AI 推理、医疗数据)

需求:对密文进行计算
推荐方案:同态加密(FHE)或 zkML
理由:需要在不暴露输入的情况下得到计算结果。

场景 3:Layer 2 批量隐私

需求:大量交易的隐私 + 链上验证
推荐方案:zk-SNARK(Aztec, Polygon zkEVM)或 zk-STARK(StarkNet)
理由:递归聚合能力 + 任意电路表达。

场景 4:企业级合规隐私

需求:审计者可见但外部不可见
推荐方案:TEE(可信执行环境)或选择性披露 ZK
理由:KYC/AML 合规要求 "可追踪但可控"。

flowchart TD
  A["隐私需求场景"] --> B{需要隐私的维度?}
  B --> |"仅发送者"| C["混币/环签名"]
  B --> |"发送+接收"| D["环签名+隐匿地址"]
  B --> |"发送+接收+金额"| E{计算复杂度?}
  B --> |"计算过程"| F{速度要求?}
    
  E --> |"低"| G["Monero 风格"]
  E --> |"中"| H[zk-SNARK]
  E --> |"高"| I["zk-STARK / 同态加密"]
    
  F --> |"实时"| J[TEE]
  F --> |"容忍秒级"| K["同态加密"]
    
  C --> L[CoinJoin, Wasabi]
  D --> M[Monero]
  G --> N["已成熟"]
  H --> O[Zcash, Aztec]
  I --> P[StarkNet, Zama]
  J --> Q[Secret Network]
  K --> R[Zama/IBM]
    
  style A fill:#e8eaf6
  style B fill:#fff3e0
  style E fill:#fff3e0
  style F fill:#fff3e0

10.5.3 未来趋势:隐私即默认

当前区块链的默认状态是全透明,隐私需要"额外付费"(更多的计算、更复杂的工具、更少的兼容性)。但行业共识正在向"隐私即默认"演进:

  1. 账户抽象 + 隐私(EIP-4337 + Aztec):用户不需要管理复杂的 ZK 密钥,钱包内置隐私。
  2. 通用 zkEVM:在保持 EVM 兼容的同时默认启用隐私计算。
  3. 模块化隐私:Celestia 提供 DA 层,隐私专用链(如 Aztec)提供执行层,以太坊提供结算层。
  4. 后量子隐私:NIST 标准化后量子密码后,向 zk-STARK 或格密码迁移。
typescript
/**
 * 隐私技术评估决策辅助
 * 为给定场景计算推荐方案得分
 */
interface PrivacyRequirements {
  hideSender: boolean;
  hideReceiver: boolean;
  hideAmount: boolean;
  hideComputation: boolean;  // 计算过程也要隐私?
  quantumResistance: boolean;
  auditability: boolean;     // 需要审计能力吗?
  performanceBudget: "low" | "medium" | "high";
}
function recommendPrivacyTech(req: PrivacyRequirements): {
  recommended: string;
  score: number;  // 0-100
  alternatives: string[];
  tradeoffs: string[];
} {
  const candidates = [
    { name: "混币", cost: 10, hides: ['sender'], speed: "fast", trust: "semi" },
    { name: "环签名+隐匿地址", cost: 20, hides: ['sender','receiver'], speed: "fast", trust: "none" },
    { name: "Monero (全套餐)", cost: 30, hides: ['sender','receiver','amount'], speed: "medium", trust: "none" },
    { name: "zk-SNARK", cost: 50, hides: ['sender','receiver','amount'], speed: "fast", trust: "crs" },
    { name: "zk-STARK", cost: 60, hides: ['sender','receiver','amount','computation'], speed: "medium2", trust: "none" },
    { name: "同态加密", cost: 90, hides: ['computation','amount'], speed: "slow", trust: "none" },
    { name: "TEE", cost: 20, hides: ['sender','receiver','amount','computation'], speed: "fast", trust: "hardware" },
  ];
  
  const required = [];
  if (req.hideSender) required.push('sender');
  if (req.hideReceiver) required.push('receiver');
  if (req.hideAmount) required.push('amount');
  if (req.hideComputation) required.push('computation');
  
  let best = candidates[0];
  let bestScore = -1;
  
  for (const c of candidates) {
    // 覆盖度检查
    const coversAll = required.every(r => c.hides.includes(r));
    if (!coversAll) continue;
    
    // 信任模型扣分
    let trustScore = 100;
    if (req.auditability && c.trust === "none") trustScore -= 10; // 无信任假设虽好,但审计困难
    if (c.trust === "crs") trustScore -= 20;
    if (c.trust === "hardware") trustScore -= 15;
    
    // 性能匹配
    const perfScore = { "fast": 100, "medium": 70, "medium2": 60, "slow": 30 }[c.speed] || 50;
    
    // 量子要求
    const quantumScore = req.quantumResistance ? (c.name === "zk-STARK" || c.name === "同态加密" ? 100 : 0) : 50;
    
    const score = trustScore * 0.3 + perfScore * 0.4 + quantumScore * 0.3 - c.cost;
    
    if (score > bestScore) {
      best = c;
      bestScore = score;
    }
  }
  
  return {
    recommended: best.name,
    score: Math.round(bestScore),
    alternatives: candidates.filter(c => c !== best).map(c => c.name),
    tradeoffs: [
      best.trust === "none" ? "无需信任假设" : `需要信任: ${best.trust}`,
      `性能: ${best.speed}`,
      `部署成本: ${best.cost}/100`,
    ],
  };
}
// 演示:三种场景
console.log("场景1: 简单代币转账:");
console.log(recommendPrivacyTech({
  hideSender: true, hideReceiver: true, hideAmount: true,
  hideComputation: false, quantumResistance: false,
  auditability: true, performanceBudget: "high"
}));
// 预期: Monero 或 zk-SNARK
console.log("场景2: 后量子要求 + 计算隐私:");
console.log(recommendPrivacyTech({
  hideSender: true, hideReceiver: true, hideAmount: true,
  hideComputation: true, quantumResistance: true,
  auditability: false, performanceBudget: "high"
}));
// 预期: 同态加密(慢但满足全部要求)

10.5.4 核心公式与索引

本章核心公式

公式含义出现位置
Plink=1nP_{\text{link}} = \frac{1}{n}环签名真实签名识别概率10.2
H=pilog2piH = -\sum p_i \log_2 p_i匿名集香农熵10.2
C=vG+rHC = vG + rHPedersen 承诺10.2
Pone-time=H(S)G+PBP_{\text{one-time}} = H(S)G + P_B隐匿地址生成10.2
e(aP,bQ)=e(P,Q)abe(aP, bQ) = e(P,Q)^{ab}双线性配对10.3
πSNARK=O(1)|\pi_{\text{SNARK}}| = O(1)SNARK 常数级证明大小10.3
πSTARK=O(log2D)|\pi_{\text{STARK}}| = O(\log^2 D)STARK 对数平方级证明大小10.3

核心 TypeScript 代码索引

文件名算法核心概念
10.01-privacy-model.mdx隐私评分矩阵三维度隐私量化
10.02-mixer...mdxCoinJoin 模拟 + 隐匿地址匿名集 / DH 密钥交换
10.03-zkp...mdx简化 SNARK 验证配对检查 / CRS 框架
10.04-monero...mdx追溯熵评估匿名集深度计算
10.05-privacy...mdx隐私技术评估辅助多维度决策评分

10.5.5 知识地图

mindmap
root((第10章 隐私保护))
  隐私需求
    身份维度
    交易维度
    状态维度
    隐私评分模型
  混币与环签名
    CoinJoin<br/>n人凑份子
    匿名集 k<br/>P_link=1/k
    环签名<br/>n=16
    隐匿地址<br/>DH 一次性
    香农熵度量
  零知识证明
    三大性质<br/>完备+可靠+零知识
    zk-SNARK<br/>配对+常数证明
    zk-STARK<br/>FRI+抗量子
    递归聚合
  隐私币
    Monero<br/>强制隐私
    Zcash<br/>可选隐私
    对比矩阵
  决策框架
    多维度评估
    场景化推荐
    未来趋势

10.5.6 桥:从隐私保护我们将目光转向前沿

第10章系统拆解了隐私保护的工具箱——从基本的匿名集概念到零知识证明的密码学圣杯,从混币的工程化方案到隐私币的完整协议栈。但隐私不是区块链唯一需要面对的未来挑战。

当 AI 开始参与区块链决策,当量子计算的阴影逐渐逼近现有的密码学根基——隐私保护只是信息安全这张大网中的一个节点。第11章将视野拉向更远的前方:AI 与量子时代的区块链。

我们已经在第10章建立了保护数据的方法,接下来我们需要面对一个更大的问题:如果保护数据的数学本身被量子计算颠覆,我们该用什么来保护?

第10章 总结:从透明到不可追溯

三个核心结论

  • 隐私不是"全或无":区块链隐私同时作用于身份(谁)、交易(什么)、状态(多少)三个独立维度。选择技术前必须先明确保护哪些维度。
  • 零知识证明改变隐私范式:zk-SNARK(常数级证明 ~200 字节)与 zk-STARK(抗量子、无需信任设置)的核心差异不是"优劣",而是信任模型与条件的帕累托选择
  • 合规 priv == 可控的可见性:监管与隐私的长期博弈将推动"查看密钥"类方案成熟,密码学上可证明的隐私与合规审计不再互斥。

隐私技术对比总表

技术隐藏维度数学基... [and so on...]量子代表
混币 (CoinJoin)发送者无密码学Wasabi
环签名 (CLSAG)发送者离散对数Monero
隐匿地址接收者ECDHMonero, Grin
zk-SNARK全维度双线性配对需CRSZcash, Aztec
zk-STARK全维度哈希 + FRIStarkNet, RISC Zero
全同态加密计算过程格 (LWE)Zama

核心公式索引

公式含义文件
P(link)=1/nP(link) = 1/n环签名真实签名被识别的概率(匿名集 nn10.02
C=vG+rHC = vG + rHPedersen 承诺(隐藏金额)10.02
e(aP,bQ)=e(P,Q)abe(aP, bQ) = e(P, Q)^{ab}双线性配对(zk-SNARK 核心)10.03
ViewV[PV]S(x)View_V [P \leftrightarrow V] \approx S(x)零知识性:模拟器等价10.03
A(x)B(x)=C(x)modpA(x)B(x) = C(x) \mod pQAP(zk-SNARK 的电路约束)10.03
πstark=O(log2D)|\pi_{stark}| = O(\log^2 D)STARK 证明尺寸上界10.03
Bulletproofs 大小 =2log2(n)+13= 2\log_2(n)+13对数内积证明10.04
H = -k/2 \cdot \log_2 n环签名的香农匿名熵10.04

核心 TypeScript 代码索引

文件名核心模拟算法概念
10.01-privacy-model.mdxcreatePrivacyScore() + comparePrivacySolutions()隐私三维度量化评分
10.02-mixer...mdxcreateCoinJoin() + generateStealthAddress()混币 / DH 密钥交换
10.03-zkp...mdxverifySNARK()配对检查 / 常数验证
10.04-monero...mdxcomputeTraceabilityEntropy()追溯难度评估
10.05-privacy...mdxrecommendPrivacyTech()多维度决策评分

桥:从隐私到未来

第10章建立了保护链上数据不可见的密码学工具箱。但第11章将面对更根本的问题:如果 Shor 算法能在多项式时间内破解这些密码学的根基,我们该用什么来保护?AI 时代的数据饥渴与量子时代的密码学颠覆,构成了第11章的双重叙事。

评论

0

评论加载中…

发表评论

0/2000