本文深入探讨了零知识证明(ZKP)的不同应用,包括ZK支付、ZK硬件加速和zkVMs,强调了如何通过ZK技术提升区块链交易的隐私性和效率。文章详细介绍了ZK支付中的私密交易机制、使用特定硬件加速证明生成的优势,以及zkVM的通用性和实现原理,展现了零知识技术的广泛应用潜力。
上次,我们探索了 zkSNARKS 的基础知识及其在区块链中的应用。我们介绍了以下内容:
要对 ZK 领域的这些方面进行复习,可以查看 第一部分 这里。
在奠定了 ZK 领域的基础之后,我们来看看零知识的更多应用:ZK 支付、ZK 硬件加速和 zkVMs。在这些应用的讨论中,我们将简要了解一些 ZK 领域最显著的领域,并结束我们的之旅。
作为 ZK 支付的简要概述,我们将介绍完全私密和安全交易的入门知识。对于 ZK 硬件加速,我们将讨论 zkSNARKs 如何用于加速密码操作。最后,对于 zkVMs,我们将探讨 zkSNARKs 如何用于提高任何区块链网络的速度,而不仅仅是以太坊。
比特币、以太坊和Solana都是公共加密货币,这意味着所有交易、账户和数据都是公开的。然而,在某些情况下,私人交易↗ 是必要的。ZK 支付旨在利用 ZK 证明确保三个标准:
在表面上,公共区块链似乎是私密的。以这个以太坊地址为例。这看起来像一个人的身份吗?
0xB256227cfc6209fCC7bA1c4acb9329721Acb89d4
虽然看起来可能不一样,但这个人的交易和活动是公开的。这些信息允许其他人追踪一个人的身份,并相对快速地监控他们在区块链上的使用情况。
ZK 支付的主体是基于 Zcash↗ 的设计。简而言之,Zcash 允许用户在 Zcash 区块链↗ 上进行币的转移,用户可以选择将其交易设为公开或私密。
Zcash 的交易使用类似于比特币的 UTXO 结构。当发送者处理交易时,发送者发布两个票据。一个票据包含发送者的新余额,另一个包含发送的金额。为了保持私密,这些票据用 ChaCha20-Poly1305↗ 加密。ChaCha20 是与 AES 类似的对称加密算法,在此示例中因其快速的加密速度而被选中。只有发送者和接收者可以使用自己的密钥解密票据。这两个新的加密票据随后被哈希并提交到一个中央 Merkle 树中。
到此为止,公众无法验证交易,因为票据是加密的。这就是 ZKP 的用武之地。Zcash 的旧版本↗,在 2018 年 Sapling 激活发布之前,使用的
BCTV14↗ 是一种比 Groth16↗ 更慢、更旧且耗能更多的证明系统。鉴于 Groth16 于 2016 年创建,Zcash 选择继续使用 BCTV14 以确保 Groth16 的安全性,然后在两年后实施了 Sapling 激活。在 Sapling 激活之后,选择了 Groth16,因为其快速的证明/生成速度。这样可以让其他人验证私交易的有效性,而无需透露任何关于用户的数据。
(作为有趣的事实,这些证明系统都是以最初提出它们的研究论文命名的。BCTV14 由以 B、C、T 和 V 开头的作者于 2014 年发布。而 Groth16 论文则由 Jens Groth 于 2016 年发布。)
Zcash 特别使用两个 ZK 电路和一个值承诺检查:
支出电路。 支出声明是一个 ZK 证明,负责确保交易能够正确进行。这个电路创建一个证明,确认提交给验证者的票据和 Merkle 路径是有效的,最初的支出者有权限进行此交易,之前的票据被废止,两个新票据的余额加起来等于原始票据。
输出电路。 输出声明是新币生成过程中的一个 ZK 证明。它允许验证者确认为该币创建的票据有效,以及值承诺的有效性。
(同态)佩德森承诺。 佩德森承诺被 Zcash 使用( Zcash 协议规范↗,第 18 页),每当承诺一个值时都会使用它。同态特性允许佩德森承诺相加和相减。例如,为确保在交易过程中不会创建/销毁币,发送者的新余额的值承诺可以与发送币的值承诺相加并检查,以确保总数保持不变。
我们的下一站是加速 ZKP 生成。目前,为交易生成 ZKP 是一个耗时且资源密集的过程。然而,目前正在进行的工作是使用专门的硬件加速这一过程。证明生成已从使用 CPU 发展到现在的 GPU,甚至是专为 ZKP 生成设计的 FPGA 电路。
CPU 的速度较慢。它们用于日常计算,而不适合 数学密集型↗ ZK 证明生成。人们逐渐开始使用 GPU,因为显卡被设计用于以更快的速度执行专用的、向量化的计算(例如,游戏和高帧率视频流)。然而,GPU 仍然被设计用于广泛的用途。社区开始探索利用 FPGA 的解决方案,FPGA 更加专业。
FPGAs↗ 是可以直接购买的硬件。用户可以重新配置内部电路以满足特定电路要求。与其让 GPU/CPU 的专用部分用于日常计算,不如将 FPGA 的整个电路改变并专用于 ZK。证明生成中最耗时的部分来自于 两个类别↗:
(快速)傅里叶变换 (FFTs)。 ZKP 通常使用傅里叶变换在椭圆配对上进行除法。虽然 FFTs 在亚指数时间运行,但它们仍然是 ZKP 生成的主要部分。
乘法。 大多数 ZKP 包含椭圆曲线乘法,这在计算上是昂贵的。因为单个门无法表达椭圆操作,所以必须将多个二进制门串联在一起以执行椭圆操作。
为应对这些挑战并加快证明生成过程,可以通过开发应用特定的集成电路 (ASICs) 找到解决方案,ASIC 是专门为生成 ZKP 的目的构建的硬件。通过将所需的数学运算硬线设计到硬件中,ASIC 可以更高效并行地执行这些计算,从而显著减少生成 ZKP 所需的时间。
使用 ASIC 进行 ZKP 生成具有多个优点,包括提高速度、降低功耗和改善可扩展性。这些专用硬件解决方案可以优化最耗时的操作,使 zkSNARKs 对于高性能应用(如隐私保护交易、安全通信和可验证计算)更具实用性。
然而,使用 ASIC 也面临 缺点↗。ASIC 最适合于不常变化的成熟应用,例如 SHA-256 POW 挖矿。而 ZKP 生成仍在迅速发展。为 ZKP 设计定制 ASIC 需要大量资源,确保硬件的安全性以防止潜在的攻击也至关重要。此外,与 FPGA 不同,ASIC 一旦硬线设计,就会永久铭刻在芯片中。如果 ZKP 算法发生变化或需要更新,必须使用全新的 ASIC,原来的将无用。更不用说创建 ASIC 的 光掩膜成本↗ 通常在 200 万到 300 万之间。因此,ASIC 的开发成本目前使其对于 ZKP 来说变得 prohibitive。
一个例子是 Cysic↗,他们的方案基于 FPGA 和 ASIC。客户提交他们希望加速的 ZK 电路,然后 Cysic 为他们构建。通过不依赖 GPU,FPGA 和 ASIC 更快,从而在证明生成期间减少时间和资源的消耗。
现在让我们去我们的最后一站——ZK 虚拟机(zkVMs),也称为 zkCPUs。与上一个博客中的 zkEVMs 相比,zkVMs 是一个更广泛的概念,适用于任何二进制程序,使其在使用案例上更加灵活。zkVMs 运行预编译的二进制文件并生成可验证证明,证明该二进制文件正确运行。任何人都可以独立验证这一证明,而无需查看实际的输入、输出或计算过程中的中间值。
与 zkEVMs↗ 不同,zkVMs 也不是绑定于任何区块链。zkVMs 可用于不在以太坊上运行的通用目的。由于 zkVMs 以预编译的二进制文件作为输入,因此可以使用多种 编程语言↗,例如 Rust、C 和 C++,所有这些都是编译语言。考虑到 Solidity 开发往往成为瓶颈,能够接触更广泛的通用软件生态系统是一个重大好处。
在 zkVM 中,每条二进制指令与一个 R1CS 门相关联以进行验证检查。例如,在伪代码中,它可能看起来像这样:
如果指令是“add a, b”:
添加约束 c = add a,b
否则如果指令是“mul a, b”:
添加约束 c = mul a,b
然而,zkVMs 存在某些 局限性↗。由于每条指令的大量汇编指令和 R1CS 门,通常更适合较小且复杂度可控的二进制文件。运行较大和更复杂的程序可能在使用 zkVM 时不切实际或效率较低。对于较大的二进制文件,电路需要优化以允许快速 ZKP 生成。特定计算需要更优化的方法以防止在 zkVM 中的减速。
RISC Zero↗ 是为通用用途开发的 zkVM。在简单层面上,二进制文件作为输入,虚拟机提取每条汇编指令。例如,以下是 RISC Zero 中如何处理内存加载:

