Basefold

This article aims to provide an intuitive explanation of the goals and processes of the Basefold protocol.

Introduction

BaseFold is a new Polynomial Commitment Scheme that is field-agnostic, with verifier complexity of O(log2n)O(\log^2n) and prover complexity of O(nlogn)O(n \log n). While the RS-code used in FRI-IOPP requires an FFT-friendly field, BaseFold eliminates this constraint by introducing the concept of random foldable code, making it usable with sufficiently large fields.

Background

Constant Polynomial in FRI-IOPP

In FRI, the following polynomial is folded using a random value α0\alpha_0.

P0(X)=c0+c1X+c2X2++c2k1X2k1P_0(X) = c_0 + c_1X + c_2X^2 + \cdots + c_{2^k-1}X^{2^k-1}

After the first round, the polynomial becomes:

P1(X)=c0+c1α0+(c2+c3α0)X++(c2k2+c2k1α0)X2k11P_1(X) = c_0 + c_1 \cdot \alpha_0 + (c_2 + c_3 \cdot \alpha_0) X + \cdots + (c_{2^k-2} + c_{2^k-1} \cdot\alpha_0) X^{2^{k-1}- 1}

If this folding process is repeated k+1k+1 times, the resulting polynomial will eventually reduce to a constant polynomial, which looks like:

Pk+1(X)=c0+c1α0+c2α1+c3α1α0++c2k1α0α1αkP_{k+1}(X) = c_0 + c_1\cdot \alpha_0 + c_2 \cdot \alpha_1 + c_3 \cdot \alpha_1 \cdot \alpha_0 + \cdots + c_{2^k-1} \cdot \alpha_0 \cdot \alpha_1 \cdot \cdots \cdot \alpha_k

This constant polynomial is identical to the evaluation of the multilinear polynomial QQ at point (α0,α1,α2,,αk)(\alpha_0, \alpha_1, \alpha_2, \dots, \alpha_k).

Q(X0,X1,X2,,Xk)=c0+c1X0+c2X1++c2k11X0X1XkQ(X_0, X_1, X_2, \dots,X_k) = c_0+ c_1X_0 + c_2X_1 + \cdots + c_{2^{k-1} -1}X_0X_1\cdots X_{k}

Protocol Explanation

Foldable Code

It is well-known that RS (Reed-Solomon) codes are a type of linear code, and the encoding of linear codes can be represented as a matrix-vector multiplication. For example, the encoding of an [n,k,d][n, k, d]-RS code, when n=16n = 16 and k=8k = 8, can be represented as follows:

The matrix on the left can be transformed into the matrix on the right by applying a row permutation.

If we divide the matrix on the right into four parts, the red and yellow-colored sections are identical and correspond to the matrix used in RS encoding when n=8n = 8 and k=4 k = 4. The green-colored section is equivalent to multiplying the red matrix by a diagonal matrix T=diag(1,ω,ω2,,ω7)T = \mathsf{diag}(1, \omega, \omega^2, \dots, \omega^7). Similarly, the blue-colored section is equivalent to multiplying the red matrix by another diagonal matrix T=diag(ω8,ω9,ω10,,ω15)T' = \mathsf{diag}(\omega^8, \omega^9, \omega^{10}, \dots, \omega^{15}).

If the matrix used in the encoding of a linear code takes the form above, it is referred to as a foldable linear code. Let us define this more formally.

Let c,k0,dNc, k_0, d \in \mathbb{N}, ki=k02i1,ni=ckik_i = k_0 \cdot 2^{i-1}, n_i = c \cdot k_i for every i[1,d]i \in [1,d]. A (c,k0,d)(c, k_0,d)-foldable linear code is a linear code with a generator matrix GdG_d and rate 1c\frac{1}{c} with the following properties:

  • the diagonal matrices Ti1,Ti1Fni1×ni1T_{i-1}, T'_{i-1} \in \mathbb{F}^{n_{i-1} \times n_{i-1}} satisfies that diag(Ti1)[j]diag(Ti1)[j]\mathsf{diag}(T_{i-1})[j] \ne \mathsf{diag}(T'_{i-1})[j] for every j[0,ni11]j \in [0,n_{i-1}-1].

  • the matrix GiFki×niG_i \in \mathbb{F}^{k_i \times n_i} equals (up to row permutation)\

