ZK 系列
zk-SNARKs 相关知识

zk-SNARKs 相关知识

文章作者: @BoxMrChen (opens in a new tab),欢迎转载,转载请注明出处。
文章 Github 仓库: https://github.com/nishuzumi/blog (opens in a new tab)欢迎Star。如果文章有误,欢迎提PR。
进入交流群:欢迎添加个人微信 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 是两种不同的的证明模式,他们之间有少许区别,主要区别在于证明方式和曲线支持程度不同。主要区别在于。

链下计算:

  1. Groth16:
  • 通常更快的证明生成时间。
  • 参数设置(Trusted Setup)通常只需要进行一次,适用于多个证明。
  1. GM17:
    • 相对于 Groth16,证明生成时间可能会稍长。
    • 每个不同的电路通常需要自己的参数设置(Trusted Setup)。

链上费用(Gas 成本):

  1. Groth16:
  • 通常需要更少的链上数据,因为 Groth16 的证明通常较小。
  • 由于证明大小较小,因此链上验证的 gas 成本通常也较低。
  1. GM17:
  • 相对于 Groth16,可能需要更多的链上数据。
  • 由于证明通常较大,因此链上验证的 gas 成本可能会稍高。

适用场景:

  • Groth16: 由于其高效性和较低的链上成本,Groth16 通常用于需要频繁生成和验证证明的应用。
  • GM17: 由于其更灵活的参数设置,GM17 适用于需要多个不同电路的应用。

安全性:

  • Groth16: 更容易受到延展性攻击的影响,因此可能需要额外的安全措施(如使用 nullifier)。
  • GM17: 设计用于抵抗延展性攻击,但可能需要为每个不同的电路进行独立的参数设置。