Plookup & Caulk

Crypto Study Club -  Session 1

8th June 2022

Recap: Constraints

\textcolor{gray}{2.} a_1 \textcolor{gray}{+3.}b_1 \textcolor{gray}{+1.}c_1 \textcolor{gray}{-1.}d_1 \textcolor{gray}{+5} = 0
\textcolor{gray}{0.} a_3 \textcolor{gray}{+0.}b_3 \textcolor{gray}{+1.}a_3b_3 \textcolor{gray}{-1.}c_3 \textcolor{gray}{+0} = 0
(a_i,b_i) \ \textcolor{grey}{+_{\text{ecc}}} \ (c_i, d_i) = (a_{i+1},b_{i+1})
\textsf{ecc gate}:
\underbrace{\hspace{2cm}}

StandardPlonk

\underbrace{\hspace{1cm}}

TurboPlonk

\textsf{a}
\textsf{b}
\textsf{c}
\textsf{d}
i
1
a_1
b_1
c_1
d_1
2
a_2
b_2
c_2
d_2
3
a_3
b_3
c_3
d_3
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
i
a_{i}
b_{i}
c_{i}
d_{i}
i+1
a_{i+1}
b_{i+1}
c_{i+1}
d_{i+1}
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
n-1
a_{n-1}
b_{n-1}
c_{n-1}
d_{n-1}
n
a_{n}
b_{n}
c_{n}
d_{n}
\textsf{add gate}:
\textsf{mult gate}:

Width = \(4\)

Circuit size = \(n\)

c_1 = a_i,
d_2 = b_i,
a_{i+1} = c_{n-1},
b_{i+1} = d_{n-1},
\underbrace{\hspace{1cm}}

Copy constraints

Cell-wise permutation

Recap: Plookup

\textsf{a}
\textsf{b}
\textsf{c}
\textsf{d}
i
1
a_1
b_1
c_1
d_1
2
a_2
b_2
c_2
d_2
3
a_3
b_3
c_3
d_3
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
i
a_{i}
b_{i}
c_{i}
d_{i}
i+1
a_{i+1}
b_{i+1}
c_{i+1}
d_{i+1}
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
n-1
a_{n-1}
b_{n-1}
c_{n-1}
d_{n-1}
n
a_{n}
b_{n}
c_{n}
d_{n}

Width = \(4\)

Circuit size = \(n\)

\textsf{key}_1
\textsf{key}_2
\textsf{key}_3
\textsf{val}
t_1^{(1)}
t_1^{(2)}
t_1^{(3)}
v_1
t_2^{(1)}
t_2^{(2)}
t_2^{(3)}
v_2
t_3^{(1)}
t_3^{(2)}
t_3^{(3)}
v_3
t_l^{(1)}
t_l^{(2)}
t_l^{(3)}
v_l

Lookup Table \(T\)

Lookup table size = \(l\)

\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots

Lookup argument:

(a_i,b_i,c_i,d_i) \in T
\underbrace{\hspace{8.5cm}}

PLookup

\textsf{a}
\textsf{b}
\textsf{c}
\textsf{d}
i
1
a_1
b_1
c_1
d_1
2
a_2
b_2
c_2
d_2
3
a_3
b_3
c_3
d_3
\vdots
\vdots
\vdots
\vdots
\vdots
i
a_{i}
b_{i}
c_{i}
d_{i}
i+1
a_{i+1}
b_{i+1}
c_{i+1}
d_{i+1}
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
n-1
a_{n-1}
b_{n-1}
c_{n-1}
d_{n-1}
n
a_{n}
b_{n}
c_{n}
d_{n}

Width = \(4\)

Circuit size = \(n\)

\textsf{key}_1
\textsf{key}_2
\textsf{key}_3
\textsf{val}
t_1^{(1)}
t_1^{(2)}
t_1^{(3)}
v_1
t_2^{(1)}
t_2^{(2)}
t_2^{(3)}
v_2
t_3^{(1)}
t_3^{(2)}
t_3^{(3)}
v_3
t_{l-2}^{(1)}
t_{l-2}^{(2)}
t_{l-2}^{(3)}
v_{l-2}

