Poseidon 在 Stylus 上加速:通过 Arbitrum 上的 Rust 实现,密码学函数的 Gas 效率提高 18 倍

本文介绍了在 Arbitrum Stylus 上优化 Poseidon 哈希函数的 Rust 实现,通过 Montgomery 形式、预计算参数、WASM 优化等手段,实现了比 Solidity 实现更低的 gas 成本,提高了零知识证明等密码学应用在链上的效率,并提供了一个与 Solidity 实现的 gas 成本对比。

介绍

Arbitrum Stylus 为密码学应用提供了显著的优势,特别是在降低计算密集型智能合约的 gas 成本方面。正如宣传的那样,它能够高效地执行密码学原语,使其成为开发高级密码学开发者的一个有吸引力的构建模块。

其中一种密码学原语是 Poseidon 哈希函数。Poseidon 是一种为零知识证明 (zk-proofs) 优化的哈希函数。它经过专门设计,可以高效地进行字段运算,并且由于其最小的约束,当在 zk 友好的电路中实现时,非常适合 zk-proofs。

历史上,Poseidon 在 EVM 链上的智能合约中的使用非常有限,因为用 Solidity 编写该算法的 gas 成本过高——但今天这种情况发生了改变。正如你将在下面看到的那样,我们优化的 Rust 实现比流行的 Solidity 实现便宜多达 18 倍。

实现概述

我们不会深入探讨 Poseidon 置换的数学细节,因为你始终可以在其官方参考中找到更多信息。但在这里我们将指出一些重要的观察结果,我们认为这些观察结果对于使用 Stylus 进行高效的 Poseidon 哈希和密码学至关重要。

模乘的昂贵性

Poseidon 置换在很大程度上依赖于模算术运算。其中一些,例如模乘,非常昂贵,因为它们需要额外除以模数。除法本质上比乘法更昂贵,从而导致这些操作的总体开销很高。根据官方的opcode 定价表,Stylus VM 对每次除法的收费明显高于乘法。这种成本使得优化对于实际应用至关重要。

使用 Montgomery 形式进行乘法运算

Montgomery 形式是一种表示形式,允许在不直接进行除法运算的情况下执行模乘。通过将数字转换为 Montgomery 形式,昂贵的除法运算被更具成本效益的算术步骤(如乘法和加法)所取代。这可以显著减少计算开销并提高性能。

预计算参数

常量 RR2INV 对于约简以及数字与 Montgomery 形式之间的转换至关重要。在运行时计算这些常量可能非常昂贵。如果在编译时知道模数,则可以在 Rust 中预先计算这些常量。因此,我们消除了不必要的开销,并确保了最佳性能。

优化

让我们从 Poseidon 的基本实现开始,它将 Montgomery 参数的常量计算外包给 Rust 的编译时。我们的执行成本为 86.952 gas,WASM 大小为 8.6 KB。这已经是一个非常好的结果了,但我们可以做得更好。

WASM 乘法

涉及 64 位整数乘法的运算在 WebAssembly 中比涉及 128 位整数的运算便宜得多。通过将 64 位整数乘法(溢出到 128 位)表示为四个 64 位整数乘法,我们可以实现 75.082 的 gas 执行成本,或比以前便宜 14%。此优化将 WASM 大小减少了 0.1 KB。

函数内联

函数调用在 CPU 上(尤其是在 Stylus VM 上)并非没有代价。内联是一种可以用函数内容替换函数调用 opcode 的优化。一些内联由 rust 编译器自动完成,其他内联(尤其是那些会膨胀二进制文件大小的内联)需要显式定义。在频繁调用的函数上应用 Rust 的 #[inline]#[inline(always)] 属性可以显著降低 Stylus 智能合约的 gas 成本。在我们的例子中,我们获得了 46.194 gas 的执行成本,或成本降低了 38%。这种优化是 WASM 大小和 gas 成本之间的权衡,在我们的例子中,它使 WASM 二进制文件增加了大约 0.3KB

展开热循环

