zk-SNARKs 相关知识
Im3boxtech
,备注`进群`,我会拉你进入交流群。曲线知识
Pedersen 哈希
在 ZK 电路中,SHA256 是比较昂贵的计算电路,虽然他在 EVM 中具有内置计算方式,但是他的计算成本还是比较高的。所以,我们需要一个更加轻量级的哈希函数。
但是,Pedersen 哈希是一个特殊的哈希,他是通过 BabyJubJub 椭圆曲线来实现的。所以,我们在计算后得到的数据其实是椭圆函数上一个点的 Y 值附加一个 X 坐标符号,一般情况下,我们会使用unpack
函数来将这个点的值转换,并且只取 X 坐标的值作为哈希值。
BabyJubJub 椭圆曲线
ETH 中确实具有一个椭圆曲线函数,但是加入 BabyJubJub 的理由主要是因这个曲线函数更加对 ZK 电路友好。并且能完成很多 ZK 电路功能。
不过可惜的是,目前 ETH 并不原生支持 BabyJubJub 曲线。详细可以查看这个链接:https://eips.ethereum.org/EIPS/eip-2494 (opens in a new tab)
目前来看,只有在链下使用 BabyJubJub 曲线,然后将结果提交到链上。
同时,一半情况下,我们建议开发者使用 ZK 电路中对电路友好的内置函数,比如说,我们可以使用 pedersenHash
来代替 sha256
。这样做的目的主要是降低电路生成和验证成本,在同样的效果下达到最佳的性能。
证明模式
延展性攻击
所谓的延展性攻击,就是破坏了 ZK 对证明的确定性生成特性,比如说,我们可以通过一个证明来生成多个证明,这样就会导致我们的证明不再是确定性的,而是可以被重新生成的。
那么如果有程序使用了这个证明中 Proof 的某些值作为唯一校验,那么他就有被攻击的风险。比如,如果 Tornado Cash 使用了proof.a.x
作为 nullifier,那么攻击者就可以使用一个输入来生成多个证明,然后使用这些证明来进行攻击。
Groth16 和 GM17
Groth16 和 GM17 是两种不同的的证明模式,他们之间有少许区别,主要区别在于证明方式和曲线支持程度不同。主要区别在于。
链下计算:
- Groth16:
- 通常更快的证明生成时间。
- 参数设置(Trusted Setup)通常只需要进行一次,适用于多个证明。
- GM17:
- 相对于 Groth16,证明生成时间可能会稍长。
- 每个不同的电路通常需要自己的参数设置(Trusted Setup)。
链上费用(Gas 成本):
- Groth16:
- 通常需要更少的链上数据,因为 Groth16 的证明通常较小。
- 由于证明大小较小,因此链上验证的 gas 成本通常也较低。
- GM17:
- 相对于 Groth16,可能需要更多的链上数据。
- 由于证明通常较大,因此链上验证的 gas 成本可能会稍高。
适用场景:
- Groth16: 由于其高效性和较低的链上成本,Groth16 通常用于需要频繁生成和验证证明的应用。
- GM17: 由于其更灵活的参数设置,GM17 适用于需要多个不同电路的应用。
安全性:
- Groth16: 更容易受到延展性攻击的影响,因此可能需要额外的安全措施(如使用 nullifier)。
- GM17: 设计用于抵抗延展性攻击,但可能需要为每个不同的电路进行独立的参数设置。