Lookup Table \(T\)

\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
t_{l-1}^{(1)}
t_{l-1}^{(2)}
t_{l-1}^{(3)}
v_{l-1}
t_l^{(1)}
t_l^{(2)}
t_l^{(3)}
v_l
i-1
a_{i-1}
b_{i-1}
c_{i-1}
d_{i-1}

Lookup table size = \(l\)

Recap: Plookup

\textsf{a}
\textsf{b}
\textsf{c}
\textsf{d}
i
1
a_1
b_1
c_1
d_1
2
a_2
b_2
c_2
d_2
3
a_3
b_3
c_3
d_3
\vdots
\vdots
\vdots
\vdots
\vdots
i
a_{i}
b_{i}
c_{i}
d_{i}
i+1
a_{i+1}
b_{i+1}
c_{i+1}
d_{i+1}
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
n-1
a_{n-1}
b_{n-1}
c_{n-1}
d_{n-1}
n
a_{n}
b_{n}
c_{n}
d_{n}

Width = \(4\)

Circuit size = \(n\)

\textsf{key}_1
\textsf{key}_2
\textsf{key}_3
\textsf{val}
t_1^{(1)}
t_1^{(2)}
t_1^{(3)}
v_1
t_2^{(1)}
t_2^{(2)}
t_2^{(3)}
v_2
t_3^{(1)}
t_3^{(2)}
t_3^{(3)}
v_3
t_{l-2}^{(1)}
t_{l-2}^{(2)}
t_{l-2}^{(3)}
v_{l-2}

Lookup Table \(T\)

Lookup table size = \(l\)

\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots
\vdots

Multi-set check:

\{\eta_j\}_{j\in[m]} \in \{t_i\}_{i\in[l]}
t_{l-1}^{(1)}
t_{l-1}^{(2)}
t_{l-1}^{(3)}
v_{l-1}
t_l^{(1)}
t_l^{(2)}
t_l^{(3)}
v_l
i-1
a_{i-1}
b_{i-1}
c_{i-1}
d_{i-1}
\eta_1
\eta_2
\eta_3
\eta_m
\vdots
t_{l}
t_1
t_2
t_3
t_{l-2}
t_{l-1}

Can be written in a form similar to the permutation argument!

Recap: Plookup

Caulk vs Plookup

  • Plookup enables efficient bitwise or any operations in circuits
  • But, what's the tradeoff? If the total lookup table size is \(N\)
\textsf{Prover} \approx \mathcal{O}(\text{max}(n\text{log}(n), N\text{log}(N)))
  • Caulk does better: for \(m\) lookups
\textsf{Prover} \approx \mathcal{O}\big(n \text{log}(n) + m\text{log}(N) + m^2\big)
  • Caulk pays in terms of pre-processing and storage
\textsf{pre-processing} \approx \mathcal{O}\big(N\text{log}(N)\big)
\textsf{storage} \approx \mathcal{O}\big(N\big)

Kate Primer

  • To prove the knowledge of a polynomial \(f(X) \in \mathbb{F}_{<n}[X]\)
f(X)= c_0 + c_1X + \dots + c_{n-1}X^{n-1}
  • Suffices to show that \(f(X)\) evaluates to \(v = f(z)\) at a scalar \(z\in \mathbb{F}_q,\)
