Intro to PLONKish/halo2
0xPARC Halo2 Learning Group
13 Jun 2022
arithmetisation
polynomial commitment scheme
accumulation scheme
arithmetisation
polynomial commitment scheme
accumulation scheme
satisfying witness
relation
low-degree polynomial
PLONKish arithmetisation
polynomial commitment scheme
accumulation scheme
satisfying witness
relation
low-degree polynomial
deep dive: 22 Jun
PLONKish arithmetisation
polynomial commitment scheme
accumulation scheme
satisfying witness
relation
low-degree polynomial
commitment opening proof
commit to polynomial, and provably evaluate it at arbitrary points
PLONKish arithmetisation
inner product argument
accumulation scheme
satisfying witness
relation
low-degree polynomial
commitment opening proof
commit to polynomial, and provably evaluate it at arbitrary points
PLONKish arithmetisation
inner product argument
accumulation scheme
satisfying witness
relation
low-degree polynomial
commitment opening proof
commitment opening proof
Θ(log d) accumulator size; amortised Θ(d) final check cost
PLONKish arithmetisation
inner product argument
accumulation scheme
satisfying witness
relation
low-degree polynomial
commitment opening proof
commitment opening proof
Θ(log d) accumulator size; amortised Θ(d) final check cost
PLONKish arithmetisation
PLONK [GWC19]
PLONKish arithmetisation (vanilla)
PLONK [GWC19]
+
⨉
w0[0]
w1[0]
w1[1]
w0[1]
w2[1]
w2[0]
PLONKish arithmetisation (vanilla)
PLONK [GWC19]
+
⨉
w0[0]
w1[0]
w1[1]
w0[1]
w2[1]
w2[0]
"local" consistency check: are all gate equations satisfied?
PLONKish arithmetisation (vanilla)
PLONK [GWC19]
+
⨉
w0[0]
w1[0]
w1[1]
w0[1]
w2[1]
w2[0]
"local" consistency check: are all gate equations satisfied?
qL·xa + qR·xb + qO·xc + qM·(xaxb) = 0
PLONKish arithmetisation (vanilla)
PLONK [GWC19]
+
⨉
w0[0]
w1[0]
w1[1]
w0[1]
w2[1]
w2[0]
"local" consistency check: are all gate equations satisfied?
qL·xa + qR·xb + qO·xc + qM·(xaxb) = 0
preprocessed selector polynomials
PLONKish arithmetisation (vanilla)
PLONK [GWC19]
+
⨉
w0[0]
w1[0]
w1[1]
w0[1]
w2[1]
w2[0]
"local" consistency check: are all gate equations satisfied?
add: 1·xa + 1·xb + (-1)·xc + 0·(xaxb) = 0
qL·xa + qR·xb + qO·xc + qM·(xaxb) = 0
PLONKish arithmetisation (vanilla)
PLONK [GWC19]
+
⨉
w0[0]
w1[0]
w1[1]
w0[1]
w2[1]
w2[0]
"local" consistency check: are all gate equations satisfied?
add: 1·xa + 1·xb + (-1)·xc + 0·(xaxb) = 0
mul: 0·xa + 0·xb + (-1)·xc + 1·(xaxb) = 0
qL·xa + qR·xb + qO·xc + qM·(xaxb) = 0
PLONKish arithmetisation (custom gates)
TurboPLONK [GW19]
vanilla PLONK gate: qL·xa + qR·xb + qO·xc + qM·(xaxb) = 0
qadd·(a0 + a1 - a2) = 0
add gate
custom gates (arbitrary linear combinations):
PLONKish arithmetisation (custom gates)
TurboPLONK [GW19]
vanilla PLONK gate: qL·xa + qR·xb + qO·xc + qM·(xaxb) = 0
qadd·(a0 + a1 - a2) + qmul·(a0 · a1 - a2) = 0
add gate
mul gate
custom gates (arbitrary linear combinations):
PLONKish arithmetisation (custom gates)
TurboPLONK [GW19]
vanilla PLONK gate: qL·xa + qR·xb + qO·xc + qM·(xaxb) = 0
qadd·(a0 + a1 - a2) + qmul·(a0 · a1 - a2) + qbool·(a0·a0 - a0) = 0
add gate
mul gate
bool gate
custom gates (arbitrary linear combinations):
PLONKish arithmetisation (custom gates)
TurboPLONK [GW19]
vanilla PLONK gate: qL·xa + qR·xb + qO·xc + qM·(xaxb) = 0
custom gates (arbitrary linear combinations):
verifier challenge to keep gates linearly independent
qadd·(a0 + a1 - a2) + y ·qmul·(a0 · a1 - a2) + y2· qbool·(a0·a0 - a0) = 0
add gate
mul gate
bool gate
PLONKish arithmetisation (permutation)
PLONK [GWC19]
+
⨉
w0[0]
w1[0]
w1[1]
w0[1]
w2[1]
w2[0]
PLONKish arithmetisation (permutation)
PLONK [GWC19]
+
⨉
w0[0]
w1[0]
w1[1]
w0[1]
w2[1]
w2[0]
"global" consistency check: do the wires correctly join the gates together?
* in Groth16, routing is baked into the trusted setup; we can't do this for universal SNARKs
PLONKish arithmetisation (permutation)
PLONK [GWC19]
w0 | w1 | w2 | gate |
w0[0] | w1[0] | w2[0] | + |
w0[1] | w1[1] | w2[1] | ⨉ |
each wire (column i) is encoded as a Lagrange polynomial wi over the powers (rows) of an nth root of unity {1, ⍵, …,⍵n-1}, where ⍵n = 1:
wi(⍵j) = wi[j]
PLONKish arithmetisation (permutation)
PLONK [GWC19]
w0 | w1 | w2 | gate |
w0[0] | w1[0] | w2[0] | + |
w0[1] | w1[1] | w2[1] | ⨉ |
each wire (column i) is encoded as a Lagrange polynomial wi over the powers (rows) of an nth root of unity {1, ⍵, …,⍵n-1}, where ⍵n = 1:
wi(⍵j) = wi[j]
to enforce equality of wires, use permutation argument (deep-dive); show that swapping w2(⍵0) with w0(⍵1) doesn't change the polynomials.
PLONKish arithmetisation (lookup)
w0 | w1 |
42 | SHA(42) |
0 | 0 |
69 | SHA(69) |
… | … |
0 | 0 |
UltraPLONK [halo2]
problem: SHA is expensive to do in-circuit
PLONKish arithmetisation (lookup)
w0 | w1 | qlookup | t0 | t1 |
42 | SHA(42) | 1 | 0 | SHA(0) |
0 | 0 | 0 | 1 | SHA(1) |
69 | SHA(69) | 1 | 2 | SHA(2) |
… | … | … | … | … |
0 | 0 | 0 | 255 | SHA(255) |
UltraPLONK [halo2]
solution: load precomputed SHA (e.g. for 8-bit values) as lookup table
PLONKish arithmetisation (lookup)
w0 | w1 | qlookup | t0 | t1 |
42 | SHA(42) | 1 | 0 | SHA(0) |
0 | 0 | 0 | 1 | SHA(1) |
69 | SHA(69) | 1 | 2 | SHA(2) |
… | … | … | … | … |
0 | 0 | 0 | 255 | SHA(255) |
UltraPLONK [halo2]
(qlookup·w0, t0)
(qlookup·w1, t1)
PLONKish arithmetisation (lookup)
w0 | w1 | qlookup | t0 | t1 |
42 | SHA(42) | 1 | 0 | SHA(0) |
0 | 0 | 0 | 1 | SHA(1) |
69 | SHA(69) | 1 | 2 | SHA(2) |
… | … | … | … | … |
0 | 0 | 0 | 255 | SHA(255) |
UltraPLONK [halo2]
(qlookup·w0 + (1 - qlookup)·0, t0)
(qlookup·w1 + (1 - qlookup)·SHA(0), t1)
lookup default value when qlookup is not enabled, so that lookup argument passes on every row
PLONKish arithmetisation (lookup)
w0 | w1 | qlookup | t0 | t1 |
42 | SHA(42) | 1 | 0 | SHA(0) |
0 | 0 | 0 | 1 | SHA(1) |
69 | SHA(69) | 1 | 2 | SHA(2) |
… | … | … | … | … |
0 | 0 | 0 | 255 | SHA(255) |
UltraPLONK [halo2]
the lookup argument is a more permissive version of the permutation argument. it enforces that:�
every cell in a set of input columns is equal to� some cell in a set of table columns
PLONKish arithmetisation (lookup)
w0 | w1 | qlookup | t0 | t1 |
42 | SHA(42) | 1 | 0 | SHA(0) |
0 | 0 | 0 | 1 | SHA(1) |
69 | SHA(69) | 1 | 2 | SHA(2) |
… | … | … | … | … |
0 | 0 | 0 | 255 | SHA(255) |
UltraPLONK [halo2]
the lookup argument is a more permissive version of the permutation argument. it enforces that:�
every expression in a set of input columns is equal to� some expression in a set of table columns
more on this in the deep-dive!
PLONKish arithmetisation
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
we conceptualise the circuit as a matrix of m columns and n rows
PLONKish arithmetisation
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
we conceptualise the circuit as a matrix of m columns and n rows,�over a given finite field 𝔽 (so the cells contain elements of 𝔽)
PLONKish arithmetisation
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
each column j corresponds to a Lagrange interpolation polynomial pj(X)
PLONKish arithmetisation
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
each column j corresponds to a Lagrange interpolation polynomial pj(X)�evaluating to pj(⍵i) = xij, where ⍵ is the nth primitive root of unity.
xij
PLONKish arithmetisation
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
instance columns contain inputs shared between prover/verifier (e.g. public inputs)
PLONKish arithmetisation
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
advice columns contain private values witnessed by the prover
PLONKish arithmetisation
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
| | | | | | | | | | | |
fixed columns contain preprocessed values set at key generation
example: Fibonacci sequence
i0 | a0 | a1 | a2 | qfib |
1 | 1 | 1 | 2 | 1 |
| 2 | 3 | 5 | 1 |
13 | 5 | 8 | 13 | 0 |
write this in tomorrow's session!
example: Fibonacci sequence
i0 | a0 | a1 | a2 | qfib |
1 | 1 | 1 | 2 | 1 |
| 2 | 3 | 5 | 1 |
13 | 5 | 8 | 13 | 0 |
qfib·(a0,cur + a1,cur - a2,cur) = 0
+ =
example: Fibonacci sequence
i0 | a0 | a1 | a2 | qfib |
1 | 1 | 1 | 2 | 1 |
| 2 | 3 | 5 | 1 |
13 | 5 | 8 | 13 | 0 |
qfib·(a0,cur + a1,cur - a0,next) = 0
qfib·(a0,cur + a1,cur - a2,cur) = 0
example: Fibonacci sequence
i0 | a0 | a1 | a2 | qfib |
1 | 1 | 1 | 2 | 1 |
| 2 | 3 | 5 | 1 |
13 | 5 | 8 | 13 | 0 |
qfib·(a0,cur + a1,cur - a0,next) = 0
qfib·(a0,cur + a1,cur - a2,cur) = 0
qfib·(a1,cur + a2,cur - a1,next) = 0
example: Fibonacci sequence
i0 | a0 | a1 | a2 | qfib |
1 | 1 | 1 | 2 | 1 |
| 2 | 3 | 5 | 1 |
13 | 5 | 8 | 13 | 0 |
qfib·(a0,cur + a1,cur - a0,next) = 0
qfib·(a0,cur + a1,cur - a2,cur) = 0
qfib·(a1,cur + a2,cur - a1,next) = 0
global permutation: a2[i] = a0[i + 1]
example: Fibonacci sequence
i0 | a0 | a1 | a2 | qfib |
1 | 1 | 1 | 2 | 1 |
| 2 | 3 | 5 | 1 |
13 | 5 | 8 | 13 | 0 |
qfib·(a0,cur + a1,cur - a0,next) = 0
qfib·(a0,cur + a1,cur - a2,cur) = 0
qfib·(a1,cur + a2,cur - a1,next) = 0
global permutation: a2[i] = a0[i + 1]
exercise: can you see how to constrain this locally (using qfib)?
example: Fibonacci sequence
i0 | a0 | a1 | a2 | qfib |
1 | 1 | 1 | 2 | 1 |
| 2 | 3 | 5 | 1 |
13 | 5 | 8 | 13 | 0 |
qfib·(a0,cur + a1,cur - a0,next) = 0
qfib·(a0,cur + a1,cur - a2,cur) = 0
qfib·(a1,cur + a2,cur - a1,next) = 0
global permutation:
PLONKish arithmetisation
how do we optimise global layout while reasoning about local offsets?
PLONKish arithmetisation
regions!
regions
"regions" are the boundary between gates and the global circuit layouter
layouter
single-pass layouter (212 rows)
layouter
dual-pass layouter (211 rows)
single-pass layouter (212 rows)
halo2_gadgets
Sinsemilla
Poseidon
210 lookup table of indexed Sinsemilla generators:
(i, P[i]x, P[i]y)
halo2_gadgets
ECC
SHA256 (experimental)
open problems / wishlist
arithmetisation (cont.)
arithmetisation (cont.)
Commit(p) = ∑n [p[i]]Gi,
where i = [0..=n], and Gi's are commitments to the Lagrange basis polynomials
ai(X)
advice polys
fi(X)
fixed polys
arithmetisation (cont.)
h(X) =
gate0(X) + y·gate1(X) + … + yn·gaten(X)
t(X)
where t(X) is the vanishing polynomial on the domain {ω0,…,ωn-1}; in other words, t(X) = Xn-1
arithmetisation (cont.)
h(x) =
gate0(x) + y·gate1(x) + … + yn·gaten(x)
t(x)
a0(x), a0(⍵x), a1(⍵x),…
f0(x), f1(⍵x), f1(⍵-1x),…
arithmetisation (cont.)
multipoint opening argument
{x}
A0
A1
{x, ⍵x}
A2
A3
multipoint opening argument
r1(x) = A2(x) + x1·A3(x)
r1(⍵x) = A2(⍵x) + x1·A3(⍵x)
q0(X) - r0(X)
X - x
q1(X) - r1(X)
(X - x)(X - ⍵x)
multipoint opening argument
polynomial commitment scheme
Setup(): generates a setup pk
Commit(pk, P): creates a commitment c to P
VerifyPoly(pk, c, P): checks c is a valid commitment to P
Open(pk, P, x): generates an opening proof π
VerifyOpen(pk, c, x, y, π): checks if y = P(x) using π
added in "Math Building Blocks" (15 Jun)
arithmetisation
polynomial commitment scheme
accumulation scheme
satisfying witness
relation
low-degree polynomial
commitment opening proof
commitment opening proof
Θ(log d) accumulator size; amortised Θ(d) final check cost
PLONKish arithmetisation +�vanishing argument, multipoint opening argument
inner product argument
accumulation scheme
satisfying witness
relation
final_poly
commitment opening proof
commitment opening proof
Θ(log d) accumulator size; amortised Θ(d) final check cost
inner product argument
Setup(1λ,d) produces a crs σ = (𝔾, 𝔽p, G, H) for group 𝔾 of � prime order p, with random G ∈ 𝔾d and H ∈ 𝔾.
Commit(σ, p(X); r): P =〈a, G〉 + [r]H, where ai∈𝔽 is the coeff � for the ith deg term in p(X), i ∈ [0,d)
VerifyPoly(pk, P, p): checks that P =〈a, G〉 + [r]H
Open(pk, p, x): generates an opening proof π for y = p(x)� =〈a, (1,x,…,xd-1)〉
VerifyOpen(pk, C, x, y, π): checks y =〈a, (1,x,…,xd-1)〉using π
added in "Math Building Blocks" (15 Jun)
NOT trusted!
inner product argument
Setup(1λ,d) produces a crs σ = (𝔾, 𝔽p, G, H) for group 𝔾 of � prime order p, with random G ∈ 𝔾d and H ∈ 𝔾.
Commit(σ, p(X); r): P =〈a, G〉 + [r]H, where ai∈𝔽 is the coeff � for the ith deg term in p(X), i ∈ [0,d)
VerifyPoly(pk, P, p): checks that P =〈a, G〉 + [r]H
Open(pk, p, x): generates an opening proof π for y = p(x)� =〈a, (1,x,…,xd-1)〉
VerifyOpen(pk, C, x, y, π): checks y =〈a, (1,x,…,xd-1)〉using π
naive opening proof: send a (O(n) communication)
want: π with O(log d) communication
added in "Math Building Blocks" (15 Jun)
inner product argument�(originally from [Bootle et al, 2016])
we have vectors a, b each of length d = 2k. we want to prove that a given inner product c and a commitment P are related as:
y = ⟨a, b⟩
P = ⟨a, G⟩ + ⟨b, H⟩
where G, H are length-n vectors of random group elements.�
we can combine this into a single commitment Pk using a random group element U:
Pk = P + [y]U = ⟨a, G⟩ + ⟨b, H⟩ + [⟨a, b⟩]U�
the naive solution would be to send the verifier a, b — but this requires sending 2d scalars. instead, the inner product argument uses O(log(d)) = O(k) communication cost.
a(k)
b(k)
added in "Math Building Blocks" (15 Jun)
modified inner product argument
we have vectors a, b each of length d = 2k.
fix b = (1, x, x2,…,xd-1) for a chosen evaluation point x, known to both prover and verifier. since b is known, no random vector H is needed.
we want to prove that v, which is an evaluation of a at x, and a commitment P are related as:
v = ⟨a, (1, x, x2,…,xd-1)⟩
P = ⟨a, G⟩ + [r]H
where G is a length-n vector of random group elements.
we can combine this into a single commitment Pk using a random group element U:
Pk = P + [v]U = ⟨a, G⟩ + [r]H + [⟨a, b⟩]U
a(k)
b(k)
added in "Math Building Blocks" (15 Jun)
modified inner product argument
we start at the kth round, where we split a, b, G into lo and hi halves. we introduce a random challenge uk and compress the vectors by adding the left and the right halves separated by uk:�
a(k-1) = uk · alo(k) + uk-1 · ahi(k)
b(k-1) = uk-1 · blo(k) + uk · bhi(k)
G(k-1) = uk-1 · Glo(k) + uk · Ghi(k)
�now, we can write a commitment Pk-1 (of the same form as Pk) using the compressed vectors:
Pk-1 = ⟨a(k-1), G(k-1)⟩ + [⟨a(k-1), b(k-1)⟩] U
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
added in "Math Building Blocks" (15 Jun)
modified inner product argument
we can examine the compressed Pk-1 equation in terms of the original vectors:
Pk-1 = ⟨a(k-1), G(k-1)⟩ + [⟨a(k-1), b(k-1)⟩]U
= ⟨uk·alo + uk-1·ahi, uk-1·Glo + uk·Ghi⟩ +
[⟨uk·alo+ uk-1·ahi, uk-1·blo + uk·bhi⟩]U
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
added in "Math Building Blocks" (15 Jun)
modified inner product argument
we can examine the compressed Pk-1 equation in terms of the original vectors:
Pk-1 = ⟨a(k-1), G(k-1)⟩ + [⟨a(k-1), b(k-1)⟩]U
= ⟨uk·alo + uk-1·ahi, uk-1·Glo + uk·Ghi⟩ +
[⟨uk·alo+ uk-1·ahi, uk-1·blo + uk·bhi⟩]U
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
uk-2Rk
uk2Lk
Pk-1 = ⟨alo,Glo⟩ + ⟨ahi,Ghi⟩ + uk2 ⟨alo,Ghi⟩ + uk-2 ⟨ahi,Glo⟩ +
[⟨alo,blo⟩ + ⟨ahi,bhi⟩)]U + [uk2 ⟨alo,bhi⟩ + uk-2 ⟨ahi,blo⟩]U
= Pk + [uk2] Lk + [uk-2] Rk
added in "Math Building Blocks" (15 Jun)
modified inner product argument
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
Pk-1 = Pk + [uk2]Lk + [uk-2]Rk
Pk-1 is the sum of Pk and the cross-terms Lk, Rk (with coefficients from the round challenge uk)
uk-2Rk
uk2Lk
added in "Math Building Blocks" (15 Jun)
modified inner product argument
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
�a(k-1)
�b(k-1)
round k-1
we repeat this in the k-1st round, defining the new compressed eqn
Pk-2 = ⟨a(k-2),G(k-2)⟩ + [⟨a(k-2),b(k-2)⟩]U
uk-2Rk
uk2Lk
uk-1·alo(k-1)
uk-1-1·ahi(k-1)
uk-1-1·blo(k-1)
uk-1·bhi(k-1)
added in "Math Building Blocks" (15 Jun)
modified inner product argument
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
�a(k-1)
�b(k-1)
we repeat this in the k-1st round, defining the new compressed eqn
Pk-2 = ⟨a(k-2),G(k-2)⟩ + [⟨a(k-2),b(k-2)⟩]U
uk-2Rk
uk2Lk
uk-1-2Rk-1
uk-12Lk-1
uk-1-1·ahi(k-1)
uk-1·alo(k-1)
uk-1-1·blo(k-1)
uk-1·bhi(k-1)
and deriving new cross-terms
Lk-1, Rk-1 such that
Pk-2 = Pk-1 + [uk-12]Lk-1 + [uk-1-2]Rk-1
round k-1
added in "Math Building Blocks" (15 Jun)
modified inner product argument
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
�a(k-1)
�b(k-1)
we repeat this in the k-1st round, defining the new compressed eqn
Pk-2 = ⟨a(k-2),G(k-2)⟩ + [⟨a(k-2),b(k-2)⟩]U
uk-2Rk
uk2Lk
uk-1-2Rk-1
uk-12Lk-1
uk-1-1·ahi(k-1)
uk-1·alo(k-1)
uk-1-1·blo(k-1)
uk-1·bhi(k-1)
and deriving new cross-terms
Lk-1, Rk-1 such that
Pk-2 = Pk-1 + [uk-12]Lk-1 + [uk-1-2]Rk-1
� = Pk + [uk2]Lk + [uk-2]Rk
+ [uk-12]Lk-1 + [uk-1-2]Rk-1
round k-1
added in "Math Building Blocks" (15 Jun)
modified inner product argument
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
�a(k-1)
�b(k-1)
uk-2Rk
uk2Lk
uk-1-2Rk-1
uk-12Lk-1
uk-1-1·ahi(k-1)
uk-1·alo(k-1)
uk-1-1·blo(k-1)
uk-1·bhi(k-1)
�a(k-2)
�b(k-2)
round k-1
round k-2
added in "Math Building Blocks" (15 Jun)
modified inner product argument
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
�a(k-1)
�b(k-1)
uk-2Rk
uk2Lk
uk-1-2Rk-1
uk-12Lk-1
uk-1-1·ahi(k-1)
uk-1·alo(k-1)
uk-1-1·blo(k-1)
uk-1·bhi(k-1)
�a(k-2)
�b(k-2)
round k-1
round k-2
…
…
…
…
added in "Math Building Blocks" (15 Jun)
modified inner product argument
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
�a(k-1)
�b(k-1)
uk-2Rk
uk2Lk
uk-1-2Rk-1
uk-12Lk-1
uk-1-1·ahi(k-1)
uk-1·alo(k-1)
uk-1-1·blo(k-1)
uk-1·bhi(k-1)
�a(k-2)
�b(k-2)
round k-1
round k-2
…
…
…
…
round 1
�a(0)
�b(0)
u1-2R1
u12L1
added in "Math Building Blocks" (15 Jun)
modified inner product argument
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
�a(k-1)
�b(k-1)
uk-2Rk
uk2Lk
uk-1-2Rk-1
uk-12Lk-1
uk-1-1·ahi(k-1)
uk-1·alo(k-1)
uk-1-1·blo(k-1)
uk-1·bhi(k-1)
�a(k-2)
�b(k-2)
round k-1
round k-2
…
…
…
…
round 1
�a(0)
�b(0)
u1-2R1
u12L1
added in "Math Building Blocks" (15 Jun)
modified inner product argument
a(k)
b(k)
�uk·alo(k)
�uk-1·ahi(k)
�uk·bhi(k)
�uk-1·blo(k)
round k
�a(k-1)
�b(k-1)
uk-2Rk
uk2Lk
uk-1-2Rk-1
uk-12Lk-1
uk-1-1·ahi(k-1)
uk-1·alo(k-1)
uk-1-1·blo(k-1)
uk-1·bhi(k-1)
�a(k-2)
�b(k-2)
round k-1
round k-2
…
…
…
…
round 1
�a(0)
�b(0)
u1-2R1
u12L1
our proof is now just 2k - 1 field elements!
added in "Math Building Blocks" (15 Jun)
modified inner product argument
P0 = [a(0)]G(0) + [a(0)·b(0)] U
but P0 = ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
verifier checks this equivalence
[a]G + [a·b] U == ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
added in "Math Building Blocks" (15 Jun)
modified inner product argument
P0 = [a(0)]G(0) + [a(0)·b(0)] U
but P0 = ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
verifier checks this equivalence
[a]G + [a·b] U == ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
from prover
added in "Math Building Blocks" (15 Jun)
modified inner product argument
P0 = [a(0)]G(0) + [a(0)·b(0)] U
but P0 = ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
verifier checks this equivalence
[a]G + [a·b] U == ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
from prover
calculated by verifier
added in "Math Building Blocks" (15 Jun)
modified inner product argument
P0 = [a(0)]G(0) + [a(0)·b(0)] U
but P0 = ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
verifier checks this equivalence
[a]G + [a·b] U == ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
= g(x, u1, …, uk)
where g(X, u1, …, uk) = ∏k(ui + ui-1X2 )
(can compute in O(log(d) steps)
⟨G,s⟩
⟨b,s⟩
where s =
(u1-1 u2-1 u3-1 … uk-1,
u1 u2-1 u3 … uk-1,
u1-1 u2 u3-1 … uk ,
…
u1 u2 u3 … uk )
added in "Math Building Blocks" (15 Jun)
modified inner product argument
P0 = [a(0)]G(0) + [a(0)·b(0)] U
but P0 = ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
verifier checks this equivalence
[a]G + [a·b] U == ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
⟨G,s⟩
where s =
(u1-1 u2-1 u3-1 … uk-1,
u1 u2-1 u3 … uk-1,
u1-1 u2 u3-1 … uk ,
…
u1 u2 u3 … uk )
needs a linear-time multi-scalar multiplication.
this is a problem for recursive proof composition: a linear-size verification circuit will yield fixed-depth recursion at best.
instead, we use an accumulation scheme to amortise this linear cost across a batch of proof instances.
added in "Math Building Blocks" (15 Jun)
PLONKish arithmetisation +�vanishing argument, multipoint opening argument
inner product argument
accumulation scheme
satisfying witness
relation
final_poly
commitment opening proof
commitment opening proof
Θ(log d) accumulator size; amortised Θ(d) final check cost
added in "Math Building Blocks" (15 Jun)
PLONKish arithmetisation +�vanishing argument, multipoint opening argument
inner product argument
accumulation scheme
satisfying witness
relation
final_poly
commitment opening proof
commitment opening proof
Θ(log d) accumulator size; amortised Θ(d) final check cost
added in "Math Building Blocks" (15 Jun)
modified inner product argument
P0 = [a(0)]G(0) + [a(0)·b(0)] U
but P0 = ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
verifier checks this equivalence
[a]G + [a·b] U == ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
⟨G,s⟩
where s =
(u1-1 u2-1 u3-1 … uk-1,
u1 u2-1 u3 … uk-1,
u1-1 u2 u3-1 … uk ,
…
u1 u2 u3 … uk )
can itself be rewritten as a polynomial commitment:
G = G(0) = Commit(𝜎, g(X,u1,…,uk))
g(X,u1,…,uk) = ∏k(ui + ui-1X2 )
added in "Math Building Blocks" (15 Jun)
modified inner product argument
P0 = [a(0)]G(0) + [a(0)·b(0)] U
but P0 = ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
verifier checks this equivalence
[a]G + [a·b] U == ∑k([uj2] Lj) + Pk + ∑k([uj-2] Rj)
⟨G,s⟩
where s =
(u1-1 u2-1 u3-1 … uk-1,
u1 u2-1 u3 … uk-1,
u1-1 u2 u3-1 … uk ,
…
u1 u2 u3 … uk )
can itself be rewritten as a polynomial commitment:
G = G(0) = Commit(𝜎, g(X,u1,…,uk))
which means we can invoke an inner product argument for G.
g(X,u1,…,uk) = ∏k(ui + ui-1X2 )
added in "Math Building Blocks" (15 Jun)
accumulation scheme
in an accumulation scheme, it is expensive to “decide” validity of an instance, but cheap to combine two (or more) instances.
π evaluation proof for the claim that P(x) = v
added in "Math Building Blocks" (15 Jun)
accumulator | accumulation step | decider |
P, x, v, a, G, L, R {u1,u2,…,uk} | polynomial commitment opening of G (O(log(d) field operations) the old accumulator and new instance (same form as the accumulator) are accumulated into a new accumulator | check (in O(d) time) that G = Commit(g(X,u1,u2,…,uk)) = ⟨s,G⟩ |
accumulation scheme
in an accumulation scheme, it is expensive to “decide” validity of an instance, but cheap to combine two (or more) instances.
accumulator | accumulation step | decider |
P, x, v, a, G, L, R {u1,u2,…,uk} | polynomial commitment opening of G (O(log(d) field operations) the old accumulator and new instance (same form as the accumulator) are accumulated into a new accumulator | check (in O(d) time) that G = Commit(g(X,u1,u2,…,uk)) = ⟨s,G⟩ |
π evaluation proof for the claim that P(x) = v
instead of trying to compute G = ⟨s, G⟩ in the circuit, the verifier instead asks the prover to supply the purported G as part of their witness.
the recursive verifier then checks (in O(log(d) field operations) that G opens at some random point to the expected value for the given challenges {u1,u2,…,uk}.
added in "Math Building Blocks" (15 Jun)
accumulation scheme
zi
zi+1
diagram adapted from https://iacr.org/cryptodb/data/paper.php?pubkey=30579
IVC prover
πi
πi+1
ai
ai+1
IVC proof
IVC proof consists of:
added in "Math Building Blocks" (15 Jun)
accumulation scheme
F
zi
zi+1
diagram adapted from https://iacr.org/cryptodb/data/paper.php?pubkey=30579
IVC prover
πi
πi+1
ai
ai+1
IVC proof
compute state transition function
added in "Math Building Blocks" (15 Jun)
accumulation scheme
F
zi
zi+1
diagram adapted from https://iacr.org/cryptodb/data/paper.php?pubkey=30579
IVC prover
πi
πi+1
ai
ai+1
IVC proof
accumulate previous inputs (zi, πi, ai) into a new accumulator ai+1
P
accumulation prover
added in "Math Building Blocks" (15 Jun)
accumulation scheme
F
zi
zi+1
diagram adapted from https://iacr.org/cryptodb/data/paper.php?pubkey=30579
IVC prover
πi
πi+1
ai
ai+1
IVC proof
verify that new accumulator was updated correctly
P
V
accumulation verifier
added in "Math Building Blocks" (15 Jun)
accumulation scheme
F
zi
zi+1
diagram adapted from https://iacr.org/cryptodb/data/paper.php?pubkey=30579
IVC prover
πi
πi+1
ai
ai+1
IVC proof
apply SNARK prover to the circuit R
P
V
R
SNARK.Prove
added in "Math Building Blocks" (15 Jun)
accumulation scheme
F
zi
zi+1
diagram adapted from https://iacr.org/cryptodb/data/paper.php?pubkey=30579
IVC prover
πi
πi+1
ai
ai+1
IVC proof
P
V
R
SNARK.Prove
IVC verifier
IVC verifier takes in some z, π, a
added in "Math Building Blocks" (15 Jun)
accumulation scheme
F
zi
zi+1
diagram adapted from https://iacr.org/cryptodb/data/paper.php?pubkey=30579
IVC prover
πi
πi+1
ai
ai+1
IVC proof
P
V
R
SNARK.Prove
IVC verifier
D
IVC verifier runs decider D to check that accumulator is well-formed
added in "Math Building Blocks" (15 Jun)
accumulation scheme
F
zi
zi+1
diagram adapted from https://iacr.org/cryptodb/data/paper.php?pubkey=30579
IVC prover
πi
πi+1
ai
ai+1
IVC proof
P
V
R
SNARK.Prove
IVC verifier
D
IVC verifier runs SNARK verifier
SNARK.Verify
added in "Math Building Blocks" (15 Jun)
thank you!
any questions?