卷 IV · 压短CH 15深度 15/23

那把必须被销毁的钥匙

Groth16 那 128 字节的证明不是白来的。生成它需要一批公开参数,而造这批参数的过程中会出现一个 32 字节的中间值。谁把它留下来,谁就能为任何假命题伪造出一份通过验证的证明——而且没有任何人能发现。它有个绰号叫「毒废料」。这一章讲人类为了销毁 32 个字节,做过些什么。

32 字节1-of-N14 万人

◻ 本章先赊三条
第一条。可信设置没有消除信任,它只是把信任从「相信证明者」搬到了「相信那场仪式里至少有一个人是诚实的」。 第二条。毒废料泄露不会泄露隐私。它打破的是可靠性——后果是凭空造币,而不是「你的交易被看光」。这两件事常被混为一谈。 第三条。「至少一个人诚实」这个门槛,可以靠人多压到几乎为零的风险——以太坊那场仪式有 14 万次贡献。

那 32 个字节是什么

不必展开代数,只需要知道它的形状。第 13 章那个 KZG 承诺(以及 Groth16)的参数长这样:

先取一个秘密的域元素 τ(读作 tau),然后公布一长串点:

    G,  τ·G,  τ²·G,  τ³·G,  …,  τᵈ·G

这一串叫「公共参考串」(CRS),谁都能下载,它就是那批公开参数。

关键:τ 本身必须被扔掉。
    知道 τ 的人,可以对任何多项式在「τ 这个点」上作弊——
    而验证者恰恰是在这个点上检查等式的。

换句话说:第 12 章那个「随机点」,在这类系统里是提前定好的,而且是加密藏起来的。验证者永远不知道它是几,所以证明者也没法针对它作弊——前提是证明者也不知道。

◆ 后果的精确形状

假设有人偷偷留下了 τ。他能做什么,不能做什么:

能不能说明
假命题伪造通过验证的证明可靠性被彻底打破(第 2 章那三条里的第二条)
在隐私币里凭空造币「我有 100 个币要花」这句假话,他能证明
看到别人交易的内容不能零知识那条性质不依赖 τ 的保密
偷走别人已有的资产不能他造的是新币,不是别人的私钥
被发现不会这才是最要命的一条。伪造的证明和真证明在数学上无法区分;而在一个隐私账本里,「总供应量对不对」根本没法直接查

「隐私系统」和「可审计的总量」在这里是冲突的:正因为没人看得见每一笔,也就没人能发现总数被悄悄放大了。这个矛盾不是工程疏忽,是这类设计的固有代价。

一个人诚实就够

怎么造一批「没有人知道 τ」的参数?答案是多方计算:让很多人接力,每个人往里面掺一点自己的随机性。

第 1 个人:取自己的秘密 s₁,把参数串「乘」上 s₁,公布结果,销毁 s₁。
第 2 个人:拿到上一步的结果,乘上自己的 s₂,公布,销毁 s₂。
……
第 N 个人:同上。

最终的 τ = s₁ · s₂ · … · s_N

要还原 τ,必须集齐全部 N 个人的秘密。
只要有一个人真的把自己那份删了,τ 就永远消失了。

而且每一步都是可验证的:任何人都能检查「第 k 个人确实是在上一步的基础上乘了某个数,而不是随手换了一串」。所以你不需要信任任何具体的人,你只需要相信:这 N 个人里,至少有一个删了。

仪式年份参与人数备注
Zcash Sprout20166第一次真正意义上的公开仪式
Zcash Sapling(Powers of Tau)201887参数变成可复用的,不再绑死一个电路
以太坊 KZG 仪式2023超过 14 万次贡献为 EIP-4844 的 blob 准备。任何人都能用浏览器参与

从 6 到 14 万,这条曲线本身就说明了一件事:这个信任假设不是靠数学变好的,是靠工程把参与门槛降到「点一下网页」变好的。

六个人和一次公路旅行

