#circuit #fixed-length #byte-array #virtual #hash #keccak #virtual-machine

nightly axiom-eth

此crate是构建证明有关以太坊虚拟机(EVM)数据的ZK电路的主要库。

4个版本

0.4.3 2024年4月30日
0.4.2 2024年3月18日
0.4.1 2024年3月12日
0.4.0 2024年1月21日

#fixed-length类别中排名第22

Download history 124/week @ 2024-04-25 29/week @ 2024-05-02 7/week @ 2024-05-09 30/week @ 2024-05-16 24/week @ 2024-05-23 13/week @ 2024-05-30 23/week @ 2024-06-06 41/week @ 2024-06-13 37/week @ 2024-06-20 23/week @ 2024-06-27 18/week @ 2024-07-04 13/week @ 2024-07-11 29/week @ 2024-07-18 6/week @ 2024-07-25 18/week @ 2024-08-01

每月下载量68
5个crate(3个直接)使用

MIT许可

780KB
16K SLoC

axiom-eth

此crate是构建证明有关以太坊虚拟机(EVM)数据的ZK电路的主要库。

模块

原语

此crate的其余部分大量使用以下原语

  • halo2-base 特别是 BaseCircuitBuilderLookupAnyManager
  • rlc:在此crate中,我们引入了一种新的自定义门,这是一种垂直门(1个建议列,1个选择列),使用3次旋转。这在 PureRlcConfig 中。我们将 BaseCircuitBuilder 扩展到支持此门,在 RlcCircuitBuilder 中。 RlcCircuitBuilder 是此crate中其余部分使用的核心电路构建器。
  • keccak:keccak哈希在EVM中扮演着非常重要的角色,因此在此crate的芯片中得到了大量使用。 keccak模块包含一个 适配器 KeccakChip,用于收集固定长度或可变长度字节数组的keccak哈希请求。需要注意的是,KeccakChip 显式约束这些keccak哈希的计算。哈希摘要以 未约束 的证据形式返回。这些哈希的验证取决于使用 KeccakChip 的具体 Circuit 实现。为此,我们现在讨论此crate中的 Circuit 实现。

Circuit 实现方法

此crate有三个主要的Halo2 Circuit trait实现方法

  • RlcKeccakCircuitImpl:这是最直接的电路实现。它创建了一个独立的电路,其中包含由RlcCircuitBuilder管理的子电路以及一个普通的zkEVM keccak子电路。由KeccakChip收集的keccak调用直接与zkEVM keccak子电路的输出表进行约束。通过实现EthCircuitInstructions来创建这样的电路。
  • EthCircuitImpl:这创建了一个包含RlcCircuitBuilder管理的子电路的电路。此外,它加载一个keccak散列(及其输入)表作为私有证人,并以公输出形式输出表的一个Poseidon散列。由KeccakChip收集的keccak调用在keccak散列表中动态查找。通过实现EthCircuitInstructions来创建这样的电路。需要注意的是,由该电路生成的证明尚未完全验证:加载的keccak表必须通过约束表 Poseidon 散列等于KeccakComponentShardCircuit的公输出来验证,该电路实际上证明表的正确性。这必须通过聚合电路来完成。
  • ComponentCircuitImpl:这是组件框架的一部分。更多详情请参阅那里。请注意,EthCircuitImpl的实现实际上是ComponentCircuitImpl的一个专用版本,因为它使用相同的PromiseLoaderPromiseCollector模式。

数据结构

  • rlp:此模块定义了RlpChip,它大量使用RLC来证明RLP(递归长度前缀)序列化的正确编码/解码。
  • mpt:此模块定义了MPTChip,它使用rlpkeccak来证明Merkle Patricia Trie(MPT)中节点的包含和排除证明。

Ethereum执行层(EL)芯片

  • block_header:证明将RLP编码的块头部(作为字节)分解为块头部字段。还通过keccak散列块头部来计算块哈希。
  • storage:证明账户证明进入状态trie和存储证明进入存储trie。
  • transaction:证明将RLP编码的交易包含在交易trie中。还提供了从交易中提取特定字段的功能。
  • receipt:证明将RLP编码的收据包含在收据trie中。还提供了从收据中提取特定字段的功能。
  • solidity:证明与一系列Solidity映射键对应的原始存储槽。

电路构建器

这是一个抽象概念,我们不会将其编码为顶级特质。这个crate在halo2-base的基础上构建,特别是使用虚拟区域管理器。在这个框架中,电路使用电路构建器编写,这是一个虚拟区域管理器的集合。电路构建器拥有一组原始Halo2列和自定义门,但将电路本身的逻辑存储在某些虚拟状态中。然后,电路构建器可以根据这个虚拟状态进行自动配置或优化,然后将原始列和门选择器分配给原始Halo2电路。

因此,对于Halo2 Challenge API的每个阶段,编写电路有两个步骤

  • 指定电路构建器内部虚拟区域的分配
  • 将原始列和门选择器分配给原始Halo2电路

在这个包中,我们大量使用了随机线性组合(RLC),它需要两个阶段:阶段0和阶段1。阶段0对应于原始Halo2中的FirstPhase结构体,阶段1对应于SecondPhase结构体。由于阶段1中虚拟分配的正确计算需要挑战值,阶段1的虚拟分配必须在阶段0之后进行。具体来说,这意味着不能提前完全预填充电路构建器中所有虚拟区域。相反,必须在收到挑战值后指定一个函数来完成虚拟分配。

上述内容推动了本模块中核心特质的定义,例如CoreBuilderPromiseBuilder。这些特质指定了函数变体的接口

  • virtual_assign_phase0
  • raw_synthesize_phase0
  • virtual_assign_phase1
  • raw_synthesize_phase1

这四个函数都在原始Halo2的Circuit::synthesize特质实现中依次调用,阶段0列在raw_synthesize_phase0virtual_assign_phase1之间提交,以便从virtual_assign_phase1开始可用挑战值。(另一个技术区别是,virtual_assign_*可以在没有Layouter的情况下调用,用于任何预计算目的。)

大多数情况下,一个电路构建器可以用于不同的电路实现:raw_synthesize_*逻辑保持不变,只需指定virtual_assign_*指令,就可以快速编写新的电路。

阶段0有效载荷

阶段0的结果/数据也需要传递到阶段1以“继续计算”。理想情况下,会使用Rust闭包来自动推断这些数据在阶段之间传递。然而,由于一些编译器限制/可能的不可稳定性,我们选择要求从阶段0到阶段1传递的所有数据都显式地声明在某种Payload结构体中。这些应始终视为闭包的显式实现。

组件框架

请参阅README

依赖关系

~18–38MB
~640K SLoC