z
v=f(z)
(f(X) - v)\big|_{X=z} = 0
\begin{aligned} Q(X) = \frac{f(X)-v}{X-z} \end{aligned}
\textcolor{gray}{\texttt{// condition}}
\textcolor{gray}{\texttt{// quotient polynomial}}
\begin{aligned} Q(\textcolor{orange}{s})(\textcolor{orange}{s}-z) \stackrel{?}{=} f(\textcolor{orange}{s})-v \end{aligned}
\textcolor{gray}{\texttt{// verification}}

Caulk: Main Idea

a_{1}
a_{2}
a_{3}
\vdots
a_{m-1}
a_{m}
c_{1}
c_{2}
c_{3}
\vdots
c_{N-1}
c_{N}
\vdots
\vdots
c_{N-2}
c_{N-3}
\vec{a}
\vec{c}
\implies \forall j \in [m]: \ \ a_{j} \in \vec{c}
\omega^{0}
\omega^{1}
\omega^{2}
\vdots
\omega^{N-2}
\omega^{N-1}
\vdots
\vdots
\omega^{N-3}
\omega^{N-4}
\omega^{i_1}
\omega^{i_2}
\omega^{i_3}
\vdots
\omega^{i_{m-1}}
\omega^{i_m}
\mathbb{H}
\mathbb{H}_I
\nu^0
\nu^{1}
\nu^{2}
\vdots
\nu^{m-2}
\nu^{m-1}
\mathbb{V}_m
  • Write \(\vec{c}\) and \(\vec{a}\) as a polynomials:
C(X) = \sum_{i=1}^{N} \textcolor{orange}{c_i} \cdot \textcolor{gray}{L_{\mathbb{H},i}(X)}
A(X) = \sum_{j=1}^{m} \textcolor{lightgreen}{a_j} \cdot \textcolor{gray}{L_{\mathbb{V}_m,j}(X)}
  • Index set \(I = \{i_j\}_{j\in[m]} \subset [N]\) and subset of roots \(\mathbb{H}_I\)
C_I(X) = \sum_{j=1}^{m} \textcolor{orange}{c_{i_j}} \cdot \textcolor{gray}{L_{\mathbb{H}_I,j}(X)}
  • High-level idea: Compute a KZG-like formulation
\begin{aligned} \forall j \in [m]: \ (\textcolor{orange}{c_i} - \textcolor{orange}{c_{i_j}}) = 0 \ \ \wedge \ \ \textcolor{orange}{c_{i_j}} = \textcolor{lightgreen}{a_j} \end{aligned}
  • Prove: \(\vec{a} \in \vec{c}\)
\textcolor{gray}{\texttt{// condition}}
\begin{aligned} Q_1(X) = \frac{C(X) - C_I(X)}{z_I(X)} \end{aligned}
\textcolor{gray}{\texttt{// quotient polynomial}}

Caulk: Step 1

a_{1}
a_{2}
a_{3}
\vdots
a_{m-1}
a_{m}
c_{1}
c_{2}
c_{3}
\vdots
c_{N-1}
c_{N}
\vdots
\vdots
c_{N-2}
c_{N-3}
\vec{a}
\vec{c}
\omega^{0}
\omega^{1}
\omega^{2}
\vdots
\omega^{N-2}
\omega^{N-1}
\vdots
\vdots
\omega^{N-3}
\omega^{N-4}
\omega^{i_1}
\omega^{i_2}
\omega^{i_3}
\vdots
\omega^{i_{m-1}}
\omega^{i_m}
\mathbb{H}
\mathbb{H}_I
\nu^0
\nu^{1}
\nu^{2}
\vdots
\nu^{m-2}
\nu^{m-1}
\mathbb{V}_m
  • Step 1: Compute quotient commitment \([Q_1]_1\)
\begin{aligned} Q_1(X) = \frac{C(X) - C_I(X)}{z_I(X)} \end{aligned}
  • Problem: Degree of \(C\) and \(Q_1\) is \(N\)!
  • Using precomputed KZG proofs, we can do \(\mathcal{O}(m)\):
Q_{1}
Q_{2}
Q_{3}
\vdots
Q_{N-1}
Q_{N}
\vdots
\vdots
Q_{N-2}
Q_{N-3}
\pi_{\textsf{\tiny KZG}}
\begin{aligned} [Q_1]_2 = \sum_{j=1}^{m}\frac{\textcolor{violet}{Q_i}}{\prod_{k\neq j}(\omega^{i_j} - \omega^{i_k})} \end{aligned}
  • Precomputing \(N\) KZG proofs takes:
    • Computation: \(\mathcal{O}(N \text{log}N)\)
    • Storage: \(\mathcal{O}(N)\)

Caulk: Step 1 in 🧐

a_{1}
a_{2}
a_{3}
\vdots
a_{m-1}
a_{m}
c_{1}
c_{2}
c_{3}
\vdots
c_{N-1}
c_{N}
\vdots
\vdots
c_{N-2}
c_{N-3}
\vec{a}
\vec{c}
\omega^{0}
\omega^{1}
\omega^{2}
\vdots
\omega^{N-2}
\omega^{N-1}
\vdots
\vdots
\omega^{N-3}
\omega^{N-4}
\omega^{i_1}
\omega^{i_2}
\omega^{i_3}
\vdots
\omega^{i_{m-1}}
\omega^{i_m}
\mathbb{H}
\mathbb{H}_I
\nu^0
\nu^{1}
\nu^{2}
\vdots
\nu^{m-2}
\nu^{m-1}
\mathbb{V}_m
  • Details:
\begin{aligned} & C(X) - C_I(X) \end{aligned}
Q_{1}
Q_{2}
Q_{3}
\vdots
Q_{N-1}
Q_{N}
\vdots
\vdots
Q_{N-2}
Q_{N-3}
\pi_{\textsf{\tiny KZG}}
\begin{aligned} =&\ C(X) - \sum_{j\in [m]} \textcolor{orange}{c_{i_j}} \cdot \textcolor{gray}{L_{\mathbb{H}_I,j}(X)} \\ =&\ C(X) \cdot \sum_{j\in[m]} \textcolor{gray}{L_{\mathbb{H}_I,j}(X)} - \sum_{j\in [m]} \textcolor{orange}{c_{i_j}} \cdot \textcolor{gray}{L_{\mathbb{H}_I,j}(X)} \\ =&\ \sum_{j\in[m]}\left(C(X) - \textcolor{orange}{c_{i_j}}\right) \cdot \textcolor{gray}{L_{\mathbb{H}_I,j}(X)} \\ =&\ \sum_{j\in[m]}\left(C(X) - \textcolor{orange}{c_{i_j}}\right) \cdot \textcolor{gray}{\prod_{k\in[m], k\neq j}\frac{(X-\omega^{i_k})}{(\omega^{i_j}-\omega^{i_k})}} \\ =&\ \sum_{j\in[m]}\left(\frac{C(X) - \textcolor{orange}{c_{i_j}}}{X - \omega^{i_j}}\right) \cdot \textcolor{gray}{\frac{\prod_{k\in[m]}(X-\omega^{i_k})}{\prod_{k\in[m], k\neq j}(\omega^{i_j}-\omega^{i_k})}} \end{aligned}
\begin{aligned} \therefore \frac{C(X) - C_I(X)}{\textcolor{gray}{\prod_{k\in[m]}(X-\omega^{i_k})}} = \sum_{j\in[m]}\frac{Q_i(X)}{\textcolor{gray}{\prod_{k\in[m], k\neq j}(\omega^{i_j}-\omega^{i_k})} } = Q(X) \end{aligned}
=1

Caulk: Step 2

a_{1}
a_{2}
a_{3}
\vdots
a_{m-1}
a_{m}
c_{1}
c_{2}
c_{3}
\vdots
c_{N-1}
c_{N}
\vdots
\vdots
c_{N-2}
c_{N-3}
\vec{a}
\vec{c}
\omega^{0}
\omega^{1}
\omega^{2}
\vdots
\omega^{N-2}
\omega^{N-1}
\vdots
\vdots
\omega^{N-3}
\omega^{N-4}
\omega^{i_1}
\omega^{i_2}
\omega^{i_3}
\vdots
\omega^{i_{m-1}}
\omega^{i_m}
\mathbb{H}
\mathbb{H}_I
\nu^0
\nu^{1}
\nu^{2}
\vdots
\nu^{m-2}
\nu^{m-1}
\mathbb{V}_m
  • Step 2: Prove that \(z_I(X)\) is indeed of correct form
  • For this, we define
\begin{aligned} u(X) = \sum_{j\in[m]} \omega^{i_j} \cdot \textcolor{gray}{L_{\mathbb{V}_m, j}(X)} \end{aligned}
  • Step 2.1: Compute \(\pi_{\text{unity}}\) which proves that \(u(X)\) has \(N\)-th roots of unity as evaluations on \(\textcolor{gray}{\mathbb{V}_m}\) 
  • This isn't enough: we need to prove that \(z_I(X)\) vanishes on \(\textcolor{gray}{\mathbb{H}_I}\)
  • Idea: Evaluations of \(u(X)\) are roots of \(z_I(X)\)
  • Step 2.2: Compute quotient polynomial \(Q_2(X)\) s.t.
\begin{aligned} Q_2(X) = \frac{z_I(u(X))}{z_{\mathbb{V}_m}(X)} \end{aligned}

Caulk: A Step Back

a_{1}
a_{2}
a_{3}
\vdots
a_{m-1}
a_{m}
c_{1}
c_{2}
c_{3}
\vdots
c_{N-1}
c_{N}
\vdots
\vdots
c_{N-2}
c_{N-3}
\vec{a}
\vec{c}
\omega^{0}
\omega^{1}
\omega^{2}
\vdots
\omega^{N-2}
\omega^{N-1}
\vdots
\vdots
\omega^{N-3}
\omega^{N-4}
\omega^{i_1}
\omega^{i_2}
\omega^{i_3}
\vdots
\omega^{i_{m-1}}
\omega^{i_m}
\mathbb{H}
\mathbb{H}_I
\nu^0
\nu^{1}
\nu^{2}
\vdots
\nu^{m-2}
\nu^{m-1}
\mathbb{V}_m
  • After Step 1 and 2, the prover sends:
    • Commitment to \(\vec{a}\): \([A]_1\)
    • Commitment to \(C_I(X)\): \([C_I]_1\)
    • Commitment to vanishing polynomial: \([z_I]_1\)
    • Commitment to roots-of-unity poly: \([u]_1\)
    • Commitment to first quotient poly: \([Q_1]_2\)
    • Unity proof: \(\pi_{\text{unity}}\)
  • Why do we commit \(Q_1(X)\) in the second group?
\begin{aligned} Q_1(X) = \frac{C(X) - C_I(X)}{z_I(X)} \end{aligned}
\begin{aligned} \implies Q_1(X) \cdot z_I(X) = (C(X) - C_I(X)) \end{aligned}

Caulk: Step 3

a_{1}
a_{2}
a_{3}
\vdots
a_{m-1}
a_{m}
c_{1}
c_{2}
c_{3}
\vdots
c_{N-1}
c_{N}
\vdots
\vdots
c_{N-2}
c_{N-3}
\vec{a}
\vec{c}
\omega^{0}
\omega^{1}
\omega^{2}
\vdots
\omega^{N-2}
\omega^{N-1}
\vdots
\vdots
\omega^{N-3}
\omega^{N-4}
\omega^{i_1}
\omega^{i_2}
\omega^{i_3}
\vdots
\omega^{i_{m-1}}
\omega^{i_m}
\mathbb{H}
\mathbb{H}_I
\nu^0
\nu^{1}
\nu^{2}
\vdots
\nu^{m-2}
\nu^{m-1}
\mathbb{V}_m
  • What remains to show is: linking of \(C_I(X)\) with \([A]_1\)
\begin{aligned} \implies Q_3(X) = \frac{C_I(u(X)) - A(X)}{z_{\mathbb{V}_m}(X)} \end{aligned}
A(X) = \sum_{j=1}^{m} \textcolor{lightgreen}{a_j} \cdot \textcolor{gray}{L_{\mathbb{V}_m,j}(X)}
C_I(X) = \sum_{j=1}^{m} \textcolor{orange}{c_{i_j}} \cdot \textcolor{gray}{L_{\mathbb{H}_I,j}(X)}
  • Notice that: 
C_I(\omega^{i_j}) = \textcolor{orange}{c_{i_j}} = \textcolor{lightgreen}{a_j}
  • Compute \([Q_3]_1\)  and we're done!
  • Last step: open all of these polys on a challenge point

Summary

  • What we covered:
    • Plookup multi-set check 
    • Caulk vs Plookup discussion
    • Caulk main idea
    • Caulk maths
  • What we didn't cover:
    • Other ideas in Caulk for membership proofs
  • More papers up for presentations:
    • Elliptic curves' survey
    • Bulletproofs++
    • SNARK based on Bulletproofs++

Plookup & Caulk

By Suyash Bagad

Plookup & Caulk

Comparison of Plookup and latest work Caulk.

  • 79