Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
zkevm-circuits
zkevm-circuits
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Package Registry
  • Analytics
    • Analytics
    • CI / CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar

新注册的用户请输入邮箱并保存,随后登录邮箱激活账号。后续可直接使用邮箱登录!

  • zkp
  • zkevm-circuitszkevm-circuits
  • Wiki
    • Zkevm docs
  • 8 arithmetic

8 arithmetic · Changes

Page history
feat: add ariethmetic doc authored Nov 28, 2023 by liuxingxing1's avatar liuxingxing1
Hide whitespace changes
Inline Side-by-side
Showing with 155 additions and 0 deletions
+155 -0
  • zkevm-docs/8-arithmetic.markdown zkevm-docs/8-arithmetic.markdown +155 -0
  • No files found.
zkevm-docs/8-arithmetic.markdown
View page @ b6e0dc8c
# 布局
arithmetic 子电路的设计包含如下几列。我们重点关注 operand*与 u16*列,
```rust
pub struct ArithmeticCircuitConfig<F> {
// TODO use table to let core lookup
q_enable: Selector,
// arithmetic table for lookup starts
tag: BinaryNumberConfig<Tag, 3>, //todo not use 3
cnt: Column<Advice>,
operand0_hi: Column<Advice>,
operand0_lo: Column<Advice>,
operand1_hi: Column<Advice>,
operand1_lo: Column<Advice>,
operand2_hi: Column<Advice>,
operand2_lo: Column<Advice>,
operand3_hi: Column<Advice>,
operand3_lo: Column<Advice>,
// arithmetic table for lookup ends
u16_0: Column<Advice>,
u16_1: Column<Advice>,
u16_2: Column<Advice>,
u16_3: Column<Advice>,
u16_4: Column<Advice>,
u16_5: Column<Advice>,
u16_6: Column<Advice>,
u16_7: Column<Advice>,
cnt_is_zero: IsZeroWithRotationConfig<F>,
}
pub enum Tag {
#[default]
Nil,
Add,
Addmod,
Mul,
Mulmod,
Lt,
Gt,
Slt,
Sgt,
Sub,
DivMod,
}
```
在这里 tag 我们使用了一个电路小工具“BinaryNumberConfig/BinaryNumberChip”。关于 BinaryNumberChip,详见[here](../code-notes/binary_number_with_real_selector.rs的内容和用法.markdown)。
## 列的含义
operand* 用来存放算术中的参数值,如 a+b=c+overflow 指令中的 a,b,c,overflow。u16*用来 lookup 算术中的输出如 c_hi,c_lo 属于 u128 范围。这里我们只需要保证输出值的 lookup 就好。cnt 记录某个具体算术指令的行计数器,从正数开始递减到 0。
# 约束
在 arithmetic 子电路中约束可以分为两类。
通用约束
- 约束 cnt 除零行外,当前行与下一行差值为 1
不同 Tag 对应的约束不同
- Add(在表中使用两行)
- 如果是 0 行,则 cnt_prev=1,cnt_prev_prev=0
- c_lo = u16 sum(rotation cur)
- c_hi = u16 sum(rotation prev)
- carry hi is bool
- carry lo is bool
- c lo + carry lo \* 2^128 = a lo + b lo
- c hi + carry hi \* 2^128 = a hi + b hi + carry lo
- Sub_Lt_Gt (a+b=c+overflow\*2^256) (可以使用 select struct)
- 如果是 0 行,则 cnt_prev=1,cnt_prev_prev=0
- carry hi is bool
- carry lo is bool
- c lo + carry lo \* 2^128 = a lo + b lo
- c hi + carry hi \* 2^128 = a hi + b hi + carry lo
- if tag is sub 有 c_lo = u16 sum(rotation cur),c_hi = u16 sum(rotation prev) and carry_hi iszero
- if tag is lt 则有 carry_hi iszero
- if tag is gt 则有 carry_hi 1
- Div_Mod
- Mul
- Slt_Sgt
- Sdiv_Smod
- Addmod
- Mulmod
# 实现 arithmetic 子电路中 Add 例子
如果我们希望为某一个 tag 实现它的约束,我们需要实现 OperationGadget,然后在 config 方法中实现 tag 对应的约束就好。
```rust
pub(crate) trait OperationGadget<F: Field> {
const NAME: &'static str;
const TAG: Tag;
const NUM_ROW: usize;
fn constraints(
config: &OperationConfig<F>,
meta: &mut VirtualCells<F>,
) -> Vec<(&'static str, Expression<F>)>;
}
impl<F: Field> OperationGadget<F> for AddGadget<F> {
const NAME: &'static str = "Arithmetic Circuit Add";
const TAG: Tag = Tag::Add;
const NUM_ROW: usize = 2;
fn constraints(
config: &OperationConfig<F>,
meta: &mut VirtualCells<F>,
) -> Vec<(&'static str, Expression<F>)> {
let mut constraints = vec![];
let a_hi = meta.query_advice(config.operand0_hi, Rotation::cur());
...
let carry_lo = meta.query_advice(config.operand3_lo, Rotation::cur());
let u16_0_for_c_lo = meta.query_advice(config.u16_0, Rotation::cur());
...
let u16_7_for_c_lo = meta.query_advice(config.u16_7, Rotation::cur());
let u16_sum_for_c_lo = expr_from_u16s(&[
u16_0_for_c_lo,
...
u16_7_for_c_lo,
]);
let u16_0_for_c_hi = meta.query_advice(config.u16_0, Rotation::prev());
...
let u16_7_for_c_hi = meta.query_advice(config.u16_7, Rotation::prev());
let u16_sum_for_c_hi = expr_from_u16s(&[
u16_0_for_c_hi,
...
u16_7_for_c_hi,
]);
constraints.push(("c lo = u16 sum", c_lo.clone() - u16_sum_for_c_lo));
constraints.push(("c hi = u16 sum", c_hi.clone() - u16_sum_for_c_hi));
constraints.push((
"carry hi is bool",
carry_hi.clone() * (1.expr() - carry_hi.clone()),
));
constraints.push((
"carry lo is bool",
carry_lo.clone() * (1.expr() - carry_lo.clone()),
));
constraints.push((
"c lo + carry lo * 2^128 = a lo + b lo",
c_lo + carry_lo.clone() * pow_of_two::<F>(128) - a_lo - b_lo,
));
constraints.push((
"c hi + carry hi * 2^128 = a hi + b hi + carry lo",
c_hi + carry_hi * pow_of_two::<F>(128) - a_hi - b_hi - carry_lo,
));
constraints
}
}
```
Clone repository
  • basics
    • evm
    • halo2
  • code notes
    • binary_number_with_real_selector
    • how to use macro
    • simple_lt
    • simple_lt_word
  • Home
  • image
  • zkevm docs
    • 1 introduction
    • 10 public
    • 11 fixed
    • 12 exp
    • 13 keccak
    • 14 comparisons
    • 15 differences
View All Pages

Copyright © 2024 ChainWeaver Org. All Rights Reserved. 版权所有。

京ICP备2023035722号-3

京公网安备 11010802044225号