2016 年 Zcash 那场仪式值得一讲,因为它把「销毁 32 个字节」这件抽象的事,变成了非常具体的物理动作。

  • 六位参与者分散在不同大洲,互不见面。
  • 每个人用一台从未联网、也永远不会联网的电脑做计算(air-gapped)。数据靠 DVD 光盘和 U 盘单向搬运。
  • 其中一位(Peter Todd)开车穿越加拿大,中途在一家五金店买了工具,把用过的硬件物理砸毁;他还用了法拉第袋、拍摄了全过程、并把随机性来源和当天的报纸头版拍在一起(证明「这不是提前准备好的」)。
  • 整个过程被记录下来,后来剪成了一部短纪录片。

这些动作在密码学上都不是必需的——数学只要求「至少一人删除」。它们是做给人看的:把一个无法被验证的承诺(「我真的删了」),尽可能变成一个可以被旁观者判断的表演。

而 2019 年披露的一件事,说明了这条路有多窄:Zcash 早期使用的那套参数里有一个数学缺陷(后来编号 CVE-2019-7167),它本身就允许伪造证明、凭空造币——和仪式办得多严密毫无关系。缺陷在 2018 年被内部发现并随 Sapling 升级悄悄修复,2019 年才公开。由于屏蔽交易的性质,官方也无法完全确认这个漏洞在被修复前是否曾被利用。

这是这本书里最典型的一次「事故不在你以为的地方」:所有人的注意力都在「τ 有没有被销毁」,而洞开在参数的数学结构里。第 22 章会把这个模式讲透。

怎么绕开它

方案要不要仪式说明
Groth16每个电路一场证明只有 128 字节,代价是改一行电路就要重办仪式。这在快速迭代的项目里是噩梦
PlonK / Marlin通用一场,可更新一场仪式生成的参数,任何不超过某个规模的电路都能用;而且后来的人还能继续往里掺随机性(updatable)。以太坊那场就是这种
STARK / Bulletproofs / Halo2 等不需要只依赖哈希函数或普通的离散对数假设。这类系统叫 transparent(透明的)。代价是证明大了几百倍(第 16 章)
✎ 术语正名

「可信设置」(trusted setup)这个译名容易让人以为要「信任某个机构」。准确的说法是:这批参数在生成时曾经存在过一个秘密,你需要相信它已经不存在了。

「透明」(transparent)的意思则是:参数完全由公开、可复现的东西决定——比如一个哈希函数的常数,或者圆周率的小数位。这类做法在密码学里有个老名字叫 nothing-up-my-sleeve numbers(袖子里没藏东西的数),你在 SHA-256 的初始常数(取自素数平方根的小数部分)里就能看到同一个思路。

顺带纠一个常见混淆:「透明」不等于「更安全」。透明系统避开了仪式风险,但换来了别的假设(比如那个哈希函数确实像随机预言机,第 8 章)。没有哪个方案的信任是零,只有信任放在哪里的区别。

⌨ 自己跑一遍

「一个人诚实就够」这句话可以用十行代码看得很清楚。下面模拟一场三人仪式:

import random

q = 2 ** 61 - 1                      # 假装这是群的阶

# ---- 仪式:三个人接力,每人乘上自己的秘密 ----
shares = []
tau = 1
for who in ['Alice', 'Bob', 'Carol']:
    s = random.randrange(2, q)       # 只有本人知道
    shares.append((who, s))
    tau = tau * s % q                # 参数被更新,但 tau 从未被任何人算出来
print('最终的 τ(上帝视角)=', tau)

# ---- 谁能还原它? ----
def try_recover(known):
    v = 1
    for who, s in shares:
        if who in known:
            v = v * s % q
        else:
            return None              # 缺一个就还原不出来
    return v

print('三个人全部串通  →', try_recover({'Alice','Bob','Carol'}) == tau)
print('两个人串通      →', try_recover({'Alice','Bob'}))
print('Carol 一个人删了 → 谁也还原不了')
最终的 τ(上帝视角)= 1837462...(每次不同)
三个人全部串通  → True
两个人串通      → None
Carol 一个人删了 → 谁也还原不了

