Aztec's zk2-Rollup
Suyash Bagad
UTXO vs Account

Aztec Model

20

Bob

Alice
Open account

bob

alice

8


2



10


10

0.5


1.5



18


2
10

Shield
Rollup Contract


Account UTXO
Value UTXO
Private sends
zkETH=8.5
zkDAI=18
zkETH=1.5
zkDAI=2
Withdraw
0
1.5

Aztec Notes
- Account balances are calculated by adding up the available UTXOs
- UTXOs are called as notes: Account notes and Value notes
- State transition in UTXO model is tricky
- A user creates an account on zk.money using an alias and a nonce n∈Z232
- We compute an account identifier as:
- Account information is stored in account notes
Account PK
Account id
Spending PK1

aid ∈ Z232
S1 ∈ G1
A ∈ G1
Account PK
Account id
Spending PK2

aid ∈ Z232
S2 ∈ G
A ∈ G1
aid:=(n ∥ HB(suyashbagad)[ 0:224 ])∈Z2256
- Spending keys are used for signing transactions
Aztec Notes
- Aztec uses value notes as a basis for private transactions on Ethereum

Value
Asset id
Nonce

Owner
Secret
a ∈ Z232
A ∈ G1
n ∈ Z232
v ∈ Fq
s ∈ Fq
- A value note is given as: V={a,v,n,O,s}
- The nonce here is same as the one used in an account note
- A note incorporates the on-chain identity (i.e. account PK) of its owner
- The secret s is the hiding factor in computing Pedersen commitment to a note:
Demo
- Creating an account using alias arcanatest
- Shielding 0.1 ETH, sending some ETH privately trial→test
- Client-side proof generation: n=32000 circuit size
- Plonk proof data: nullifiers and data entry
- Before delving into circuits, we'll discuss some prelims
Arithmetic Circuit
- A typical computational problem: find solutions to the equation (i.e. stmt)
x12⋅x2+x1+1=22
- Witness: w≡(x1=3,x2=2), public inputs: ℓ≡(c=1,z=22)
- I can convince you that I know a solution w to {stmt,ℓ} without revealing w
- PLONK: Circuit size: n=4, prover: O(n⋅logn), proof size and verifier: O(1)
Data Tree
- D is size 232 Merkle tree which supports batch updates
- Contains commitments to all account and value notes ever created in Aztec
- Suppose we wish to add A1,A2,V1,V2 to D
Data Tree
- Old data root: Dold,
C(A1)
C(A2)
C(V1)
C(V2)
D
New data root: Dnew
Data Tree
- Old data root: Dold,
- With subtree root S and the partial proof {h1,h2}, we can verify:
C(A1)
C(A2)
C(V1)
C(V2)
D
New data root: Dnew
S
h1
h2
Dnew=?H(h2,H(S,h1))
Nullifier Tree
- N is size 2256 sparse Merkle tree which supports non-membership proofs
- To prove that a note is unspent, we need to give a non-membership proof
- Suppose we have 16 leaf values {A,B,…,P} s.t. idx(A)=1 and so on
- To prove J∈/T, a membership proof (10,ϕ,πmerkle) suffices!
A
F
N
Account Circuit
- Let's look at an example of account migration
- New account notes must have same alias but different nonce
- Need to track the old and new account notes!
- Check if the old notes actually exist in the data tree: C(A1,old), C(A2,old)∈D
- Add old note nullifiers to the nullifier tree: N⟵N(aid, old)
- Add new note commitments to the data tree: D⟵{C(A1,new), C(A2,new)}
- Check the validity of signature σ(aid, old,Aold,Anew,S1,old,S2,old)
- If not migrating, set nnew=nold and check Aold=Anew

aid, new
S1,new
Anew

aid, old
S2,new
Anew
A2,new
A1,new

aid, old
S1,old
Aold
A1,old

