... | ... | @@ -22,10 +22,87 @@ EVM的复杂性决定了电路的证据和约束将会非常复杂,进而决 |
|
|
|
|
|
## 子电路
|
|
|
|
|
|
详细阐述其代码接口。包括
|
|
|
我们团队根据halo2的代码设计以及zkEVM的开发需要,定义了以下接口作为子电路的接口。上文所述的子电路(Core、State等等)均实现此接口,并通过接口并入最终的“超级电路(Super Circuit)”中。下面详细阐述其代码接口。
|
|
|
|
|
|
SubCircuitConfig
|
|
|
### SubCircuitConfig
|
|
|
```rust
|
|
|
/// SubCircuit configuration
|
|
|
pub trait SubCircuitConfig<F: Field> {
|
|
|
/// Config constructor arguments
|
|
|
type ConfigArgs;
|
|
|
|
|
|
SubCircuit
|
|
|
/// Type constructor
|
|
|
fn new(meta: &mut ConstraintSystem<F>, args: Self::ConfigArgs) -> Self;
|
|
|
}
|
|
|
```
|
|
|
此接口包含new方法:新建column和建约束(即`configure()`的内容要在此方法里)。ConfigArgs是外界传进来的column,这些传进来的column就不必新建了。
|
|
|
|
|
|
未完待续 |
|
|
\ No newline at end of file |
|
|
那么,一个结构体`MyConfig`要实现此接口,一般其成员就要包括此子电路所使用的所有column。同时,此结构体一般还需要一些函数来帮助以后的分配数值(可选)。例如`assign_row`将具体数值填入所有column的一行。
|
|
|
|
|
|
### SubCircuit
|
|
|
|
|
|
```rust
|
|
|
/// SubCircuit is a circuit that performs the verification of a specific part of
|
|
|
/// the full Ethereum block verification. The SubCircuit's interact with each
|
|
|
/// other via lookup tables and/or shared public inputs. This type must contain
|
|
|
/// all the inputs required to synthesize this circuit (and the contained
|
|
|
/// table(s) if any).
|
|
|
pub trait SubCircuit<F: Field> {
|
|
|
/// Configuration of the SubCircuit.
|
|
|
type Config: SubCircuitConfig<F>;
|
|
|
|
|
|
/// Cells that need to use permutation constraints.
|
|
|
type Cells;
|
|
|
|
|
|
/// Create a new SubCircuit from witness
|
|
|
fn new_from_witness(witness: &Witness) -> Self;
|
|
|
|
|
|
/// Returns the instance columns required for this circuit.
|
|
|
fn instance(&self) -> Vec<Vec<F>> {
|
|
|
vec![]
|
|
|
}
|
|
|
|
|
|
/// Assign only the columns used by this sub-circuit. This includes the
|
|
|
/// columns that belong to the exposed lookup table contained within, if
|
|
|
/// any; and excludes external tables that this sub-circuit does lookups
|
|
|
/// to. Return the cells that need to use permutation constraints.
|
|
|
fn synthesize_sub(
|
|
|
&self,
|
|
|
config: &Self::Config,
|
|
|
layouter: &mut impl Layouter<F>,
|
|
|
) -> Result<Self::Cells, Error>;
|
|
|
|
|
|
/// Number of rows before and after the actual witness that cannot be used, which decides that
|
|
|
/// the selector cannot be enabled
|
|
|
fn unusable_rows() -> (usize, usize);
|
|
|
|
|
|
/// Return the number of rows required to prove the witness.
|
|
|
/// Only include the rows in witness and necessary padding, do not include padding to 2^k.
|
|
|
fn num_rows(witness: &Witness) -> usize;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
此接口是为了负责EVM的特定一部分的子电路而设计的。
|
|
|
|
|
|
- `type Config`设置为上述的`MyConfig`
|
|
|
- `Cells`设置为要使用permutation约束的格子,目前为空`()`即可
|
|
|
- `new_from_witness(witness: &Witness)`创建一个新的子电路,输入是Witness,即证据,是一个包含所有电路输入的大表格。
|
|
|
- `instance`返回此电路所需的公开列的具体数值
|
|
|
- `synthesize_sub`对此子电路进行synthesize操作,即分配值给子电路的格子。会返回`Cells`供permutation约束使用
|
|
|
- `unusable_rows`开始和最后不可用的行数,例如有约束要找前1行,那第一行就是不可用的,因为第一行再找前1行就找到错误的行数了。
|
|
|
- `num_rows`统计一共要用多少行
|
|
|
|
|
|
那么,一个结构体`MyCircuit`要实现此接口,一般其成员就包括一份Witness,其包括整张大表格,内含所有数值。需要注意的是,此结构体不包含`MyConfig`以及任何column,这是halo2的一种设计。
|
|
|
|
|
|
### 组合成为超级电路SuperCircuit
|
|
|
|
|
|
1. `SuperCircuitConfig`结构体包括所有子电路的config结构体
|
|
|
2. `SuperCircuit`结构体包括所有子电路的结构体
|
|
|
3. 为`SuperCircuit`实现halo2的`Circuit`接口,重点是两个方法:`configure`和`synthesize`。
|
|
|
1. `configure`,即建立所需column和约束,只需依次调用子电路的构造函数new,然后将构造的所有子电路的config结构体组成`SuperCircuitConfig`返回。
|
|
|
2. `synthesize`,即分配值给子电路,只需依次调用子电路的方法synthesize_sub即可。
|
|
|
|
|
|
### 总结
|
|
|
重点是
|
|
|
1. SubCircuitConfig的new,其包含了设置约束的configure功能。
|
|
|
2. SubCircuit的synthesize_sub,其包含了分配值的synthesize功能。 |
|
|
\ No newline at end of file |