# Ceno EVM Add Breakdown ## Overview The add opcode constraints can be divided into three parts: **main constraints**, **selection constraint**, and **product constraint**. ### Main constraints These constraints include computing uint addition and generating records. We use the notation `Uint<M, C>` to denote the total bit width is `M`, the bit width for each cell is `C`. - The program counter is denoted by `Uint<64, 32>`. - The stack value is denoted by `Uint<256, 16>`. - The timestamp is denoted by `Uint<48, 48>` #### Witnesses ``` // state updates - pc: 2 cells - ts: 1 cell - top: 1 cell - pc carry: 1 cell // stack operations - addend_0: 16 cells - addend_1: 16 cells - stack_ts_lt0: 3 cells - stack_ts_lt1: 3 cells // uint add - carry: 16 cells ``` #### State updates From `(pc, ts, top)` to `(pc + 1, ts + 1, top - 1)` $$ \begin{align} record_{lk0} &= \mathsf{RANGE} + r_0 \cdot 2^{15} \cdot carry_{pc} + r_1 \\ record_{r0} &= \mathsf{STATE} + r_0 \cdot pc[0] + r_0^2 \cdot pc[1] + r_0^3 \cdot ts + r_0^4 \cdot top + r_1 \\ record_{w0} &= \mathsf{STATE} + r_0 \cdot (pc[0] + 1 - 2^{32} \cdot carry_{pc}) + r_0^2 \cdot (pc[1] + carry_{pc}) \\ &+ r_0^3 \cdot (ts + 1) + r_0^4 \cdot (top - 1) + r_1 \end{align} $$ #### Bytecode check Check `(pc, ADD)` in the program. $$ \begin{align} record_{lk1} &= \mathsf{BYTECODE} + r_0 \cdot pc[0] + r_0^2 \cdot pc[1] + r_0^3 \cdot \mathsf{ADD} + r_1 \end{align} $$ #### Stack operations Check `0 <= top - 2 < 1024`. Suppose the previous timestamp is `old_stack_ts0` and `old_stack_ts1`, then `stack_ts_lt0 = ts - old_stack_ts0`, `stack_ts_lt1 = ts - old_stack_ts1`. Check `stack_ts_lt0` and `stack_ts_lt1` are within $[0..2^{48})$. Read `(top - 1, addend_0, ts - stack_ts_lt0)` and `(top - 2, addend_1, ts - stack_ts_lt1)` from the stack and push `(top - 2, addend_0 + addend_1, ts)` into the stack. $$ \begin{align} record_{lk2} &= \mathsf{RANGE} + r_0 \cdot 2^{6} \cdot (top - 2) + r_1 \\ record_{lk3} &= \mathsf{RANGE} + r_0 \cdot stack\_ts\_lt0[0] + r_1 \\ record_{lk4} &= \mathsf{RANGE} + r_0 \cdot stack\_ts\_lt0[1] + r_1 \\ record_{lk5} &= \mathsf{RANGE} + r_0 \cdot stack\_ts\_lt0[2] + r_1 \\ record_{lk6} &= \mathsf{RANGE} + r_0 \cdot stack\_ts\_lt1[0] + r_1 \\ record_{lk7} &= \mathsf{RANGE} + r_0 \cdot stack\_ts\_lt1[1] + r_1 \\ record_{lk8} &= \mathsf{RANGE} + r_0 \cdot stack\_ts\_lt1[2] + r_1 \\ record_{r1} &= \mathsf{STACK} + r_0 \cdot (top - 1) + r_0^2 \cdot addend_0[0] + \cdot + r_0^{17} \cdot addend_0[15] + r_0^{18} \cdot (ts - 2^{32} \cdot stack\_ts\_lt0[2] - 2^{16} \cdot stack\_ts\_lt0[1] - stack\_ts\_lt0[0]) + r_1 \\ record_{r2} &= \mathsf{STACK} + r_0 \cdot (top - 2) + r_0^2 \cdot addend_1[0] + \cdot + r_0^{17} \cdot addend_1[15] + r_0^{18} \cdot (ts - 2^{32} \cdot stack\_ts\_lt1[2] - 2^{16} \cdot stack\_ts\_lt1[1] - stack\_ts\_lt1[0]) + r_1 \\ record_{w1} &= \mathsf{STACK} + r_0 \cdot (top - 2) + r_0^2 \cdot (addend_0[0] + addend_1[0] - 2^{16} \cdot carry[0]) + \cdot + r_0^{17} \cdot (addend_0[15] + addend_1[15] - 2^{16} \cdot carry[15] + carry[14]) + r_0^{18} \cdot ts + r_1 \end{align} $$ #### Uint Check `(addend_0 + addend_1)[0..16]` are in $[0..2^{16})$. Check `carry[0..16]` are bits. $$ \begin{align} record_{lk9} &= \mathsf{RANGE} + r_0 \cdot (addend_0[0] + addend_1[0] - 2^{16} \cdot carry[0]) + r_1 \\ \vdots & \\ record_{lk24} &= \mathsf{RANGE} + r_0 \cdot (addend_0[15] + addend_1[15] - 2^{16} \cdot carry[15] + carry[14]) + r_1 \\ record_{lk25} &= \mathsf{RANGE} + r_0 \cdot 2^{15} \cdot carry[0] + r_1 \\ \vdots & \\ record_{lk40} &= \mathsf{RANGE} + r_0 \cdot 2^{15} \cdot carry[15] + r_1 \end{align} $$ ### Proving protocol (Suppose `inst_num_vars = 20`) #### Layer 0..21: Split and read / write / lookup $$ \begin{align} out_{lk\_d}(rt) &+ \\ \alpha_i out_{lk\_n}(rt) &+ \\ \alpha_i^2 out_r(rt) &+ \\ \alpha_i^3 out_w(rt) &= \sum_{b_s}eq(rt, b_s) \Big(in^{(0)}_{lk\_d}(b_s) \cdot in^{(1)}_{lk\_d}(b_s) \\ &+ \alpha_i \left(in^{(0)}_{lk\_d}(b_s) * in^{(1)}_{lk\_n}(b_s) + in^{(0)}_{lk\_n}(b_s) \cdot in^{(1)}_{lk\_d}(b_s)\right) \\ &+ \alpha_i^2 in^{(0)}_r(b_s) \cdot in^{(1)}_r(b_s) \\ &+ \alpha_i^3 in^{(0)}_w(b_s) \cdot in^{(1)}_w(b_s) \Big) \end{align} $$ Receive a randomness $r$ from the verifier. Let $rt' = [r] \| rs$, then $$ \begin{align} out'_{lk\_d}(rt') &= in^{(0)}_{lk\_d}(rs) + r \cdot (in^{(1)}_{lk\_d}(rs) - in^{(0)}_{lk\_d}(rs)) \\ out'_{lk\_n}(rt') &= in^{(0)}_{lk\_n}(rs) + r \cdot (in^{(1)}_{lk\_n}(rs) - in^{(0)}_{lk\_n}(rs)) \\ out'_r(rt') &= in^{(0)}_{r}(rs) + r \cdot (in^{(1)}_{r}(rs) - in^{(0)}_{r}(rs)) \\ out'_w(rt') &= in^{(0)}_{w}(rs) + r \cdot (in^{(1)}_{w}(rs) - in^{(0)}_{w}(rs)) \end{align} $$ Let $rt_w$ be the last `rt'`. #### Layer 21..22: Split and read / lookup $$ \begin{align} out_{lk\_d}(rt) &+ \\ \alpha_i out_{lk\_n}(rt) &+ \\ \alpha_i^2 out_r(rt) &= \sum_{b_s}eq(rt, b_s) \Big(in^{(0)}_{lk\_d}(b_s) \cdot in^{(1)}_{lk\_d}(b_s) \\ &+ \alpha_i in^{(0)}_{lk\_d}(b_s) * in^{(1)}_{lk\_n}(b_s) + in^{(0)}_{lk\_n}(b_s) \cdot in^{(1)}_{lk\_d}(b_s) \\ &+ \alpha_i^2 in^{(0)}_r(b_s) \cdot in^{(1)}_r(b_s) \Big) \end{align} $$ Receive a randomness $r_i$ from the verifier. Let $rt' = [r] || rs$, then $$ \begin{align} out'_{lk\_d}(rt') &= in^{(0)}_{lk\_d}(rs) + r \cdot (in^{(1)}_{lk\_d}(rs) - in^{(0)}_{lk\_d}(rs)) \\ out'_{lk\_n}(rt') &= in^{(0)}_{lk\_n}(rs) + r \cdot (in^{(1)}_{lk\_n}(rs) - in^{(0)}_{lk\_n}(rs)) \\ out'_r(rt') &= in^{(0)}_{r}(rs) + r \cdot (in^{(1)}_{r}(rs) - in^{(0)}_{r}(rs)) \end{align} $$ Let $rt_r$ be the last `rt'`. #### Layer 22..26: Split and lookup $$ \begin{align} out_{lk\_d}(rt) + \alpha_i out_{lk\_n}(rt) &= \sum_{b_s}eq(rt, b_s) \Big(in^{(0)}_{lk\_d}(b_s) \cdot in^{(1)}_{lk\_d}(b_s) \\ &+ \alpha_i in^{(0)}_{lk\_d}(b_s) * in^{(1)}_{lk\_n}(b_s) + in^{(0)}_{lk\_n}(b_s) \cdot in^{(1)}_{lk\_d}(b_s) \Big) \end{align} $$ Receive a randomness $r_i$ from the verifier. Let $rt' = [r] || rs$, then $$ \begin{align} out'_{lk\_d}(rt') &= in^{(0)}_{lk\_d}(rs) + r \cdot (in^{(1)}_{lk\_d}(rs) - in^{(0)}_{lk\_d}(rs)) \\ out'_{lk\_n}(rt') &= in^{(0)}_{lk\_n}(rs) + r \cdot (in^{(1)}_{lk\_n}(rs) - in^{(0)}_{lk\_n}(rs)) \end{align} $$ Let $rt_{lk}$ be the last `rt'`. #### Layer 26: Select layer $$ \begin{align} &out'_{lk\_d}(rt_{lk}) + \alpha_{26} \cdot out'_{lk\_n}(rt_{lk}) + \alpha_{26}^2 \cdot out'_r(rt_r) + \alpha_{26}^3 \cdot out'_w(rt_w) \\ &= \sum_{b_s} sel(rt_{lk}[6..], b_s) \Big(\sum_{i = 0}^{40} eq(rt_{lk}[..6], i) \cdot \big(record_{lki}(b_s) + \alpha_{26} \cdot 1 \big) + \sum_{i = 41}^{63} eq(rt_{lk}[..6], i) \cdot \big(1 + \alpha_{26} \cdot 0 \big) \Big) \\ &+ \sum_{b_s} \Big(eq(rt_{lk}[6..], b_s) - sel(rt_{lk}[6..], b_s)\Big) \cdot \Big(1 + \alpha_{26} \cdot 0 \Big) \\ &+ \alpha_{26}^2 \cdot \sum_{b_s}sel(rt_r[2..], b_s) \cdot \Big(\sum_{i = 0}^2 eq(rt_r[..2], i) record_{ri}(b_s) + \sum_{i = 3}^3 eq(rt_r[..2], i)\Big) \\ &+ \alpha_{26}^2 \cdot \sum_{b_s}\Big(eq(rt_r[2..],b_s) - sel(rt_r[2..], b_s)\Big) \cdot 1 \\ &+ \alpha_{26}^3 \cdot \sum_{b_s}sel(rt_w[1..], b_s) \cdot \Big(\sum_{i = 0}^1 eq(rt_w[..1], i) record_{wi}(b_s)\Big) \\ &+ \alpha_{26}^3 \cdot \sum_{b_s}\Big(eq(rt_w[1..],b_s) - sel(rt_w[1..], b_s)\Big) \cdot 1 \end{align} $$ After reorganizing the equation: $$ \begin{align} &out'_{lk\_d}(rt_{lk}) + \alpha_{26} \cdot out'_{lk\_n}(rt_{lk}) + \alpha_{26}^2 \cdot out'_r(rt_r) + \alpha_{26}^3 \cdot out'_w(rt_w) - (1 + \alpha_{26}^2 + \alpha_{26}^3) \\ &= \sum_{b_s} sel(rt_{lk}[6..], b_s) \Big(\sum_{i = 0}^{40} eq(rt_{lk}[..6], i) record_{lki}(b_s) + \sum_{i = 41}^{63} eq(rt_{lk}[..6], i) + \alpha_{26} \cdot \sum_{i = 0}^{40} eq(rt_{lk}[..6], i) - 1 \Big) \\ &+ \alpha_{26}^2 \cdot \sum_{b_s}sel(rt_r[2..], b_s) \cdot \Big(\sum_{i = 0}^2 eq(rt_r[..2], i) record_{ri}(b_s) + \sum_{i = 3}^3 eq(rt_r[..2], i) - 1\Big) \\ &+ \alpha_{26}^3 \cdot \sum_{b_s}sel(rt_w[1..], b_s) \cdot \Big(\sum_{i = 0}^1 eq(rt_w[..1], i) record_{wi}(b_s) - 1\Big) \end{align} $$ #### Final layer: Main body $$ \begin{align} &\sum_{i = 0}^{40}\alpha_{27}^i \cdot record_{lki}(rt) + \sum_{i = 0}^{2}\alpha_{27}^{i + 41} \cdot record_{ri}(rt) + \sum_{i = 0}^{1}\alpha_{27}^{i + 44} \cdot record_{wi}(rt) \\ &= \mathsf{RANGE} + r_0 \cdot 2^{15} \cdot carry_{pc}(rt) + r_1 \\ &+ \alpha_{27} \cdot (\mathsf{BYTECODE} + r_0 \cdot pc[0](rt) + r_0^2 \cdot pc[1](rt) + r_0^3 \cdot \mathsf{ADD} + r_1) \\ &+ \alpha_{27}^2 \cdot (\mathsf{RANGE} + r_0 \cdot 2^{6} \cdot (top(rt) - 2) + r_1) \\ &+ \alpha_{27}^3 \cdot(\mathsf{RANGE} + r_0 \cdot stack\_ts\_lt0[0](rt) + r_1) \\ &+ \alpha_{27}^3 \cdot(\mathsf{RANGE} + r_0 \cdot stack\_ts\_lt0[1](rt) + r_1) \\ &+ \alpha_{27}^5 \cdot(\mathsf{RANGE} + r_0 \cdot stack\_ts\_lt0[2](rt) + r_1) \\ &+ \alpha_{27}^6 \cdot(\mathsf{RANGE} + r_0 \cdot stack\_ts\_lt1[0](rt) + r_1) \\ &+ \alpha_{27}^7 \cdot(\mathsf{RANGE} + r_0 \cdot stack\_ts\_lt1[1](rt) + r_1) \\ &+ \alpha_{27}^8 \cdot (\mathsf{RANGE} + r_0 \cdot stack\_ts\_lt1[2](rt) + r_1) \\ &+ \sum_{i = 9}^{24} \alpha_{27}^i \cdot (\mathsf{RANGE} + r_0 \cdot (addend_0[i - 9](rt) + addend_1[i - 9](rt) - 2^{16} \cdot carry[i - 9](rt)) + r_1) + \sum_{i = 10}^{24} \alpha_{27}^i r_0 carry[i - 10](rt)\\ &+ \sum_{i = 25}^{40} \alpha_{27}^i \cdot (\mathsf{RANGE} + r_0 \cdot 2^{15} \cdot carry[i - 25](rt) + r_1) \\ &+ \alpha_{27}^{41} \cdot (\mathsf{STATE} + r_0 \cdot pc[0](rt) + r_0^2 \cdot pc[1](rt) + r_0^3 \cdot ts(rt) + r_0^4 \cdot top(rt) + r_1) \\ &+ \alpha_{27}^{42} \cdot (\mathsf{STACK} + r_0 \cdot (top(rt) - 1) + r_0^2 \cdot addend_0[0](rt) + \cdot + r_0^{17} \cdot addend_0[15](rt) + r_0^{18} \cdot (ts(rt) - 2^{32} \cdot stack\_ts\_lt0[2](rt) - 2^{16} \cdot stack\_ts\_lt0[1](rt) - stack\_ts\_lt0[0](rt)) + r_1) \\ &+ \alpha_{27}^{43} \cdot (\mathsf{STACK} + r_0 \cdot (top(rt) - 2) + r_0^2 \cdot addend_1[0](rt) + \cdot + r_0^{17} \cdot addend_1[15](rt) + r_0^{18} \cdot (ts(rt) - 2^{32} \cdot stack\_ts\_lt1[2](rt) - 2^{16} \cdot stack\_ts\_lt1[1](rt) - stack\_ts\_lt1[0](rt)) + r_1) \\ &+ \alpha_{27}^{44} \cdot (\mathsf{STATE} + r_0 \cdot (pc[0](rt) + 1 - 2^{32} \cdot carry_{pc}(rt)) + r_0^2 \cdot (pc[1](rt) + carry_{pc}(rt)) + r_0^3 \cdot (ts(rt) + 1) + r_0^4 \cdot (top(rt) - 1) + r_1) \\ &+ \alpha_{27}^{45} \cdot (\mathsf{STACK} + r_0 \cdot (top(rt) - 2) + r_0^2 \cdot (addend_0[0](rt) + addend_1[0](rt) - 2^{16} \cdot carry[0]) + \cdot + r_0^{17} \cdot (addend_0[15](rt) + addend_1[15](rt) - 2^{16} \cdot carry[15](rt) + carry[14](rt)) + r_0^{18} \cdot ts(rt) + r_1) \end{align} $$ After reorganizing the equation: $$ \begin{align} &\sum_{i = 0}^{40}\alpha_{27}^i \cdot record_{lki}(rt) + \sum_{i = 0}^{2}\alpha_{27}^{i + 41} \cdot record_{ri}(rt) + \sum_{i = 0}^{1}\alpha_{27}^{i + 44} \cdot record_{wi}(rt) \\ &- \mathsf{BYTECODE} - r_0^3\mathsf{ADD} - (\sum_{i = 1}^{40}\alpha_{27}^i) \mathsf{RANGE} - (\alpha_{27}^{41} + \alpha_{27}^{44}) \mathsf{STATE} - (\alpha_{27}^{42} + \alpha_{27}^{43} + \alpha_{27}^{45})\mathsf{STACK} - (\sum_{i = 0}^{45}\alpha_{27}^i)r_1 + r_0(2^{7}\alpha_{27}^2 + \alpha_{27}^{42} + 2\alpha_{27}^{43} + 2\alpha_{27}^{45} - \alpha_{27}^{44}) + r_0^4\alpha_{27}^{44} \\ &= r_0(1 + \alpha_{27}^{41} + \alpha_{27}^{44}) \cdot pc[0](rt) \\ &+ r_0^2(1 + \alpha_{27}^{41} + \alpha_{27}^{44}) \cdot pc[1](rt)\\ &+ (r_0^3(\alpha_{27}^{41}+ \alpha_{27}^{44}) + r_0^{18}(\alpha_{27}^{42} + \alpha_{27}^{43} + \alpha_{27}^{45})) \cdot ts(rt) \\ &+ (r_0(2^6 \alpha_{27}^{2} + \alpha_{27}^{42} + \alpha_{27}^{43} + \alpha_{27}^{45}) + r_0^4(\alpha_{27}^{41} + \alpha_{27}^{44})) \cdot top(rs) \\ &+ (r_0 (2^{15} \alpha_{27} - 2^{32} \alpha_{27}^{44}) + r_0^2(\alpha_{27}^{44})) \cdot carry_{pc}(rt) \\ &+ \sum_{i = 0}^{15}(r_0\alpha_{27}^{9 + i} + r_0^{2 + i}(\alpha_{27}^{42} + \alpha_{27}^{45})) \cdot addend_0[i](rt) \\ &+ \sum_{i = 0}^{15}(r_0\alpha_{27}^{9 + i} + r_0^{2 + i}(\alpha_{27}^{43} + \alpha_{27}^{45})) \cdot addend_0[i](rt) \\ &+ \sum_{i=0}^{14}(r_0(\alpha_{27}^{10 + i} - 2^{16}\alpha_{27}^{9 + i} + 2^{15}\alpha_{27}^{25 + i}) - r_0^{2 + i}2^{16} \alpha_{27}^{45} + r_0^{3 + i}\alpha_{27}^{45}) carry[i](rt) \\ &+ (r_0(- 2^{16}\alpha_{27}^{9 + i} + 2^{15}\alpha_{27}^{25 + i}) - r_0^{2 + i}2^{16} \alpha_{27}^{45}) carry[15](rt) \\ \end{align} $$ ## Time consuming (outdated) ### Binary tree | num_vars | prover time | setup (time before sumcheck) | |-------------------------|--------------|------------------------------| | **prove split and product** | | | | 0 | 1.821ms | 23.200µs | | 1 | 342.451µs | 56.780µs | | 2 | 424.292µs | 40.410µs | | 3 | 508.262µs | 45.700µs | | 4 | 566.923µs | 55.400µs | | 5 | 668.973µs | 45.280µs | | 6 | 868.954µs | 58.760µs | | 7 | 834.033µs | 66.300µs | | 8 | 1.094ms | 82.361µs | | 9 | 1.561ms | 169.661µs | | 10 | 2.086ms | 248.871µs | | 11 | 2.537ms | 409.291µs | | 12 | 1.712ms | 358.852µs | | 13 | 2.835ms | 493.372µs | | 14 | 3.032ms | 646.133µs | | 15 | 4.011ms | 1.130ms | | 16 | 5.030ms | 1.563ms | | 17 | 8.301ms | 2.993ms | | 18 | 13.419ms | 5.224ms | | 19 | 23.927ms | 10.524ms | | 20 | 43.387ms | 20.724ms | | 21 | 86.262ms | 43.771ms | | 22 | 155.693ms | 76.566ms | | 23 | 288.990ms | 140.764ms | | 24 | 534.614ms | 263.226ms | | 25 | 1.038s | 523.181ms | | **prove select** | | | | 20 | 1.523s | 1.507s | | **total** | **4.309640456s** | | ### 4-ary tree | num_vars | prover time | setup (time before sumcheck) | |-------------------------|--------------|------------------------------| | **prove split and product** | | | | 0 | 1.745ms | 20.710µs | | 2 | 755.783µs | 46.320µs | | 4 | 945.794µs | 51.760µs | | 6 | 1.161ms | 59.290µs | | 8 | 1.787ms | 88.181µs | | 10 | 2.250ms | 253.031µs | | 12 | 2.708ms | 341.651µs | | 14 | 5.322ms | 1.217ms | | 16 | 7.650ms | 1.754ms | | 18 | 19.357ms | 5.608ms | | 20 | 64.324ms | 21.960ms | | 22 | 226.425ms | 78.134ms | | 24 | 786.492ms | 262.881m | | **prove select** | | | | 20 | 1.483s | 1.467s | | total | 3.044195178s | |