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

本页目录

链上数据天然公开,隐私从何谈起?本章建立三维威胁模型,拆解混币、环签名与零知识证明(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 都放进一个黑箱子,然后每个人从中随机取出一张 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;         // 香农熵: pilog2pi\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;

  

  // 香农熵 = i=1k1klog2(k)=log2(k)\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.anonymitySet}, 熵:{result.entropy.toFixed(2)} bits`);

// 输出:匿名集: 4, 熵: 2.00 bits

// 攻击者猜对的概率 P=1/4=25%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:{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(`Sprime:{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["输出: nullifier1,nullifier2nullifier_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(接受|假) ≤ negl

      零知识 模拟器等价

    zk-SNARK

      优点: 常数证明大小 ~200B

      缺点: 需要可信设置(CRS)

      不抗量子

      双线性配对 e(aP,bQ)=e(P,Q)^{ab}

      QAP: A(x)·B(x)=C(x)

    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.name.padEnd(18)} |{s.anonymitySet.toString().padStart(6)} | r.traceability.toExponential(2).padStart(12){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