aid, old
S2,old
Aold
A2,old
Join-Split Circuit
- A join-split transaction spends two input notes and creates two new output notes
V1in={a1in,v1in,n1in,A1in,s1in}
V2in={a2in,v2in,n2in,A2in,s2in}
V1out={a1out,v1out,n1out,A1out,s1out}
V2out={a2out,v2out,n2out,A2out,s2out}
- A join-split transaction must obey the following:
- Asset ids must match: a1in=a2in=a1out=a2out=:a
- Input note owners must match: A1in=A2in
- Input note nonces match: n1in=n2in=n
- Amounts are balanced: v1in+v2in=v1out+v2out+ tx_fee
- Range constraints: tx_fee≤2242,a≤232
Join-Split Circuit
- A join-split transaction spends two input notes and creates two new output notes
V1in={a1in,v1in,n1in,A1in,s1in}
V2in={a2in,v2in,n2in,A2in,s2in}
V1out={a1out,v1out,n1out,A1out,s1out}
V2out={a2out,v2out,n2out,A2out,s2out}
- State transition constraints
- Input notes must be present in the data tree: C(V1in),C(V2in)∈D
- Input notes are not already spent: N(V1in),N(V2in)∈/N
- Nullify the input notes to avoid double-spending: N⟵N(V1in),N(V2in)
- Output notes are added to the data tree: D⟵C(V1out),C(V2out)
Recursive Proof Verification
- A Plonk proof π is verified by checking equality of polynomial evaluations
π={G12w+3[a]1,[b]1,[c]1,[z]1,[t0]1,[t1]1,[t2]1,[Wz]1,[Wzω]1, Fp2waˉ,bˉ,cˉ,zˉω,sˉσ1,sˉσ2}
Wz(x)⋅(x−z)=F1(x)−F1(z)
Wzω(x)⋅(x−zω)=F2(x)−F2(zω)
Wz(x)⋅(x−z)+u⋅(Wzω(x)⋅(x−zω))=F1(x)−F1(z)+u⋅(F2(x)−F2(zω))
Recursive Proof Verification
- A Plonk proof π is verified by checking equality of polynomial evaluations
π={G12w+3[a]1,[b]1,[c]1,[z]1,[t0]1,[t1]1,[t2]1,[Wz]1,[Wzω]1, Fp2waˉ,bˉ,cˉ,zˉω,sˉσ1,sˉσ2}
Wz(x)⋅(x−z)=F1(x)−F1(z)
Wzω(x)⋅(x−zω)=F2(x)−F2(zω)
Wz(x)⋅(x−z)+u⋅(Wzω(x)⋅(x−zω))=F1(x)−F1(z)+u⋅(F2(x)−F2(zω))
P0(Wz(x)+uWzω(x))⋅x=P1(zWz(x)+uzωWzω(x))+F(x)−E)
P0⋅x=?P1
Recursive Proof Verification
- Suppose we have n Plonk proofs (π1,π2,…,πn) with verification equations:
P0(i)⋅x=?P1(i)∀i∈[n]
(P0(1)+qP0(2)+⋯+ qn−1P0(n))⋅x=?(P1(1)+qP1(2)⋯+qn−1P1(n))
- A single pairing is ≈300 times costlier than a scalar multiplication
- Using recursive verification, we can verify any number of Plonk proofs using a single pairing
- Too good to be true? The circuit size presents a practical constraint on the number of proofs to be rolled up
- Failure of the recursive check implies at least one of the n proofs is wrong
DeFi Bridge
v1in=1
A=0xF5C...17
n=15,s=0x8C...2

v2in=0.5
A=0xF5C...17
n=15,s=0x8C...2

v1out=4500
A=0xF5C...17
n=15,s=0x8C...2

v2out=0.15
A=0xF5C...17
n=15,s=0x8C...2

DeFi Bridge
v1in=1
A=0xF5C...17
n=15,s=0x8C...2

v2in=0.5
A=0xF5C...17
n=15,s=0x8C...2

v1out=4500
A=0xF5C...17
n=15,s=0x8C...2

v2out=0.15
A=0xF5C...17
n=15,s=0x8C...2

d=1.5
nd=4
P=H(A,n,s)

DeFi Deposit
DeFi Claim
Claim Note
v1=0.4

v2=0.8

d1=1.2

v3=1

v4=0.1

d2=1.1

v5=0.05

v6=0.15

d3=0.2

v7=0.3

v8=0.1

d4=0.4

v9=0.2

v10=0.6

d5=0.8

din=3.7
nd=4

in
out
vout,1=11,100
vout,2= 0.37



+
DeFi Interaction Note
v1=3600

v2=0.12

v3=3300

v4=0.11

v5=600

v6=0.02

v7=1200

v8=0.04

v9=2400

v10=0.08

DeFi Bridge
Takeaways
- Aztec uses UTXO model (recall Hermez was account-based)
- Modern zkSNARKs are very powerful
- Allow one to prove complicated statements at low costs
- DSLs like Noir and Cairo make it easy for developers to write circuits
- No need to understand the moon-math to build apps
- Privacy at low costs for decentralised finance, NFTs, DAOs
- Aztec connect supports any application that can be modelled as async swap
- Single rollup provider as of today, will take time to decentralise
Aztec zk-zk-Rollup
By Suyash Bagad
Aztec zk-zk-Rollup
- 145