再算一下「至少一人诚实」这个假设有多值钱。如果每个参与者独立地有 10% 的概率作恶:

for n in (1, 3, 6, 10, 87, 1000):
    print('%5d 人全部作恶的概率 %.3e' % (n, 0.1 ** n))
# 1 人      1.000e-01
# 3 人      1.000e-03
# 6 人      1.000e-06     ← Zcash 2016
# 10 人     1.000e-10
# 87 人     1.000e-87     ← Zcash 2018
# 1000 人   0.000e+00(下溢,实际是 10^-1000)

这个模型是乐观的——现实中参与者未必独立(同一个组织派了五个人、同一个云厂商的五台机器、同一个有后门的随机数发生器)。所以真实仪式会刻意找互相敌对、地理分散、软硬件各异的参与者。「独立性」在这里不是数学假设,是社会工程。

python3 -c "print(*['%d ren %.0e'%(n,0.1**n) for n in (1,3,6,10,87)], sep='\n')"

在线跑:python.org/shell。想看真实仪式长什么样,找以太坊 KZG Ceremony 的公开贡献记录——每一次贡献都留下了可验证的证明。

▸ 在现实里
  • 核武器的双人规则、导弹发射钥匙。同一个信任结构的反面:那里要求「必须多个人同时同意才能做事」,这里要求「只要一个人守规矩就没事」。前者叫门限,后者叫 1-of-N,它们在密码学里是同一族工具的两种配置。
  • DNSSEC 的根密钥仪式。互联网域名系统的信任根,每季度由一群「可信社区代表」在两个高度设防的设施里,用智能卡、生物识别、防拆封条完成一次签名仪式,全程录像并有第三方审计。它和 Zcash 那场在形式上高度相似——都是把「你必须相信一件无法验证的事」尽量转成「很多人一起看着」。
  • 硬件随机数的可信问题。2013 年斯诺登文件揭示的 Dual_EC_DRBG 后门,本质上也是「参数里可能藏着一个只有制造者知道的秘密」。它和毒废料是同一个形状的风险,而它的教训直接推动了「透明参数」在标准里的普及。
  • 为什么以太坊选了通用可更新的仪式。因为 Groth16 那种「每改一次电路就重办一次」的模式,在一个持续升级的公链上是不可接受的运营负担。技术选型经常是被运维现实决定的,而不是被论文里的性能表决定的。
✗ 这个直觉是错的

「可信设置太危险了,万一那个秘密没被销毁,我的隐私就全没了。所以要用就用 STARK。」

前半句的担心是对的,理由是错的。毒废料泄露不会泄露任何人的隐私——零知识那条性质(第 7 章的模拟器论证)根本不依赖 τ 的保密。泄露的后果是可靠性被打破:他能证明假命题,也就是在隐私币里凭空造币。

分清这两件事非常实用,因为它决定了你该防什么。可靠性被打破是「系统被悄悄印钞」,隐私被打破是「用户被看光」。前者的受害者是所有持币人(通过通胀),后者的受害者是具体的个人。它们的应急预案完全不同。

后半句也太快了。STARK 免掉了仪式,但它把信任放到了别的地方(哈希是随机预言机、FRI 的可靠性分析、那套参数的安全比特数),而且证明大了几百倍。判据是:不要问「有没有可信设置」,要问「这个系统一共有几条必须成立的假设,每条如果不成立会怎样」。下一章那张表就是按这个判据组织的。

✓ 结账

这一章的一句话

可信设置不是「信任某个机构」,是「相信某个曾经存在过的 32 字节秘密已经不存在了」;它可以靠让很多互相敌对的人接力来压到几乎零风险,但它换来的那 128 字节证明,代价是每一次电路改动都要重办一次这场戏。

下一章把这本书出现过的所有方案摊在一张表上。你会看到四个旋钮——证明大小、验证成本、要不要仪式、扛不扛量子——以及一条冷酷的规律:没有一个方案在四个旋钮上都好。Groth16 的 128 字节和 STARK 的 45 KB,买的是两种完全不同的东西,而选哪一个几乎从来不取决于「哪个更先进」。