pub fn ram_load(&mut self, triple: &TripleWord) -> Result<bool> {
trace!("RAM_LOAD[{}]: {triple:?}", self.cycle);
self.start();
self.code[ControlIndex::RamLoad] = BabyBearElem::ONE;
self.code[ControlIndex::Info] = BabyBearElem::new(triple.addr);
(
self.code[ControlIndex::Data1Lo],
self.code[ControlIndex::Data1Hi],
) = split_word16(triple.data[0]);
(
self.code[ControlIndex::Data2Lo],
self.code[ControlIndex::Data2Hi],
) = split_word16(triple.data[1]);
(
self.code[ControlIndex::Data3Lo],
self.code[ControlIndex::Data3Hi],
) = split_word16(triple.data[2]);
self.next()
}
在提取了所有汇编指令后,它们一个接一个地运行,如下所列。在此过程中,将约束添加到主电路,证明程序的有效性。

pub fn body(&mut self) -> Result<()> {
debug!("BODY");
loop {
self.start();
self.code[ControlIndex::Body] = BabyBearElem::ONE;
if !self.next_fini(FINI_TAILROOM)? {
break;
}
}
Ok(())
}
而不是使用 zkSNARK,RISC Zero 使用的是包含四个处理阶段的 zkSTARK。阶段 1 本质上是承诺阶段。证明者在每一步后创建轨迹多项式,并将其提交到 Merkle 树。阶段 2 允许验证者验证多项式并发送 PLONK 混合参数,证明者利用这些参数生成 Merkle 根。阶段 3 和阶段 4 使用 DEEP-FRI 技术↗,这要求证明者提供除原始 Merkle 树承诺之外的多项式的值。当然,这是对 整个过程↗ 的大概描述。
这篇两部分的文章介绍了 ZKP 的基础知识——从 zkSNARKs 及其在 zkEVMs、ZK 编程语言和 zkBridges 中的应用,一直到 ZK 支付、ZK 硬件加速和 zkVMs。零知识的世界是一个广阔而迷人的世界,而我们才刚刚触及表面。
本指南可以用于启动对 ZKP 的进一步探索。ZKP 在确保区块链上交易的安全性和有效性,以及证明其他方面的知识方面变得越来越重要。随着 ZK 领域的不断发展和扩展,现实世界应用的潜力将呈指数增长。
特别感谢同事 Zellic 工程师 Mohit Sharma 给予的帮助和参与。
Zellic 专注于确保新兴技术的安全性。我们的安全研究人员在从《财富》500 强到 DeFi 巨头的最有价值目标中发现了漏洞。
开发者、创始人和投资者信任我们的安全评估,从而实现快速、无忧和没有重大漏洞的交付。凭借我们在现实世界攻防安全研究方面的背景,我们找到了其他人所忽视的东西。
联系我们↗ 以获得更优质的审计服务。真实的审计,不是走过场。
- 原文链接: zellic.io/blog/intro-to-...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!