Gi=[Gi1Gi1Gi1Ti1Gi1Ti1]G_i = \begin{bmatrix} G_{i−1} & G_{i−1} \\ G_{i−1} \cdot T_{i-1} & G_{i−1} \cdot T'_{i-1} \\ \end{bmatrix}

Random Foldable Code

To design a linear code that is foldable and efficiently encodable regardless of its finite field, BaseFold uses this algorithm:

  1. Set G0D0G_0 \leftarrow D_0​, where D0D_0​ is a distribution that outputs with 100% probability. Such a DiD_i​ is referred to as a (c,k0)(c, k_0)-foldable distribution.

  2. Sample Ti$(F×)niT_i \leftarrow_\$ (\mathbb{F}^\times)^{n_i} and set Ti=TiT'_i = -T_i.

  3. Generate Gi+1G_{i+1}​ using Gi,Ti,TiG_i, T_i, T'_i.

  4. Repeat steps 2 and 3 until a GiG_i​ of the desired size is obtained.

This type of code is called a Random Foldable Code (RFC). The paper demonstrates that this code has good relative minimum distance. For those interested, refer to Section 3.1 of the paper. Additionally, it is noted that this is a special case of punctured Reed-Muller codes. For further details, consult Appendix D of the paper.

Encoding Algorithm

The encoding can be computed recursively as follows:

  1. If i=0i = 0, return Enc0(m)\mathsf{Enc}_0(m).

  2. Unpack 1×ki1 \times k_i matrix mm into a pair of 1×ki/21 \times k_i / 2 matrix (ml,mr)(m_l, m_r).

  3. Set l=Enci1(ml)l = \mathsf{Enc}_{i-1}(m_l), t=diag(Ti1)t = \mathsf{diag}(T_{i-1}), and then pack a pair of ki×ni/2k_i \times n_i / 2 matrices (l+tr,ltr)(l + t \circ r, l - t \circ r) to ki×nik_i \times n_i matrix.

This approach is valid and can be proven inductively:

  • If i=0i = 0, Enc0(m)=mG0\mathsf{Enc}_0(m) = m \cdot G_0​, which holds by definition.

  • If i>0i>0, Enci(m)=mGi\mathsf{Enc}_i(m) = m \cdot G_i holds because of the recursive construction of GiG_i.

l+tr=Enci1(ml)+diag(Ti1)Enci1(mr)=mlGi1+diag(Td1)(mrGi1)=mlGi1+mrGi1Ti1ltr=Enci1(ml)diag(Ti1)Enci1(mr)=mlGi1diag(Ti1)(mrGi1)=mlGi1mrGi1Ti1(l+tr,ltr)=(ml,mr)[Gi1Gi1Gi1Ti1Gi1Ti1]=mGi\begin{align*} l + t \circ r &= \mathsf{Enc}_{i-1}(m_l) + \mathsf{diag}(T_{i-1}) \circ \mathsf{Enc}_{i-1}(m_r) \\ &= m_l \cdot G_{i-1} + \mathsf{diag}(T_{d-1}) \circ (m_r \cdot G_{i-1}) \\ &= m_l\cdot G_{i-1} + m_r \cdot G_{i-1} \cdot T_{i-1} \end{align*} \\ \begin{align*} l - t \circ r &= \mathsf{Enc}_{i-1}(m_l)- \mathsf{diag}(T_{i-1}) \circ \mathsf{Enc}_{i-1}(m_r )\\ &= m_l \cdot G_{i-1} - \mathsf{diag}(T_{i-1}) \circ (m_r \cdot G_{i-1}) \\ &= m_l\cdot G_{i-1} - m_r \cdot G_{i-1} \cdot T_{i-1} \end{align*} \\ (l+t\circ r, l-t \circ r) = (m_l, m_r) \cdot \begin{bmatrix} G_{i-1} &G_{i-1} \\ G_{i-1} \cdot T_{i-1} & G_{i-1} \cdot -T_{i-1} \end{bmatrix} = m \cdot G_i