循环控制指令有时可能很昂贵。能够删除循环或展开循环以用于频繁执行的操作(例如大整数的乘法和加法)在理论上会有所帮助。在 rust 中,可以使用宏来展开循环,而不会过多地损害代码可读性。更新后的模算术为 Poseidon 带来了新的结果:每次执行 28.392 gas。与上一个版本相比,它再次提高了 39%。不幸的是,这使二进制文件大小膨胀了 1.0 KB,但考虑到 gas 节省,这仍然是一个值得的权衡。现在我们的合约重达 ****WebAssembly 的 9.8 KB

缓存合约

完成与代码相关的优化后,我们可以使用 Stylus 缓存 WASM 合约。它允许在没有冷启动的情况下调用频繁使用的合约。强制我们的合约缓存在 dev nitro 节点上,我们已经可以看到令人惊叹的新结果:15.148 执行价格,额外 47% 的改进。此改进对 WASM 大小没有任何影响。

WASM 优化

之前的优化是在源代码级别进行的,但我们也可以对 WASM 本身进行一些技巧来帮助降低成本。如果你听说过 WebAssembly 优化器,那么 wasm-opt 工具可能很熟悉。对“速度”进行积极的 WASM 优化为 Poseidon 开辟了新的视野,并产生了额外的 22% gas 改进。现在执行的 gas 成本低至 11.887。与其他优化不同,没有“二进制大小权衡”。WASM 大小现在为 9.6KB,减少了 0.2KB

与 Solidity 实现的比较

正如本文开头提到的那样,EVM 链中 Poseidon 的一个限制因素是昂贵的 gas 成本。

现在我们将我们优化的实现与一些流行的 Solidity 替代方案进行比较,正如你所看到的,收益非常显著。与某些 Solidity 汇编 (Yul) 实现相比,Rust 实现更具可读性和可审核性(因此可以说更安全)。

下表比较了 Poseidon 哈希的 gas 成本,以两个 256 位整数作为参数。哈希在 bn256 字段上运行,状态大小为 3。这确保了仅调用一次 Poseidon 置换。所有实现都具有相同的度和相同数量的参数。为了清晰起见和公平比较,省略了每次 EVM 交易 21000 的基本 gas 费用。

Poseidon 实现 Gas 执行成本 观察
Solidity 实现 220244 简单的实现,gas 成本高,适合安全审计。
Yul 实现 19313 针对 EVM 执行进行了优化,难以自定义、读取和审核。
openzeppelin-crypto 中的 Rust 实现 11887 高效,零不安全代码,可自定义。

使用汇编 (Yul) 实现的 Poseidon,包含大约 350 行汇编代码,比使用 不安全 代码的 Rust 实现 贵 62%

与优化的 Rust 实现相比,简单的 Solidity 实现虽然比汇编实现更简单且更易于审计,但成本高出约 18 倍

meme

结论

Arbitrum Stylus 为在链上运行高度优化的密码学原语(如 Poseidon 哈希)提供了一个绝佳的环境。与传统的 Solidity 实现相比,开发人员可以显著降低 gas 成本,并使他们的密码学变得非常廉价。这种效率使 Stylus 成为基于 zk-proof 的应用程序和其他性能关键型密码学系统的引人注目的选择。

Stylus 实现的另一个巨大优势是,它也可以被 Arbitrum One 和其他 Orbit 链中的 Solidity 合约使用。只需要部署一次 WASM 实现。该链上的所有合约都可以像调用任何其他合约一样调用它。

虽然我们的实现尚未准备好投入生产,但我们邀请你尝试并在开发中使用它,直到它通过审计并可以放心地投入生产。

我们仍然可以探索一些可以使 Poseidon 更加高效的优化,并且我们的积压工作中还有其他密码学原语,例如 Pedersen 哈希和椭圆曲线。如果你是一个在 Arbitrum 上构建的项目,并且需要高度优化的密码学原语,请联系我们的团队或在我们的 repo 中提出问题。

  • 原文链接: openzeppelin.com/news/po...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
OpenZeppelin
OpenZeppelin
江湖只有他的大名,没有他的介绍。