Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

零知识证明:证明成立,同时隐藏秘密

零知识证明(Zero-Knowledge Proof,ZKP)让证明者向验证者证明一个陈述成立,同时不通过证明过程泄露公开信息和结论之外的秘密信息。它既可以用于保护隐私,也可以配合简洁证明验证复杂计算。

证明的可靠性与零知识性是不同性质。限制伪造成功率不代表保护秘密;直接公开秘密答案的验证过程,即使可靠,也不具备隐藏该秘密的零知识性。

公开输入、见证与证明

一个证明任务通常包含以下部分:

概念含义示例
公开输入(Public input)验证者已知或需要核对的数据一个公开的哈希值 h
见证(Witness)使陈述成立的秘密数据满足 H(s) = h 的秘密 s
约束关系(Relation)证明需要满足的规则对 s 计算哈希后,结果等于 h
证明(Proof)证明者按协议生成的可验证数据验证者检查的数据 π,而不是 s 本身

在这个例子中,公开陈述是“存在秘密 s,使 H(s) 等于 h”。证明者利用 s 生成证明,验证者用 h、证明和系统的公共参数进行验证,不必拿到 s 后自己计算哈希。

常用的知识证明还要求证明者确实掌握相应见证,不能只碰巧构造出可接受的证明。这个要求与不泄露见证的零知识性有关联,但不是同一个性质。

把哈希值直接交给对方,或者说“我知道它的原文”,本身不是零知识证明。还需要具体协议,让验证者能够检查陈述。若公开的 h 对应一个很容易猜测的秘密,攻击者仍可能自行枚举;零知识证明不会消除公开信息本身的泄露。

三个基本性质

完备性(Completeness):陈述为真,证明者有合法见证,双方遵循协议时,验证应当成功。具体系统可能允许可忽略的完备性误差,不能把正常失败率与安全性混为一谈。

可靠性(Soundness):陈述为假时,恶意证明者也很难使验证者接受。协议通过数学结构和安全参数限制错误接受的可能性;一些系统的保证还依赖攻击者的计算能力及密码学假设。

零知识性(Zero-knowledge):证明过程不额外泄露秘密信息。形式上,验证者所见的信息应能在不知道见证的情况下,仅用公开输入模拟出来,或与这样的模拟不可区分。这比“没有直接写出密码”更强。

可靠性回答“能不能骗过验证”,零知识性回答“验证会不会泄密”。增加挑战轮数可能降低某个协议的欺骗概率,却不能把一个原本泄露答案的问答过程变成零知识证明。

交互式证明的秘密门模型

设洞穴有左右两条通道,深处由一道需要密码才能打开的门相连。证明者声称知道密码,验证者想确认这件事,但不想获得密码。

  1. 验证者在洞外等待,证明者先随机选择一条通道进入,验证者看不到选择。
  2. 证明者进入后,验证者才随机要求她从左侧或右侧回来。
  3. 知道密码的人可以穿过门,从指定通道返回;不知道密码的人,只能在要求碰巧与自己所在通道一致时成功。
  4. 在挑战独立、随机且无法提前预测的条件下,重复 n 次,不知道密码的人全部成功的概率为 2^(-n)。

验证者看到的是她按要求回来,没有看到密码或开门方法。关键在于挑战发生在证明者选择通道之后,而且验证者不能观察隐藏路径;如果这些条件改变,结论也可能改变。

秘密门模型描述挑战顺序与重复试验的关系。具体密码学协议还需要定义消息、模拟器与安全假设,模型中的成功概率不能代替形式化的零知识性证明。

从交互式到非交互式

交互式证明需要证明者与验证者交换挑战和响应。非交互式证明则允许证明者在系统参数确定后生成一份证明,由验证者独立检查,更适合链上合约和异步系统。

非交互式不等于“公布一个很难的问题,再把秘密答案交上去”。验证者收到的仍然是密码学证明,而不是私人经历、密码或见证本身。它的安全性依赖具体构造和公共参数。

部分协议使用 Fiat–Shamir 变换,用对公开输入和协议消息的哈希生成挑战,从而减少交互。它需要满足相应的安全条件,不能简单认为任何问答协议都能通过一次哈希安全地改成非交互式证明。

zk-SNARK 与 zk-STARK

类型主要特点需要注意的条件
zk-SNARK强调简洁、非交互和知识证明,证明较小、验证较高效底层构造多样,部分方案需要可信设置,不能说所有 SNARK 都需要
zk-STARK强调可扩展、透明设置,主要依赖哈希等工具通常无需秘密的可信设置;证明大小和验证成本仍取决于具体方案

可信设置指某些方案需要产生公共参数,而且某些生成过程中的秘密必须妥善销毁。透明设置避免了这类秘密依赖,但不意味着系统不再需要密码学假设、正确实现和安全参数。

这两类方案的区别涉及证明大小、生成与验证成本、设置方式和安全假设。不能仅用“把真假证明者的答题概率进一步拉开”概括它们,也不能只凭名称判断某个应用是否保护隐私。

应用中的证明对象

证明年龄满足要求

用户可以用受信任机构签发的凭证作为见证,证明凭证签名有效,且其中的出生日期满足公开日期下的年龄门槛,而不公开完整出生日期。

这里需要同时验证凭证来源和日期条件。如果只让用户自行填写出生日期,再证明计算没有错误,就无法证明现实中的年龄。零知识证明保证所选约束成立,外部数据是否可信仍需要凭证、签名或其他机制支持。

验证交易与链下计算

隐私交易可以证明金额守恒、输入资产可用及授权有效,同时隐藏选定的金额或参与者信息。但是否真的隐藏这些信息,还取决于交易格式、公开输入及协议设计。

有效性 Rollup 使用证明来验证一批状态转换是否符合规则,减少基础链重复执行的工作。这强调的是计算正确性和验证效率;若交易数据仍公开发布,使用 ZK 技术也不会自动让交易内容保密。

零知识证明的边界

证明只能保证编码进去的规则。若电路遗漏条件、签名没有绑定用途、公开输入过多,或者验证合约接受了错误参数,即便底层证明系统可靠,应用仍可能出错或泄露信息。

安全参数用于限制伪造的可能性,但不能把所有系统概括为某个固定的“99.99% 正确率”。还应区分协议误差、密码学假设和工程实现错误;实际风险未必来自随机猜测。

零知识性也不隐藏公开结论本身。证明“已满 18 岁”已经透露了一个年龄范围,多次提交不同门槛的证明还可能缩小这个范围。应用应先确定需要公开什么,再选择证明的陈述和参数。

参考资料