BaseFold IOPP

To use this in IOPP, we need to ensure that πi\pi_i is indeed an encoded random linear combination derived from mi+1m_{i+1}. To demonstrate this, let mim_i ​represent the message at the ii-th layer and πi\pi_i ​ the oracle (or block) at the ii-th layer. Then, the following holds:

πi+1=mi+1Gi+1=mi+1[GiGiGiTiGiTi]=[Enci(mi+1,l)+diag(Ti)Enci(mi+1,r)Enci(mi+1,l)+diag(Ti)Enci(mi+1,r)]\begin{align*} \pi_{i+1} &= m_{i+1}\cdot G_{i+1} \\ &= m_{i+1} \cdot \begin{bmatrix} G_i & G_i \\ G_i \cdot T_i & G_i \cdot T_i' \end{bmatrix} \\ &= [\mathsf{Enc}_i(m_{i+1, l}) + \mathsf{diag}(T_i) \circ \mathsf{Enc}_i(m_{i+1, r}) || \mathsf{Enc}_i(m_{i+1, l}) + \mathsf{diag}(T_i') \circ \mathsf{Enc}_i(m_{i+1, r}) ] \end{align*}

Thus, for j[0,ni1]j \in [0, n_i - 1], the following conditions are satisfied, where nin_i ​ is the length of πi\pi_i:

πi+1[j]=Enci(mi+1,l)[j]+diag(Ti)[j]Enci(mi+1,r)[j]πi+1[j+ni]=Enci(mi+1,l)[j]+diag(Ti)[j]Enci(mi+1,r)[j]\pi_{i+1}[j] = \mathsf{Enc}_i(m_{i+1, l})[j] + \mathsf{diag}(T_i)[j] \cdot \mathsf{Enc}_i(m_{i+1, r})[j] \\ \pi_{i+1}[j + n_i] = \mathsf{Enc}_i(m_{i+1, l})[j] + \mathsf{diag}(T_i')[j] \cdot \mathsf{Enc}_i(m_{i+1, r})[j]

The values πi+1[j]\pi_{i+1}[j] and πi+1[j+ni]\pi_{i+1}[j + n_i] are evaluations of the polynomial f(X)=Enci(mi+1,l)[j]+XEnci(mi+1,r)[j]f(X) = \mathsf{Enc}_i(m_{i+1, l})[j] + X \cdot \mathsf{Enc}_i(m_{i+1, r})[j] at diag(Ti)[j]\mathsf{diag}(T_i)[j] and diag(Ti)[j]\mathsf{diag}(T_i')[j], respectively. When using the sampled value αi\alpha_i at each ii-th layer, f(αi)f(\alpha_i) can be constructed as follows, ensuring that πi\pi_i encodes the message mi,l+αimi,rm_{i,l} + \alpha_i \cdot m_{i, r}:

πi[j]=f(αi)=Enci(mi+1,l)[j]+αiEnci(mi+1,r)[j]=Enci(mi+1,l+αimi+1,r)[j]\begin{align*} \pi_i[j] &= f(\alpha_i) \\ &= \mathsf{Enc}_i(m_{i+1, l})[j] + \alpha_i \cdot \mathsf{Enc}_i(m_{i+1, r})[j] \\ &=\mathsf{Enc}_i(m_{i+1, l} + \alpha_i \cdot m_{i+1, r})[j] \end{align*}

Using this property, an IOPP (Interactive Oracle Proof of Proximity) can be designed. Here, interpolate((x1,y1),(x2,y2))\text{interpolate}((x_1, y_1), (x_2, y_2)) refers to the computation of a degree-1 polynomial PP such that P(x1)=y1,P(x2)=y2P(x_1) = y_1, P(x_2) = y_2.

IOPP.Commit:πd:=Encd(f)Fnd(πd1,,π0)Fnd1××Fn0\mathsf{IOPP.Commit}: \pi_d := \mathsf{Enc}_d(f) \in \mathbb{F}^{n_d} \rightarrow (\pi_{d - 1}, \dots, \pi_0) \in \mathbb{F}^{n_{d-1}} \times \cdots \times \mathbb{F}^{n_0}

Prover witness: the polynomial fF[X0,X1,,Xd1]f \in \mathbb{F}[X_0, X_1, \dots, X_{d-1}]

For ii from d1d − 1 to 00:

  1. The verifier samples αi$F\alpha_i \leftarrow_\$ \mathbb{F} and sends it to the prover.

  2. For each index j[0,ni1]j \in [0, n_i - 1], the prover

    1. sets f(X):=interpolate((diag(Ti)[j],πi+1[j]),(diag(Ti)[j],πi+1[j+ni]))f(X) := \mathsf{interpolate}((\mathsf{diag}(T_i)[j], π_{i+1}[j]),(\mathsf{diag}(T'_i)[j], π_{i+1}[j + n_i])).

    2. sets πi[j]=f(αi)\pi_i[j] = f(\alpha_i).

  3. The prover outputs oracle πiF\pi_i \in \mathbb{F}.

IOPP.Query:(πd,,π0)accept or reject\mathsf{IOPP.Query}: (\pi_d, \dots, \pi_0) \rightarrow \text{accept or reject}

  1. The verifier samples an index μ$[0,nd11]\mu \leftarrow_\$ [0, n_{d-1}-1].

  2. For ii from d1d − 1 to 00, the verifier

    1. queries oracle entries πi+1[μ],πi+1[μ+ni]\pi_{i+1}[\mu], \pi_{i+1}[\mu + n_i].

    2. computes p(X):=interpolate((diag(Ti)[μ],πi+1[μ]),(diag(Ti)[μ],πi+1[μ+ni]))p(X) := \mathsf{interpolate}((\mathsf{diag}(T_i)[\mu], π_{i+1}[\mu]),(\mathsf{diag}(T'_i)[\mu], π_{i+1}[\mu + n_i])).

    3. checks that p(αi)=πi[μ]p(α_i) = \pi_i[\mu].

    4. if i>0i > 0 and μ>ni1\mu > n_{i−1}, update μμni1\mu \leftarrow \mu − n_{i−1}.

  3. If π0\pi_0 is a valid codeword w.r.t. generator matrix G0G_0, output accept, otherwise output reject.

Multilinear PCS based on interleaving BaseFold IOPP

When performing the sumcheck protocol, the problem is reduced to an evaluation claim. Interestingly, the BaseFold IOPP shares a similar structure: given an input oracle that encodes a polynomial fF[X0,X1,,Xd1]f \in \mathbb{F}[X_0, X_1, \dots, X_{d-1}], the final oracle sent by the honest prover in the IOPP protocol is precisely an encoding of a random evaluation f(r)f(\bm{r}), where r=(r0,r1,,rd1)\bm{r} = (r_0, r_1, \dots, r_{d-1}).

Thus, the sumcheck protocol and the IOPP protocol can be executed interleaved, sharing the same random challenge. At the end, the verifier needs to check whether the evaluation claim f(r)=yf(\bm{r})=y, obtained through the sumcheck protocol, matches the final prover message from the IOPP protocol. It performs as follows:

PC.Eval\mathsf{PC.Eval}

Public input: oracle πf:=Encd(f)Fnd\pi_f := \mathsf{Enc}_d(f) \in \mathbb{F}^{n_d}, point r\bm{r}, claimed evaluation y=f(r)Fy = f(\bm{r}) \in \mathbb{F}

Prover witness: the polynomial fF[X0,X1,,Xd1]f \in \mathbb{F}[X_0, X_1, \dots, X_{d-1}]

  1. The prover sends the following to the verifier:

hd(X)=b{0,1}d1f(b,X)eq~r(b,X),eq~r(X0,X1,,Xd1)=i=0d1(riXi+(1ri)(1Xi))h_d(X) =\sum_{\bm{b} \in \{0, 1\}^{d-1}} f(\bm{b}, X) \cdot \widetilde{\mathsf{eq}}_r(\bm{b}, X), \\ \widetilde{\mathsf{eq}}_r(X_0, X_1, \dots, X_{d-1}) = \prod_{i = 0}^{d-1}(r_i \cdot X_i + (1 - r_i)(1 - X_i))
  1. For ii from d1d − 1 to 00:

  2. Verifier samples and sends ri$Fr_i \leftarrow_\$ \mathbb{F} to the prover.

  3. For each j[0,ni1]j \in [0, n_i - 1], the prover

    1. sets gj(X):=interpolate((diag(Ti)[j],πi+1[j]),(diag(Ti)[j],πi+1[j+ni]))g_j(X) := \mathsf{interpolate}((\mathsf{diag}(T_i)[j], π_{i+1}[j]),(\mathsf{diag}(T'_i)[j], π_{i+1}[j + n_i])).

    2. sets πi[j]=gj(ri)\pi_i[j] = g_j(r_i).

  4. The prover outputs oracle πiFni\pi_i ∈ \mathbb{F}^{n_i}.

  5. if i>0i > 0, the prover sends verifier.

hi(X)=b{0,1}i1f(b,X,ri,,rd1)eq~z(b,X,ri,,rd1)h_i(X) =\sum_{\bm{b} \in \{0, 1\}^{i-1}} f(\bm{b}, X, r_i, \dots, r_{d-1}) \cdot \widetilde{\mathsf{eq}}_z(\bm{b}, X, r_i, \dots, r_{d-1})
  1. The verifier checks that

    1. IOPP.query(πd,,π0)\mathsf{IOPP.query}^{(\pi_d, \dots, \pi_0)} outputs accept.

    2. hd(0)+hd(1)=?yh_d(0) + h_d(1) \stackrel{?}= y and for every i[1,d1]i \in [1, d - 1], hi(0)+hi(1)=?hi+1(ri)h_i(0) + h_i(1) \stackrel{?}= h_{i+1}(r_i).

    3. Enc0(h1(r0)/eq~z(r0,,rd1))=?π0\mathsf{Enc}_0(h_1(r_0) / \widetilde{\mathsf{eq}}_z(r_0, \dots, r_{d-1})) \stackrel{?}= \pi_0.

Conclusion

In a 256-bit PCS:

  • BaseFold compared to field-agnostic Brakedown:

    • Prover time: Slower

    • Verifier time: Faster

    • Proof size: Bigger with a small number of variables but smaller with a large number of variables.

  • BaseFoldFri compared to the non-field-agnostic ZeromorphFri:

    • Prover time: Faster

    • Verifier time: Faster

    • Proof size: Larger

In a 64-bit PCS:

  • BaseFold compared to field-agnostic Brakedown:

    • Prover time: Slower

    • Verifier time: Faster

    • Proof size: Smaller

  • BaseFoldFri compared to the non-field-agnostic ZeromorphFri:

    • Prover time: Faster

    • Verifier time: Slower

    • Proof size: Larger

In a 256-bit SNARK:

  • BaseFold compared to field-agnostic Brakedown:

    • Prover time: Faster with a small number of variables but similar with a large number of variables.

    • Verifier time: Faster

    • Proof size: Smaller

  • BaseFoldFri compared to the non-field-agnostic ZeromorphFri:

    • Prover time: Similar

    • Verifier time: Similar

    • Proof size: Larger

In a 64-bit SNARK:

  • Both BaseFold and BaseFoldFri, compared to Zeromorph:

    • Prover time: Similar

    • Verifier time: Slower with a small number of variables but faster with a large number of variables.

    • Proof size: Larger

Written by ryan Kim from A41

Last updated