1. 引言
后续博客:
- 如何选择ZK-friendly 哈希函数?
当暴露在ZK空间中时,对于普通crypto工程师来说,通常只需很少的时间就可以偶然发现一些外来的哈希函数——很可能是Poseidon。本文,将介绍ZK中高效哈希函数的历史,并解释为何不简单地使用现有已标准化哈希函数SHA-2/3。
也可参考:
- Dmitry Khovratovich——很多ZK-friendly哈希函数(包括Poseidon)的作者之一,在2022年10月的播客分享 Episode 250: What’s the Deal with Hash Functions?。
2. 为何需要Poseidon之类的哈希函数?
当前,许多ZK框架都基于Poseidon哈希函数实现,原因何在?
- membership proofs和Merkle tree commitments 对许多ZK应用场景至关重要。这两种情况下:
- 都需要使用Merkle tree来积累很多数据元素。
- 并使用ZKP系统来证明叶子节点到root的path。
- Merkle tree中每个节点的计算,正是基于某密码学哈希函数的哈希运算。
假设有Merkle tree中某叶子节点,并向使用SNARK或STARK证明其ownership。最终的ZK电路中包含多个哈希计算,直到到达该Merkle tree的root。随着Merkle tree的高度增加,生成proof的性能将高度依赖于所使用哈希函数的效率。这也是为何在ZK场景,没人用传统已标准化哈希函数(如SHA-256、SHA-3、Blake等)的原因。尽管这些传统已标准化哈希函数在现代CPU上运行非常快。
当前现状为:
- 大多数现代ZKP系统都基于更大素数域运算——如Halo2的256-bit、Plonky2的64-bit、Plonky3的31-bit,其性能开销通常与电路中的乘法运算相关。
- 对R1CS约束,通常仅关注乘法次数
- Plonkish系统porver开销随trace width、trace depth、transition多项式degree而增加,即也取决于电路的乘法复杂度。
传统哈希函数,通常基于位运算,而不是基于素数域元素运算的。这有两个重要的含义:
- 1)内部状态的哈希计算必须至少是256位的,在Plonkish表示中,这意味着large trace width,或large trace depth。
- 2)需要在ZKP的原生素数域中模拟二进制运算,将:
- 要求证明每个输入元素为a bit(即对每个bit证明 x ( x − 1 ) = 0 x(x-1)=0 x(x−1)=0)。
- 模拟AND/XOR,需要做乘法运算: x 1 a n d x 2 = x 3 ⇒ x 1 ⋅ x 2 = x 3 x_1\ \mathsf{and}\ x_2=x_3 \Rightarrow x_1 \cdot x_2=x_3 x1 and x2=x3⇒x1⋅x2=x3, x 1 x o r x 2 = x 3 ⇒ x 1 + x 2 – 2 ⋅ x 1 ⋅ x 2 = x 3 x_1\ \mathsf{xor}\ x_2=x_3 \Rightarrow x_1 + x_2 – 2\cdot x_1 \cdot x_2 = x_3 x1 xor x2=x3⇒x1+x2–2⋅x1⋅x2=x3。这将导致大量的乘法运算,从而导致large trace,最终导致prover性能非常低效。
因此,研究人员开发了新的哈希函数,这些新的经过优化的哈希函数,可在ZK证明系统中高效运行。这些哈希函数定义为直接基于素数域运算,从而抵消了上述缺点。此外,引入了额外的技术来最小化ZK电路中的乘法次数。因此现代ZK友好哈希函数可 以由少于100次的乘法来构建(如2022年论文 Horst Meets Fluid-SPN: Griffin for Zero-Knowledge Applications)。与仅证明传统哈希函数输入为bits(忽略实际哈希计算)相比,这已经大大减少了乘法运算次数。
广义来说,新的哈希函数可分为三大类:
- 1)Low-degree round functions 哈希函数:如MiMC、GMiMC、Poseidon、Poseidon2、Neptune。
- 2)“Low-degree equivalent” round functions 哈希函数:如Rescue、Rescue-Prime、Anemoi、Griffin、Grendel。
- 3)Lookup-based round functions 哈希函数:如Reinforced Concrete、Tip5、Monolith。
现有已标准化哈希函数SHA-2/3、Blake等,具有非常快的plain(电路外)哈希性能,但受限于其算术性质,在ZK电路内具有很高的开销。
- MiMC为首个实用 Low-degree round functions 的哈希函数,基于MiMC方向,后来有了Poseidon——相比于传统哈希函数,实现了在ZK电路内的性能飞跃。
- 后来,研究人员基于“Low-degree equivalent” round functions,进一步改进了电路内性能,从而有了Rescue、Rescue-Prime和Griffin。
- ZK电路内,Griffin比Poseidon更便宜,但Griffin在电路外的哈希开销更昂贵。
- 百万美元的问题是:能否得到与SHA-3或类似的速度,但仍能提高ZK电路内部开销的新哈希函数?
事实上,这个问题是有答案的!答案是肯定的——当ZKP证明系统支持lookup argument时。- Lookup-based round functions 哈希函数【愿SHA-3速度与你同在】
3. Low-degree round functions 哈希函数
Low-degree round functions 哈希函数,可看成是初代ZK友好哈希函数,起源于MiMC。
很多哈希函数,都基于MiMC和GMiMC构建,如:
- Poseidon
- Poseidon2
- Neptune
除依赖于 Low-degree round functions 之外,大多数通常都基于power map y = x d y=x^d y=xd 构建,其中 d d d 值取决于具体素数域, d d d值通常为 3 , 5 或 7 3,5或7 3,5或7。
Low-degree round functions 哈希函数:
- 每轮就有相对小数量的乘法运算次数
- 需要很多轮,以确保安全
总体来说,比基于bits运算的标准化哈希函数(如SHA-2)性能要好得多,且在做密码学分析攻击时,分析起来也相对直接。
4. “Low-degree equivalent” round functions 哈希函数
“Low-degree equivalent” round functions 哈希函数,基于如下发现:
- 在ZK电路中,不必直接对给定电路的约束系统进行建模。对不同的约束系统进行建模就足够了,当且仅当原始约束系统得到满足时,该约束系统才得到满足。
如:
- 假设电路计算 y = x 1 / d y=x^{1/d} y=x1/d,可直接构建某约束来直接证明 y = x 1 / d y=x^{1/d} y=x1/d。
- 另一种方法是证明 y = x 1 / d y=x^{1/d} y=x1/d的等价表示—— y d = x y^d=x yd=x。
- 若 d d d小,而素数域大时,则 1 / d 1/d 1/d是一个相当大的指数,需要进行多次乘法运算。但是, y d = x y^d=x yd=x为其equivalent constraint of low degree,适于在ZK电路中高效表示。
使用 y = x 1 / d y=x^{1/d} y=x1/d power map的设计:
- 相同的安全性,需要的轮数更少
- 相比于仅依赖Low-degree round functions 的哈希函数,通常在证明系统中具有更高效的表示。——这是重大利好,因为ZK友好哈希函数的设计目的之一,就是改进ZK电路内的性能。
但是“Low-degree equivalent” round functions 哈希函数 的这种改进是有代价的,当用于在电路外(将“电路外”,称为,plain)计算哈希时,必须直接计算 y = x 1 / d y=x^{1/d} y=x1/d,这比计算 y = x d y=x^{d} y=xd要慢得多。因此,基于“Low-degree equivalent” round functions 设计的哈希函数,其相对于,Low-degree round functions 哈希函数(如Poseidon),通常plain哈希性能要更慢。
遵循 “Low-degree equivalent” round functions 策略的哈希函数有:
- Rescue
- Rescue-Prime
- Anemoi
- Griffin
- Grendel:采用Legendre symbol,具有更低效的构建。
5. Lookup-based round functions 哈希函数
Lookup-based round functions 哈希函数,为第三代且最新的一类哈希函数,其遵循现代ZKP系统发展趋势,使用lookup tables来让计算更便宜。主要在于如下发现:
- 当基于大素数域运算时,可将域元素分解为更小的元素(如8-bit size),然后做table lookup,将结果组合回某域元素。
这种方法有多个优势:
- 1)table lookup在电路外是快速的,(当ZKP证明系统支持lookup argument时)在ZK电路内也相对便宜。
- 2)对应的安全性高——特别是应对algebraic attacks。因此仅需要少量轮数就行。
- 缺点在于,底层的证明系统必须支持lookup arguments,从而支持Lookup-based round functions 类型的哈希函数。
遵循Lookup-based round functions的:
- 首个哈希函数为:Reinforced Concrete:针对约256-bit大素数域做了高度优化。在电路外的性能相比其它ZK友好哈希函数要快得多,但相比于SHA-3来说仍然要慢得多。
- Tip5:基于Reinforced Concrete思想,但针对的是Plonky2中所使用的特殊64-bit素数域,而构建的哈希函数。
- Monolith:针对更通用的域(如同时适用于Plonky2的64-bit域,和Plonky3的31-bit域),为首个实现与SHA-3电路外性能相当的ZK友好哈希函数。
参考资料
[1] TACEO 2023年8月17日博客 What’s the deal with hash functions in Zero Knowledge?