Rollup Circuit in Aztec 3

March 22, 2023

Recap: Private Functions

/**
  * L2 Contract
  *
  * Name: Ping
  * Contract Address: 0xbd28a63...
  *
**/

// Computes p^2 + 4p - 3
fn A(p: i32, q: u64) -> i64 {

    // Calls B from another contract (pong)
    let p_sq: u64 = pong::B(p);
    
    // Calls C from another contract (pong)
    let p_four: u64 = pong::C(u64::from(p), 4);
    
    // Calls D twice from the same contract
    let temp: i64 = D(i64::from(p_sq), p_four);  
    let result: i64 = D(temp, i64::from(-3));
    return result;
}

// Computes q + r
fn D(q: i64, r: i64) -> i64 {
    return (q + r);
}
/**
  * L2 Contract
  *
  * Name: Pong
  * Contract Address: 0xae4821f...
  *
**/

// Computes p^2
fn B(p: i32) -> u64 {
    let p_: u64 = u64::from(p);
    return u64::pow(p_, 2);
}

// Computes q * r
fn C(q: u64, r: u8) -> u64 {
    return (q * r);
}
A \rightarrow \textsf{pong}(B) \rightarrow \textsf{pong}(C) \rightarrow D \rightarrow D
p
4
-3
\textsf{out}
A

Recap: Call Stack

B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})

\(\ast\)

B

\(+\)

D

\(\ast\)

C

\(+\)

D

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_{\textsf{mock}}
\pi_A
\pi_1

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_1

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_1
\pi_B
\pi_2

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_2

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_2

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_2
\pi_C
\pi_3

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_3

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_3

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_3
\pi_D
\pi_4

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_4

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_4

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_4
\pi_D
\pi_5

Recap: Private Kernel Circuit

A(\textcolor{orange}{p})
B(\textcolor{orange}{p})
C(\textcolor{orange}{p, 4})
D(\textcolor{orange}{p^2, 4p})
D(\textcolor{orange}{p',-3})
K

\(V\)

\(V\)

\text{MMC}
\pi_5

Final Private Kernel Proof

  • Private kernel circuit hides private function execution
  • The final proof is sent to the transaction pool
  • The Sequencer then picks it up and starts rolling up multiple proofs

Recursive Verification

bool verify(proof π) {
    auto pa = compute_pa(π);    // cost: 70, uses G1 MSM op 
    auto pb = compute_pb(π);    // cost: 10, uses G1 MSM op
    bool res = (pa == pb * x);  // cost: 900, uses pairing op
    return res;
}
bool verify(proof π₁, proof π₂) {
    auto pa₁ = compute_p0(π₁, vk_1);    // cost: 70
    auto pb₁ = compute_p1(π₁, vk_1);    // cost: 10
    auto pa₂ = compute_p0(π₂, vk_2);    // cost: 70
    auto pb₂ = compute_p1(π₂, vk_2);    // cost: 10
    
    auto pa = pa₁ + u * pa₂;      // Aggregate pa's
    auto pb = pb₁ + u * pb₂;      // Aggregate pb's
    
    bool res = (pa₁ == pb₁ * x);  // cost: 900
    return res;
}
\underbrace{\hspace{3.6cm}}{}
\underbrace{\hspace{6cm}}{}
1 \times \pi \approx 1000
2 \times \pi \approx 1100

Recursive Verification

bool verify(proof π₁, proof π₂, ..., proof πₘ) {

    auto pa = 0, pb = 0;              // initialise
    for(i = 0; i < m; i++) {
    	auto paᵢ = compute_p0(πᵢ);    // cost: 70%
    	auto pbᵢ = compute_p1(πᵢ);    // cost: 10%
        pa += uᵢ * paᵢ;               // aggregate pa
        pb += uᵢ * pbᵢ;               // aggregate pb
    }
    return (pa, pb);                  // returns aggregated object
}
  • One pairing for multiple proofs \(\rightarrow\) can save \(\$\$\$\)
  • Computing \(P_a, P_b\) can be done in a circuit!
\pi \longrightarrow \textsf{aggregate\_circuit}(\pi) \longrightarrow \pi_{\textsf{agg}}

Base Rollup Circuit

\(V\)

\textsf{aggr}
\textsf{aggr}

\(V\)

\textsf{vk}_{\textsf{kernel}}
\pi_{1}
(P_{a}, P_{b })
\pi_{2}
(P_{a}, P_{b })
(\vec{n}, \vec{c}, \vec{d})
(T_{\textsf{old}}, T_{b\textsf{new}})
(\vec{n}, \vec{c}, \vec{d})
(T_{\textsf{old}}, T_{b\textsf{new}})
(p_{a}, p_{b })
(p_{a}, p_{b })
(P_{a}, P_{b })
\textsf{aggr}
\textsf{merkle}
\textsf{merkle}
\textsf{sha256}
H_{\textsf{PI}}

Merge Rollup Circuit

\(V\)

\textsf{aggr}
\textsf{aggr}

\(V\)

\textsf{vk}_{\textsf{base}}
\pi_{1}
(P_{a}, P_{b })
\pi_{2}
(P_{a}, P_{b })
H_{\textsf{PI}}
H_{\textsf{PI}}
(p_{a}, p_{b })
(p_{a}, p_{b })
(P_{a}, P_{b })
\textsf{aggr}
\textsf{sha256}
H_{\textsf{PI}}

Rolling Up

\pi_{1}
\pi_{2}
\pi_{3}
\pi_{4}
\pi_{5}
\pi_{6}
\pi_{7}
\pi_{8}

Private kernel proofs

\underbrace{\hspace{9.6cm}}{}

Tx proofs

Base rollup

Merge rollup

Merge rollup

  • We roll only 2 proofs / circuit,
  • Circuit sizes \(\approx 1M\)
  • Easily run even on macbooks
  • Helps decentralisation

Root Rollup Circuit

\pi_{1}
\pi_{2}
\pi_{3}
\pi_{4}
\pi_{5}
\pi_{6}
\pi_{7}
\pi_{8}
  • Final merge rollup proof can be submitted to L1
  • But verifying a Honk proof would be too expensive: \(\frac{\text{cost}}{\text{tx}}\) go brrr
  • Need to down-step from Honk to Plonk to reduce verification costs

Honk

Ultra

Std

\pi_{\textsf{final}}
/**
 * @title Rollup Processor
 * @dev Smart contract responsible for processing Aztec zkRollups, 
 *      including relaying them to a verifier
 *      contract for validation and performing 
 *.     all relevant ERC20 token transfers
 */
contract RollupProcessor is IRollupProcessor, Decoder, Ownable, Pausable {
    using SafeMath for uint256;

    bytes32 public dataRoot = 0x2708a627...;
    bytes32 public nullRoot = 0x2694dbe3...;
    bytes32 public rootRoot = 0x2d264e93...;
    ...
    ...
    ...
}

Aztec 3 Rollup Circuit

By Suyash Bagad

Aztec 3 Rollup Circuit

A brief presentation on the planned rollup circuit in Aztec 3.0.

  • 92