# FFlonk Comments and Optimizations ## (Optimized) PCS of ShPlonk This PCS is composed by the following algorithms: 1. $gen(d)$. The generator algorithm outputs $srs = ([1]_1, [x]_1, [x^2]_1,\dots,[x^{d-1}]_1,[1]_2,[x]_2)$ for a random (and secret) $x \in \mathbb{F}$. 2. $com(f_i)$. Given a polynomial $f_i \in \mathbb{F}_{<d}[X]$, the committer algorithm outputs $[f_i(x)]_1$. 3. $open(\{cm_i\}_k,\{S_i\}_k,\{r_i\}_k; \{f_i\}_k)$. The opening algorithm works as follows, where $k$ is the number of committed polynomials, $\{cm_i\}_k$ are the alleged commitments to $\{f_i\}_k$, $T = \{z_1,\dots,z_t\}$ is the set of opening points, $\{S_i\}_k$ is the opening set for the $i$-th polynomial, and $\{r_i\}_k$ are the polynomials interpolating the alleged the openings. **Assume for simplicity that $k=2$ and that $S_1 = \{z_1\}$ and $S_2 = \{z_2\}$**. 1. V sends a random challenge $\gamma \in \mathbb{F}$. 2. P sends $W = [(f/Z_T)(x)]_1$, where: $$ f(X) = (X-z_2)(f_1(X) - r_1(X)) + \gamma (X-z_1)(f_2(X) - r_2(X)).$$ In the normal batched KZG, V would stop here and simply use pairings to check the correctness. In ShPlonk, however, there is one extra round to reduce verifier complexity. 3. V sends a random evaluation point $z \in \mathbb{F}$. 4. P sends $W' = \left[\frac{L(x)}{(z-z_2)(x-z)}\right]_1$, where: $$ L(X) = (z-z_2)(f_1(X) - r_1(z)) + \gamma (z-z_1)(f_2(X) - r_2(z)) - Z_T(z) \frac{f(X)}{Z_T(X)}.$$ This protocol improves the original shPlonk, by one verifier scalar multiplication, by normalizing the definition of $L$ dividing it by $(z-z_2)$. Notice that $L(z) = f(z) - f(z) = 0$. 5. TOFINISH. verifier check ## PCS of Fflonk This PCS differs from the previous one in that the commitment to a set of polynomials $f_i \in \mathbb{F}_{<d}[X]$, is carried on by computing the polynomial: $$ g(X) = f_1(X^t) + f_2(X^t)X + \dots + f_t(X^t)X^{t-1}, $$ and outputting $[g(x)]_1$. ### One Vector of Polynomials and One Evaluation Point Assume $z = h^t$. Then, to open $f_1,\dots,f_t$ at $\{f_1(z), \dots, f_t(z)\}$, open $g$ at $\{h, h\omega, h\omega^2,\dots,h\omega^{t-1}\}$, where $\omega$ is a primitive $t$-th root of unity. To this end, compute the following two sets: \begin{align} \bar{Z}' = roots_t(z) = \{h, h\omega,\dots, h\omega^{t-1}\}, \\ \bar{S} = \{f_1(z), f_2(z), \dots, f_t(z)\}, \end{align} and compute the set: $$ \bar{S}' = \bar{S}(\bar{Z}') = \{f_1(z) + f_2(z)h + \dots + f_t(z)h^{t-1}, \dots, f_1(z) + f_2(z)h\omega + \dots + f_t(z)(h\omega)^{t-1}\} $$ and notice that $\bar{S}' = \{g(h),g(h\omega),\dots,g(h\omega^{t-1})\}$. Finally, engage in the $open(cm,\bar{Z}',\bar{S}'; g)$ protocol. ### One Vector of Polynomials and Multiple Evaluation Points Assume $z_1 = h_1^t, \dots, z_k = h_k^t$. Then, basically run the previous protocol on each of the evaluations points. Then, to open $f_1,\dots,f_t$ at $\{[f_1(z_1), f_2(z_1), \dots, f_t(z_1)], \dots, [f_1(z_k), f_2(z_k), \dots, f_t(z_k)]\}$, open $g$ at $\{[h_1, h_1\omega,\dots, h_1\omega^{t-1}], \dots, [h_k, h_k\omega,\dots, h_k\omega^{t-1}]\}$, where $\omega$ is a primitive $t$-th root of unity. To this end, compute the following two sets: \begin{align} \bar{Z}' = roots_t(z) = \{[h_1, h_1\omega,\dots, h_1\omega^{t-1}], \dots, [h_k, h_k\omega,\dots, h_k\omega^{t-1}]\}, \\ \bar{S} = \{[f_1(z_1), f_2(z_1), \dots, f_t(z_1)], \dots, [f_1(z_k), f_2(z_k), \dots, f_t(z_k)]\}, \end{align} and compute the set $\bar{S}' = \{[g(h_1),g(h_1\omega),\dots,g(h_1\omega^{t-1})], \dots, [g(h_k),g(h_k\omega),\dots,g(h_k\omega^{t-1})]\}$. Finally, engage in the $open(cm,\bar{Z}',\bar{S}'; g)$ protocol. ### Multiple Vectors of Polynomials and Multiple Evaluation Points Generalize the previous protocol and engage in the $open(\{cm_i\},\bar{Z}',\bar{S}'; \{g_i\})$ protocol. I don't write it to avoid crazy notation, but this is the one applied in the following section. ## Adding Zero-Knowledge (with Dummy Gates) In the [PlonK](https://eprint.iacr.org/2019/953.pdf) paper, in the order for the protocol to be zero-knowledge, the authors add to some witness-related polynomial a blinding polynomial $b \in \mathbb{F}[X]$ as follows: $$ a(X) := b(X)Z_H(X) + {\sum}_{i=1}^n w_iL_i(X). $$ To guarantee zero-knowledge, the degree of this polynomial should be **at least** equal to the number of revealed evaluations of $a$ that the prover sends to the verifier in the opening phase of the KZG commitment scheme. This strategy ends up defining polynomials with degree $n + \deg(b)$, which is inefficient for practical scenarios in which $n$ is a power of two. To avoid this issue, we proceed as follows. From now on, let $m$ be the circuit size (that is, the number of gates) and let $n$ be the closest power of two such that $n \geq m+4$. ### Wiring Polynomials We add zero-knowledge to the wiring polynomials $a,b,c$ by sampling blinding factors $b_1,\dots,b_6 \in \mathbb{F}$ and defining: \begin{align} a(X) &:= {\sum}_{i=1}^m w_iL_i(X) + b_1L_{m+1}(X) + b_2L_{m+2}(X), \\ b(X) &:= {\sum}_{i=1}^m w_{m+i}L_i(X) + b_3L_{m+1}(X) + b_4L_{m+2}(X) , \\ c(X) &:= {\sum}_{i=1}^m w_{2m+i}L_i(X) + b_5L_{m+1}(X) + b_6L_{m+2}(X), \end{align} where note that $a(\omega^i)=b(\omega^i)=c(\omega^i)=0$ for all $i \in \{m+3,m+4,\dots,n\}$. In essence, we are adding **dummy gates** that will be satisfied by definition and not because of the circuit. Now, let's look at the satisfiability of the following constraint, for each $x \in H$: $$ q_L(x)a(x) + q_R(x)b(x) + q_O(x)c(x) + q_M(x)a(x)b(x) + q_C(x) + PI(x) = 0 $$ - For $i=1,\dots,m$ the constraint is satisfied if the associated values satisfy the given circuit. In fact, we can safely assume that the number of public inputs is lower than $m$, so the public input polynomial $PI$ evaluates to $0$ in the forthcoming cases. - For $i=m+1$ the constraint becomes: $$ q_L(\omega^{m+1})b_1 + q_R(\omega^{m+1})b_3 + q_O(\omega^{m+1})b_5 + q_M(\omega^{m+1})b_1\cdot b_3 + q_C(\omega^{m+1}) = 0, $$ which is satisfied by setting all the selectors equal to $0$ at $\omega^{m+1}$. The same happens in the case $i=m+2$. - For $i =m+3,\dots,n$ we simply set $q_C(\omega^i)=0$. Notice that while the rest of the selectors could evaluate to **any** value from $\mathbb{F}$ (without affecting the soundness of the protocol), so we set them to $0$ for simplicity of the exposition. To summary, the only change we have to do with respect to the original protocol is to define the selector polynomials as follows: $$ \begin{array}{c} q_L(X) = {\sum}_{i=1}^{m} q_{L_i}L_i(X), \quad q_R(X) = {\sum}_{i=1}^{m} q_{R_i}L_i(X), \quad q_O(X) = {\sum}_{i=1}^{m} q_{O_i}L_i(X), \\[0.2cm] q_M(X) = {\sum}_{i=1}^{m} q_{M_i}L_i(X), \quad q_C(X) = {\sum}_{i=1}^{m} q_{C_i}L_i(X). \end{array} $$ ### Grand-Product Polynomial We add zero-knowledge to the grand-product polynomial $z$ by sampling blinding factors $b_7,b_8,b_9 \in \mathbb{F}$ and defining: \begin{align} z(X) := &~L_1(X) +{\sum}_{i=1}^{m−1} \left(L_{i+1}(X) {\prod}_{j=1}^i \frac{(w_j + \beta \omega^j + \gamma)(w_{m+j} + \beta k_1 \omega^j + \gamma)(w_{2m+j} + \beta k_2 \omega^j + \gamma)}{(w_j + \beta \sigma^*(j) + \gamma)(w_{m+j} + \beta \sigma^*(m+j) + \gamma)(w_{2m+j} + \beta \sigma^*(2m+j) + \gamma)} \right) \\[0.1cm] &~+ L_{m+1}(X) + b_7L_{m+2}(X) + b_8L_{m+3}(X) + b_9L_{m+4}(X) + \sum_{i=m+5}^n L_i(X). \end{align} Now, let's look at the satisfiability of the following constraint, for each $x \in H$: \begin{align} &(a(x) + \beta x + \gamma) (b(x) + \beta k_1 x + \gamma) (c(x) + \beta k_2 x + \gamma) z(x) \\ &-(a(x) + \beta S_{\sigma_1}(x) + \gamma) (b(x) + \beta S_{\sigma_2}(x) + \gamma) (c(x) + \beta S_{\sigma_3}(x) + \gamma) z(x\omega) = 0. \end{align} - For $i=1,\dots,m$ the constraints is satisfied if the $z$ polynomial is correctly constructed. - For $i=m+1$ the constraint becomes: \begin{align} &(b_1 + \beta \omega^{m+1} + \gamma) (b_3 + \beta k_1 \omega^{m+1} + \gamma) (b_5 + \beta k_2 \omega^{m+1} + \gamma) \\ &-(b_1 + \beta S_{\sigma_1}(\omega^{m+1}) + \gamma) (b_3 + \beta S_{\sigma_2}(\omega^{m+1}) + \gamma) (b_5 + \beta S_{\sigma_3}(\omega^{m+1}) + \gamma) b_7 = 0, \end{align} which is not satisfied with overwhelming probability. Consequently, we should multiply both sides of the constraint by $(x-\omega^{m+1})$. The same goes for the cases $i=m+2,i=m+3$ and $i=m+4$, so we also multiply by $(x-\omega^{m+2}),(x-\omega^{m+3})$ and $(x-\omega^{m+4})$ as well. - For $i =m+5,\dots,n$ the constraint turns out to be: \begin{align} (\beta \omega^{i} + \gamma) (\beta k_1 \omega^{i} + \gamma) (\beta k_2 \omega^{i} + \gamma) -(\beta S_{\sigma_1}(\omega^{i}) + \gamma) (\beta S_{\sigma_2}(\omega^{i}) + \gamma) (\beta S_{\sigma_3}(\omega^{i}) + \gamma) = 0, \end{align} which is satisfied by setting $S_{\sigma_1}(\omega^i) = \omega^i, S_{\sigma_2}(\omega^i) = k_1\omega^i$ and $S_{\sigma_3}(\omega^i) = k_2\omega^i$, i.e., the permutation $\sigma^*$ acts like the identity function for $i \in \{m+5,\dots,n\}$. Moreover, we should add a constraint attesting that $z$ is equal to one at $\omega^{m+1}$ (since this is the point in which the "real" gates ends). Finally, notice that the $S_{\sigma_1},S_{\sigma_2},S_{\sigma_3}$ could evaluate to **any** value from $\mathbb{F}$ (without affecting the soundness of the protocol) for $i=m+1,\dots,m+4$, so we set them to $1$ for simplicity in their definition. To summary, we must have to perform two changes. First, the new constraints of $Z$ become: $$ \begin{align} &L_1(X)(z(X)-1)) = 0, \\[0.1cm] &[(a(X) + \beta X + \gamma) (b(X) + \beta k_1 X + \gamma) (c(X) + \beta k_2 X + \gamma) z(X) \\ &-(a(X) + \beta S_{\sigma_1}(X) + \gamma) (b(X) + \beta S_{\sigma_2}(X) + \gamma) (c(X) + \beta S_{\sigma_3}(X) + \gamma) z(X\omega)] \\ &\qquad (X-\omega^{m+1})(X-\omega^{m+2})(X-\omega^{m+3})(X-\omega^{m+4})= 0, \\[0.1cm] &L_{m+1}(X)(z(X)-1)) = 0. \end{align} $$ Second, we define the sigma polynomials as follows: $$ \begin{array}{c} S_{\sigma_1}(X) = {\sum}_{i=1}^{m} \sigma^*(i)L_i(X) + \sum_{i=m+1}^n \omega^iL_i(X), \quad S_{\sigma_2}(X) = {\sum}_{i=1}^{m} \sigma^*(m+i)L_i(X) + \sum_{i=m+1}^n k_1\omega^iL_i(X), \\[0.1cm] S_{\sigma_3}(X) = {\sum}_{i=1}^{m} \sigma^*(2m+i)L_i(X) + \sum_{i=m+1}^n k_2\omega^iL_i(X). \end{array} $$ ## Lagrange Polynomials Keep in mind that Lagrange polynomials are different if points in which they are evaluated are distinct. For example, the Lagrange polynomial for $H$ satisfies, for $i \in [n]$: $$ L_i(x) = \begin{cases} 1 & \text{if } x = \omega^{i-1} \\ 0 & \text{if } x = \omega^j, j \neq i-1 \end{cases} $$ and moreover $L_i$ is a polynomial of degree $n-1$. In contrast, the Lagrange polynomial $L_i^{(S_0)}$ satisfies, for $i\in[8]$: $$ L_i^{(S_0)}(x) = \begin{cases} 1 & \text{if } x = h_0\omega_8^{i-1} \\ 0 & \text{if } x = h_0\omega_8^j, j \neq i-1 \end{cases} $$ the Lagrange polynomial $L_i^{(S_1)}$ satisfies, for $i\in[4]$: $$ L_i^{(S_1)}(x) = \begin{cases} 1 & \text{if } x = h_1\omega_4^{i-1} \\ 0 & \text{if } x = h_1\omega_4^j, j \neq i-1 \end{cases} $$ and the Lagrange polynomial $L_i^{(S_2)}$ satisfies, for $i \in \{1,2,3\}$ and $j \in \{4,5,6\}$: \begin{array}{cc} L_i^{(S_2)}(x) = \begin{cases} 1 & \text{if } x = h_2\omega_3^{i-1} \\ 0 & \text{otherwise} \end{cases} & L_j^{(S_2)}(x) = \begin{cases} 1 & \text{if } x = h_3\omega_3^{j-1} \\ 0 & \text{otherwise} \end{cases} \end{array} or more explicitly: \begin{array}{c} L_i(X) := \frac{\omega^{i-1}}{n}\frac{X^n-1}{X-\omega^{i-1}}, \\[0.1cm] L_i^{(S_0)}(X) := \frac{\omega_8^{i-1}}{8h_0^7} \cdot \frac{X^8 - h_0^8}{(X-h_0\omega_8^{i-1})}, \\[0.1cm] L_i^{(S_1)}(X) := \frac{\omega_4^{i-1}}{4h_1^3} \cdot \frac{X^4 - h_1^4}{(X-h_1\omega_4^{i-1})}, \\[0.1cm] L_i^{(S_2)}(X) := \frac{\omega_3^{i-1}}{3h_2^5-3h_3^3h_2^2} \cdot \frac{X^6 - (h_2^3+h_3^3)X^3 + h_2^3h_3^3}{(X-h_2\omega_3^{i-1})}, \\[0.1cm] L_j^{(S_2)}(X) := \frac{\omega_3^{j-1}}{3h_3^5-3h_2^3h_3^2} \cdot \frac{X^6 - (h_2^3+h_3^3)X^3 + h_2^3h_3^3}{(X-h_3\omega_3^{j-1})}. \end{array} ## Division by a Polynomial of the form $X^m - \beta$ Given a polynomial $p(X) = a_dX^d + \dots + a_1X + a_0 \in \mathbb{F}[X]$ of degree $d$ at least $m$ and a field element $\beta$, the quotient of the division $p(X)/(X^m-\beta)$ is the polynomial: \begin{align} q(X) := &~a_{d}X^{d-m} + a_{d-1}X^{(d-1)-m} + \dots + a_{d-(m-1)}X^{(d-(m-1))-m} + \\[0.2cm] &+ (a_{d-m}+a_{d} \cdot \beta)X^{(d-m)-m} + \dots + (a_{d-(2m-1)}+a_{d-(m-1)} \cdot \beta)X^{(d-(2m-1))-m} + \\[0.2cm] &+ (a_{d-2m}+a_{d-m}\cdot \beta + a_{d} \cdot \beta^2)X^{(d-2m)-m} + \dots + (a_{d-(3m-1)}+a_{d-(2m-1)}\cdot\beta + a_{d-(m-1)} \cdot \beta^2)X^{(d-(3m-1))-m} \\ &\qquad\qquad\qquad\qquad\qquad\qquad\quad~\vdots \\ \end{align} Basically, $q$ is a polynomial with the $m$ leading coefficients equal to the $m$ leading coefficients of $p$; the following $m$ coefficients are of the form $a_i+a_j \cdot \beta$, with $j-i=m$; the following $m$ coefficients are of the form $a_i+a_j\cdot\beta + a_k \cdot \beta^2$, with $j-i=k-j=m$; and so on. Intuitively speaking, each $m$ coefficients of $q$, one jumps from the actual coefficient of $p$ with jumps of length $m$ until "is possible" from bot to top. Consequently, the last $m$ coefficients of $p$ are never used for $q$. For instance, if $p(X) = \sum_{i=0}^{10} a_iX^i$ and $m=2$, then: \begin{align} q(X) := &~a_{10}X^8 + a_9X^7 + (a_8+a_{10}\beta)X^6 + (a_7+a_9\beta)X^5 + \\ &+(a_6+a_8\beta+a_{10}\beta^2)X^4 + (a_5+a_7\beta+a_9\beta^2)X^3 + \\ &+(a_4+a_6\beta+a_8\beta^2+a_{10}\beta^3)X^2 + (a_3+a_5\beta+a_7\beta^2+a_9\beta^3)X + \\ &+(a_2+a_4\beta+a_6\beta^2+a_8\beta^3+a_{10}\beta^4) \end{align} Note that if $d \leq 2m-1$, then $q$ is only composed of the $m$ leading coefficients of $p$. ### Alternative ```javascript function divideByVanishingCoset(p, n, b, p) { let q = Array(p.length).fill(0n); let r = [...p]; for (let i = p.length - 1; i >= n; i--) { let leadingCoeff = r[i]; if (leadingCoeff === 0n) continue; r[i] = 0n; r[i - n] = mod(r[i - n] + b * leadingCoeff, p); q[i - n] = mod(q[i - n] + leadingCoeff, p); } return [q, r]; } ``` We want to find polynomials $q$ and $r$ such that $p(X) = q(X)(X^n-\beta) + r(X)$ with $0 \leq \deg(r)<n$. The following observation is crucial: \begin{align}p(X) &= 0 \cdot (X^n-\beta) + p(X) = 0 \cdot (X^n-\beta) + (p(X) - p_dX^d) + p_dX^d = \\ &= 0 \cdot (X^n-\beta) + (p(X) - p_dX^d) + p_dX^{d-n}X^d - \beta \cdot p_dX^{d-n} + \beta \cdot p_dX^{d-n} = \\ &= 0 \cdot (X^n-\beta) + (p(X) - p_dX^d) + p_dX^{d-n}(X^d - \beta) + \beta \cdot p_dX^{d-n} = \\ &=p_dX^{d-n} \cdot (X^n-\beta) + (p(X) - p_dX^d + \beta \cdot p_dX^{d-n}) \end{align} The idea is to lower the degree of $r$ by correctly varying $q$ and $r$ while preserving the previous identity. ### Generalization to Multiple Polynomials Given a polynomial $p(X) = a_dX^d + \dots + a_1X + a_0$ of degree $d$ at least $|T| = 18$ that is divisible by $Z_T$, the following algorithm gives the quotient of the division $p/Z_T$. We start by noticing that: $$ Z_T(X) = Z_{S_0}(X) \cdot Z_{S_1}(X) \cdot Z_{S_2}(X) = (X^8 - \mathfrak{z}) \cdot (X^4-\mathfrak{z}) \cdot (X^6 - \mathfrak{z}(1 + \omega)X^3 + \mathfrak{z}^2\omega) $$ Then, we proceed as follows: 1. Divide $p$ by $Z_{S_0}$ to obtain the polynomial $q_0$ such that $q_0(X) \cdot Z_{S_0}(X) = p(X)$. 1. Divide $q_0$ by $Z_{S_1}$ to obtain the polynomial $q_1$ such that $q_1(X) \cdot Z_{S_1}(X) = q_0(X)$. 1. Split $Z_{S_2}(X) = (X^6 - \mathfrak{z}(1 + \omega)X^3 + \mathfrak{z}^2\omega)$ as the multiplication of $(X^3-\mathfrak{z})$ and $(X^3-\mathfrak{z}\omega)$. Then: - Divide $q_1$ by $(X^3-\mathfrak{z})$ to obtain the polynomial $q_2$ s.t. $q_2(X) \cdot (X^3-\mathfrak{z}) = q_1(X)$. - Divide $q_2$ by $(X^3-\mathfrak{z}\omega)$ to obtain the polynomial $q_3$ s.t. $q_3(X) \cdot (X^3-\mathfrak{z}\omega) = q_2(X)$. The polynomial $q_3(X)$ satisfies $Z_T(X) \cdot q_3(X) = p(X)$. ###### tags: `PlonK`