链上数据天然公开,隐私从何谈起?本章建立三维威胁模型,拆解混币、环签名与零知识证明(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)依赖的核心假设是:地址聚类与行为指纹。攻击者(分析者)通过以下手段逐步降低目标用户的匿名度:
- 启发式聚类(Heuristic clustering):利用共同输入所有权假设(Common Input Ownership Heuristic, CIOH),将共享同一笔交易输入的多个地址归为同一实体。
- 地址重用检测:同一地址被多次使用,直接暴露关联关系。
- 交易图分析:构建资金流向图,识别交易所、混币器、合约等“服务节点”,通过交互行为推断实体身份。
- 时间戳关联:交易时间与现实世界事件关联,缩小匿名集。
- KYC 关联机制:交易所、OTC 平台、法币出入金接口要求身份验证,形成“去匿名化枢纽”。
我们定义去匿名化程度为一个衡量指标:
其中 是攻击者视角下无法与目标区分的用户集合大小。 意味着完全去匿名化。
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)是中心化金融设施与公链之间的“隐私断层”。其关联机制可形式化为:
其中 是所有可能的 KYC 出金/入金事件。一旦用户在某交易所 完成 KYC 并存入/提取资金到地址 ,则 。
更糟糕的是,即使后续资金经过多层转移或混币,只要最终回流到已 KYC 标记的地址,图回溯分析仍然有效:
其中 为混币池的匿名度(k-anonymity)。这个公式直观说明:匿名集越大,关联置信度越低。
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));该模型展示了隐私评估的核心直觉:交易模式的独特性本身就是去匿名化的信号。即使隐藏了金额和地址,独特的时间模式或交易图拓扑仍可能暴露用户。
本节核心公式索引
- 去匿名化程度:
- KYC 后验概率:
- 关联置信度:
10.2 混币与环签名
如果区块链的透明性让每笔交易都暴露在链分析之下,那么混币与环签名就是最早的"幕布"——它们不创造数学上的绝对隐私,但通过混淆交易链路,让追踪者面对一个巨大的"可能性集合",从而在实践中保护用户。
10.2.1 混币(CoinJoin)的基本原理
直觉:多人凑份子发钱
混币的核心思想简单得出奇:把多笔输入和输出混合在一次交易中,让外部的观察者无法判断哪个输入对应哪个输出。
想象五个人各自拿着 10 都放进一个黑箱子,然后每个人从中随机取出一张 50 进去了、$50 出来了,但你无法知道谁的钱最终给了谁。
比特币的 CoinJoin 正是这一思想的链上实现。
CoinJoin 交易结构
在普通的比特币交易中,输入地址向输出地址直接转账,链路清晰:
在 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)
混币的效果可以用匿名集来量化:
在这个交易中有 个 的输出。外部观察者只能判断"Alice 输入了 1 BTC"和"有人得到了 1 BTC",但无法确定这 究竟流向了 个输出中的哪一个。
攻击者将真实的资金流向猜对的概率为:
匿名集越大,隐私越强。 但混币面临两个核心问题:
- 需要信任协调者:谁来组织这个混币交易?
- 等值约束:所有参与金额必须相等,否则金额差异会泄露链路。
类型Script 模拟:混币交易的输入输出匹配
/**
* 混币(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; // 香农熵:
} {
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;
// 香农熵 =
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.entropy.toFixed(2)} bits`);
// 输出:匿名集: 4, 熵: 2.00 bits
// 攻击者猜对的概率 Wasabi 钱包:Chaumian 盲签名混币
现代混币方案使用 Chaumian 盲签名 来解决"信任协调者"问题:
- 用户先对输出地址进行盲签名——用盲因子 包裹地址,让协调者签名时不知道真实地址
- 协调者对盲化后的地址签名后返回
- 用户移除盲因子 ,得到一个"协调者不知道对应关系"的有效签名
- 协调者只能看到所有等值输出,但不知道哪个用户对应哪个输出
这消除了对协调者诚实性的依赖:即使协调者串通,也无法将输入与输出关联。
10.2.2 环签名(Ring Signature)
从"混合多签名"到"环签名"
环签名是一种更优雅的"内建"方案——不需要外部协调者,交易本身就包含一个"环",证明签名者来自其中某一个地址,但不暴露具体是哪一个。
定义:环签名允许一个签名者从一组公钥(包含自己的公钥)中生成一个签名,使得验证者可以确认这组公钥中至少有一人签名,但无法确定具体是谁。
关键性质
环签名满足三个核心性质:
- 无条件匿名性:给定环签名,识别出真实签名者的计算复杂度等价于破解底层困难问题
- 不可伪造性:非环成员无法伪造有效签名
- 无需环成员许可(区别于群签名):环成员甚至不知道自己被包含在某个环中
环签名链接概率
在包含 个成员的环中,外部观察者正确猜出真实签名者的概率为:
当环大小 (Monero 默认),攻击者的正确识别概率仅为 。经过三轮交易,匿名性将呈指数级提升:
密码学构造(简化版 - CryptoNote 风格)
环签名基于一次性密钥(stealth address)和密钥映像(key image)设计。核心公式:
其中 是随机生成的混淆公钥的"变形因子", 是椭圆曲线基点。真实签名者的位置索引 被嵌套在环中。
签名 必须满足循环验证方程:
验证时检查 的循环一致性。
10.2.3 隐匿地址(Stealth Address)
核心思想:接收方一次性地址
区块链地址一旦公开,就成为追踪的固定锚点。隐匿地址让每个发送方都能为接收方生成一个独特的一次性地址,而接收方使用自己的私钥扫描区块链来发现属于自己的这些地址。
一次性地址生成(简化 Diffie-Hellman 方案)
发送方(Alice)使用接收方(Bob)的公钥 :
- Alice 生成临时私钥 ,计算公钥
- 共享秘密:
- 一次性地址公钥:
接收方(Bob)扫描时,用私钥 对每个交易的 计算 ,如果生成的公钥匹配自己的,则知道该交易是给他的。
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
/**
* 隐匿地址(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(`{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(`{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 三性质(形式化定义)
对于陈述 和证据 ,证明者 向验证者 证明 (其中 是某个 NP 语言):
zk-SNARK 的核心优势
| 特性 | 说明 |
| ------ | ------ |
| 证明大小 | (仅 ~200 字节) |
| 验证时间 | (毫秒级) |
| 可信设置 | 需要一次性 CRS 生成仪式 |
| 抗量子 | 否(基于椭圆曲线配对) |
可信设置(Trusted Setup)的脆弱性
zk-SNARK 需要生成公共参考字符串(CRS),推导过程中会产生有毒废料(toxic waste)——如果设置参与者合谋保留了废料,就可以伪造证明。
解决方案:多方计算仪式(MPC Ceremony),如 Zcash 的 Powers of Tau:
- 第一个人贡献随机值 ,计算
- 第二个人用新随机值 再次"混合":
- 最终只要至少一个人诚实销毁了自己的随机值,整个 CRS 就是安全的
zk-STARK:无需可信设置
| 特性 | zk-SNARK | zk-STARK |
| ------ | ---------- | ---------- |
| 可信设置 | 需要 | 不需要 |
| 证明大小 | ~200 字节 | ~50-200 KB |
| 验证时间 | (仍很快) |
| 抗量子 | 否 | 是 |
| 依赖假设 | 椭圆曲线配对 | 哈希函数(抗碰撞) |
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 合并为单一证明):
- 所属权:私钥对应某个未被花费的 UTXO
- 余额非负:输入总额 >= 输出金额(在密文层面)
- 无双重花费:输入的零知识承诺是唯一的(通过 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["输出: + + 新承诺"]
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)
如果陈述为真且证明者知道证据,验证者总是接受:
2. 可靠性(Soundness)
如果陈述为假,任何作弊的证明者都无法让验证者接受(除可忽略概率外):
3. 零知识性(Zero-Knowledge)
验证者从交互中获得的信息,完全可以由一个模拟器独立生成——也就是说,验证者"什么也没学到":
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),然后证明"我知道满足这个电路的输入(证据)"。
对于一个包含 个门的电路,zk-SNARK 使用以下密码学构造:
其中 是多项式,只有当电路逻辑被正确满足时,中间多项式的等式才成立。证明者要证明的是:
核心密码学:双线性配对(Bilinear Pairing)
zk-SNARK 依赖于椭圆曲线上的双线性配对 :
这允许验证者通过检查配对等式来验证多项式约束,而不需要看到证据。
可信设置仪式(CRS 生成)
zk-SNARK 的公共参考字符串(CRS)包含可信设置中生成的公开参数:
其中 是"有毒废料"。如果设置参与者保留 ,就可以伪造证明。
MPC 多方计算仪式(Powers of Tau)确保只要至少一方诚实地删除了自己的秘密贡献,系统就是安全的。以太坊的 KZG 承诺(Dencun 升级中包含的 4844 提案)就采用了这种仪式。
zk-SNARK 的证明验证成本
对于 1 万次门电路,zk-SNARK 的技术参数是惊人的:
| 指标 | 值 | 对比(非 ZK 验证) |
| ------ | ---- | ---- |
| 证明大小 | 约 200-300 字节 | N/A |
| 验证时间 | 约 2-3 毫秒 | (几毫秒到秒级) |
| 证明生成时间 | 几秒到几分钟 | N/A |
证明大小与验证时间的常数级增长,是 zk-SNARK 名称中 "S"(Succinct 简洁) 的来源。
抗量子短板
zk-SNARK 的安全基础是:
- 椭圆曲线离散对数
- 双线性配对的 Diffie-Hellman 假设
这两者都在量子计算下存在多项式时间破解——zk-SNARK 不具有抗量子安全性。
/**
* 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-SNARK | zk-STARK |
| ------ | ---------- | ---------- |
| 安全假设 | 椭圆曲线配对 + CRS | 哈希函数(抗碰撞) |
| 可信设置 | 需要 Powers of Tau | 无需 |
| 证明大小 | ~200 字节 | ~50-200 KB |
| 验证时间 | 毫秒 |
| 量子安全 | 否 | 是 |
| 递归聚合 | 需要特殊构造 | 原生支持 |
FRI 协议:STARK 的核心
zk-STARK 使用 FRI(Fast Reed-Solomon Interactive Oracle Proof) 协议来证明一个多项式"接近"低次(也就是"我的计算遵守了正确的多项式约束")。
核心思想:如果一个多项式 的次数远小于其求值域,那么随机采样可以高概率检测出作弊。
给定声明"多项式 的次数 ",验证者:
- 要求证明者承诺 在域 上的所有求值(通过 Merkle 树根)
- 随机挑战点
- 证明者提供 的 Merkle 证明
- 验证者检查一致性
- 将问题"折叠"为更小的子问题,迭代 轮
最终验证只需要 次查询,但每次查询需要整个求值域的 Merkle 证明(约多项式 次求值)。
STARK 证明尺寸公式
其中 是约束次数, 是有限域大小。
这意味着证明大小随约束的平方对数增长,而非 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 个成员的环:
这意味着每个外部观察者猜对真实发送者的概率只有 6.25%。经过 3 层混洗后:
2. 隐匿地址:一次性接收
每个 Monero 交易为接收方生成一次性公钥,只有接收方的"扫描私钥"可以检出这笔交易。这消除了"地址复用"的追踪风险。
3. RingCT:隐藏金额
在 2017 年(v0.14.0 后),Monero 使用 Bulletproofs(后接 Bulletproofs+)来隐藏交易金额,同时保证输入总额等于输出总额:
其中 是输入的 Pedersen 承诺:。证明者需要证明 而不泄露具体数值。
Bulletproofs+ 将证明大小从 ~13 KB 压缩到 ~1.4 KB,显著提升链上效率。
10.4.2 Zcash:可选隐私与 zk-SNARK
设计哲学
"透明是默认,隐私是选择。"
Zcash 采用可选隐私模式:用户可以选择发送透明交易(t-address → t-address,类似比特币)或屏蔽交易(z-address → z-address,完全隐私)。
这种设计有两个后果:
- 可用性:交易所可以轻松集成透明地址
- 隐私泄漏:如果用户不小心混合使用 t 和 z 地址,可能通过 Heuristic 分析暴露身份
核心技术:zk-SNARK + 承诺
Zcash 的隐私交易(Sapling 之前用 Sprout,Orchard 之后用 Halo2)使用 zk-SNARK 来证明:
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 横向对比:三场维度的博弈
隐私强度对比
| 维度 | Monero | Zcash (z-addr) | 比特币 + 混币 | 以太坊 (非 ZK) |
| ------ | -------- | --------------- | ------------- | --------------- |
| 发送者匿名 | 环签名 1/16 | zk-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 模拟:隐私币交易追溯难度评估
/**
* 隐私币匿名性评估模拟
* 比较不同方案的"不可逆追踪熵"
*/
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.anonymitySet.toString().padStart(6)} | {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+0010.4.4 知识地图
mindmap
root((隐私币))
Monero
强制隐私
环签名 n=16
隐匿地址
RingCT(Bulletproofs+)
优点: 无信任假设 无CRS
缺点: 大交易体积 不扩容
Zcash
可选隐私
zk-SNARK(Halo2)
承诺池
优点: 小证明 快验证
缺点: 可选→元数据泄漏
对比维度
发送者匿名
接收者匿名
金额隐藏
量子安全
法律合规
10.5 隐私技术全景对比与决策框架
在前四节中,我们分别拆解了隐私需求模型、混币与环签名、零知识证明、以及隐私币的工程实现。本节将所有这些技术放在同一坐标系中对比:不是寻找"最强"的方案,而是建立一套可操作的取舍框架。
10.5.1 隐私技术全景矩阵
| 技术 | 匿名维度 | 数学基础 | 信任模型 | 验证成本 | 证明/数据大小 | 抗量子 | 代表项目 |
| ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ |
| 混币(CoinJoin) | 发送者 | 无密码学 | 半信任(协调者) | 最低 | ~200B | 否 | Wasabi, Samourai |
| 环签名 | 发送者 | 离散对数假设 | 无 | 低(签名验证) | ~4 KB/签名 | 否 | Monero |
| 隐匿地址 | 接收者 | ECDH | 无 | 最低 | ~70B(ephemeral key) | 否 | Monero, Grin |
| zk-SNARK | 全维度(发送/收/金额) | 配对 + CRS | 一次性 MPC | 最低(O(1)) | ~200 B | 否 | Zcash, Aztec |
| zk-STARK | 全维度 | 哈希 + FRI | 无 | 低(O(log²D)) | 50-200 KB | 是 | StarkNet, RISC0 |
| 同态加密 | 计算中隐私 | LWE/RLWE | 无 | 高 | 密文膨胀 10-100x | 是 | Zama, 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 未来趋势:隐私即默认
当前区块链的默认状态是全透明,隐私需要"额外付费"(更多的计算、更复杂的工具、更少的兼容性)。但行业共识正在向"隐私即默认"演进:
- 账户抽象 + 隐私(EIP-4337 + Aztec):用户不需要管理复杂的 ZK 密钥,钱包内置隐私。
- 通用 zkEVM:在保持 EVM 兼容的同时默认启用隐私计算。
- 模块化隐私:Celestia 提供 DA 层,隐私专用链(如 Aztec)提供执行层,以太坊提供结算层。
- 后量子隐私:NIST 标准化后量子密码后,向 zk-STARK 或格密码迁移。
/**
* 隐私技术评估决策辅助
* 为给定场景计算推荐方案得分
*/
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 核心公式与索引
本章核心公式
| 公式 | 含义 | 出现位置 |
| ------ | ------ | ------ |
| 环签名真实签名识别概率 | 10.2 |
| 匿名集香农熵 | 10.2 |
| Pedersen 承诺 | 10.2 |
| 隐匿地址生成 | 10.2 |
| 双线性配对 | 10.3 |
| SNARK 常数级证明大小 | 10.3 |
| STARK 对数平方级证明大小 | 10.3 |
核心 TypeScript 代码索引
| 文件名 | 算法 | 核心概念 |
| -------- | ------ | ------ |
10.01-privacy-model.mdx | 隐私评分矩阵 | 三维度隐私量化 |
10.02-mixer...mdx | CoinJoin 模拟 + 隐匿地址 | 匿名集 / 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 |
| 隐匿地址 | 接收者 | ECDH | 无 | 否 | Monero, Grin |
| zk-SNARK | 全维度 | 双线性配对 | 需CRS | 否 | Zcash, Aztec |
| zk-STARK | 全维度 | 哈希 + FRI | 无 | 是 | StarkNet, RISC Zero |
| 全同态加密 | 计算过程 | 格 (LWE) | 无 | 是 | Zama |
核心公式索引
| 公式 | 含义 | 文件 |
| ------ | ------ | ------ |
| 环签名真实签名被识别的概率(匿名集 ) | 10.02 |
| Pedersen 承诺(隐藏金额) | 10.02 |
| 双线性配对(zk-SNARK 核心) | 10.03 |
| 零知识性:模拟器等价 | 10.03 |
| QAP(zk-SNARK 的电路约束) | 10.03 |
| STARK 证明尺寸上界 | 10.03 |
| Bulletproofs 大小 | 对数内积证明 | 10.04 |
| H = -k/2 \cdot \log_2 n | 环签名的香农匿名熵 | 10.04 |
核心 TypeScript 代码索引
| 文件名 | 核心模拟算法 | 概念 |
| -------- | ------ | ------ |
10.01-privacy-model.mdx | createPrivacyScore() + comparePrivacySolutions() | 隐私三维度量化评分 |
10.02-mixer...mdx | createCoinJoin() + generateStealthAddress() | 混币 / DH 密钥交换 |
10.03-zkp...mdx | verifySNARK() | 配对检查 / 常数验证 |
10.04-monero...mdx | computeTraceabilityEntropy() | 追溯难度评估 |
10.05-privacy...mdx | recommendPrivacyTech() | 多维度决策评分 |
桥:从隐私到未来
第10章建立了保护链上数据不可见的密码学工具箱。但第11章将面对更根本的问题:如果 Shor 算法能在多项式时间内破解这些密码学的根基,我们该用什么来保护?AI 时代的数据饥渴与量子时代的密码学颠覆,构成了第11章的双重叙事。
评论
0评论加载中…