Optimising Sumcheck

December 10, 2025

Sumcheck: The new bottleneck

  • Binius enables efficient SNARKs over binary fields
  • Fast commitment scheme + sumcheck based IOPs
  • Commitment part is so fast that sumcheck becomes the bottleneck

Credit: Radi Cojbasic's talk at zk summit 12.

Sumcheck: The new bottleneck

  • Binius enables efficient SNARKs over binary fields
  • Fast commitment scheme + sumcheck based IOPs
  • Commitment part is so fast that sumcheck becomes the bottleneck
  • Aim: speed-up first few rounds of sumcheck

Product Sumcheck

p(x) := p_1(x) \cdot p_2(x) \cdots p_d(x)
  • We need sumcheck to prove (multilinear) polynomial relations like
  • Sumcheck round polynomial in round \(i\)
s_i(c) := \sum_{x \in \{0, 1\}^{\ell - i}} p(\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i - 1}}, c, x)
= \sum_{x \in \{0, 1\}^{\ell - i}} \prod_{j=1}^{d} p_j (\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i - 1}}, c, x)

Product of extension-field elements

  • In Binius, polynomials \(p_1(x), \dots, p_d(x)\) are defined over \(\textsf{GF}(2)\)
  • Round challenges \((\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i - 1}})\) are from \(\textsf{GF}(2^{128})\)

Product Sumcheck

  • Sumcheck round polynomial in round \(i\)
s_i(c) := \sum_{x \in \{0, 1\}^{\ell - i}} p(\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i - 1}}, c, x)
= \sum_{x \in \{0, 1\}^{\ell - i}} \prod_{j=1}^{d} p_j (\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i - 1}}, c, x)

Product of extension-field elements

  • In Binius, polynomials \(p_1(x), \dots, p_d(x)\) are defined over \(\textsf{GF}(2)\)
  • Round challenges \((\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i - 1}})\) are from \(\textsf{GF}(2^{128})\)
\newcommand{\arraystretch}{1.3} \begin{array}{|c|c|c|c|} \hline \textsf{Base field} & \textsf{Extension field} & \textsf{Degree of extension} & \text{\textbf{$t_{\text{ee}} / t_{\text{bb}}$}} \\[1ex] \hline \textsf{GF}[2] & \textsf{GF}[2^{128}] & 128 & 145 \times 10^2 \\[1ex] \hline \textsf{GF}[2^2] & \textsf{GF}[2^{128}] & 64 & 2.5 \times 10^2 \\[1ex] \hline \textsf{GF}[2^4] & \textsf{GF}[2^{128}] & 32 & 0.5 \times 10^2 \\[1ex] \hline \end{array}

Product Sumcheck

  • Sumcheck round polynomial in round \(i\)
s_i(c) := \sum_{x \in \{0, 1\}^{\ell - i}} p(\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i - 1}}, c, x)
= \sum_{x \in \{0, 1\}^{\ell - i}} \prod_{j=1}^{d} p_j (\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i - 1}}, c, x)
\begin{equation*} p_j(\textcolor{FireBrick}{r_1}, \dots, \textcolor{FireBrick}{r_{i-1}}, c, \mathbf{x}) = \ \overbrace{ \begin{aligned} & \color{FireBrick}{(1-r_1) \cdots (1-r_{i-2})(1-r_{i-1})} \cdot \\ & \color{FireBrick}{(1-r_1) \cdots (1-r_{i-2}) \cdot r_{i-1}} \cdot \\ & \color{FireBrick}{(1-r_1) \cdots r_{i-2} \cdot (1-r_{i-1})} \cdot \\ & \color{FireBrick}{(1-r_1) \cdots r_{i-2} \cdot r_{i-1}} \cdot \\ & \vdots \\ & \color{FireBrick}{r_1 \cdots r_{i-2} \cdot r_{i-1}} \cdot \end{aligned} }^{\textsf{challenge-terms}} \quad \overbrace{ \begin{aligned} & p_j(0, \dots, 0, c, \mathbf{x}) \\ & p_j(0, \dots, 0, 1, c, \mathbf{x}) \\ & p_j(0, \dots, 1, 0, c, \mathbf{x}) \\ & p_j(0, \dots, 1, 1, c, \mathbf{x}) \\ & \vdots \\ & p_j(1, \dots, 1, c, \mathbf{x}). \end{aligned} }^{\textsf{witness-terms}} \quad \begin{aligned} + \\ + \\ + \\ + \\ & \\[8pt] \\ \end{aligned} \end{equation*}

Products in Round \(1\)

\begin{equation*} p_j(\textcolor{grey}{x}) := (1-\textcolor{grey}{x}) \cdot \textcolor{skyblue}{\alpha_j} + \textcolor{grey}{x} \cdot \textcolor{lightgreen}{\beta_j}. \end{equation*}
  • In the first round, \(p_1, p_2, \dots, p_d\) are linear polynomials:
  • Trick 1: separate out witness and challenge terms
\begin{equation*} p(\textcolor{grey}{x}) = \prod_{j=1}^{d}p_j(\textcolor{grey}{x}) := \prod_{j=1}^{d} \left( (1-\textcolor{grey}{x}) \cdot \textcolor{skyblue}{\alpha_j} + \textcolor{FireBrickk}{x} \cdot \textcolor{lightgreen}{\beta_j} \right) \end{equation*}
\begin{alignedat}{5} &\;\textcolor{grey}{(1-x)^d} \cdot \textcolor{grey}{x^0} &\quad& (\textcolor{SkyBlue}{\alpha_1}\cdot\textcolor{SkyBlue}{\alpha_2}\cdots \textcolor{SkyBlue}{\alpha_{d-1}}\cdot\textcolor{SkyBlue}{\alpha_d}) &\quad& + &\quad& \\ &\; \textcolor{grey}{(1-x)^{d-1}} \cdot \textcolor{grey}{x^1} && (\textcolor{SkyBlue}{\alpha_1}\cdot\textcolor{SkyBlue}{\alpha_2}\cdots \textcolor{SkyBlue}{\alpha_{d-1}}\cdot\textcolor{LightGreen}{\beta_d}) && + & \\ &\; \textcolor{grey}{(1-x)^{d-2}} \cdot \textcolor{grey}{x^1} && (\textcolor{SkyBlue}{\alpha_1}\cdot\textcolor{SkyBlue}{\alpha_2}\cdots \textcolor{LightGreen}{\beta_{d-1}}\cdot\textcolor{SkyBlue}{\alpha_d}) && + & \\ &\; \textcolor{grey}{(1-x)^{d-3}} \cdot \textcolor{grey}{x^2} && (\textcolor{SkyBlue}{\alpha_1}\cdot\textcolor{SkyBlue}{\alpha_2}\cdots \textcolor{LightGreen}{\beta_{d-1}}\cdot\textcolor{LightGreen}{\beta_d}) && + & \\ &\;\vdots && \vdots && + & \\ &\; \textcolor{grey}{(1-x)^{1}} \cdot \textcolor{grey}{x^{d-1}} && (\textcolor{LightGreen}{\beta_1}\cdot\textcolor{LightGreen}{\beta_2}\cdots \textcolor{LightGreen}{\beta_{d-1}}\cdot\textcolor{SkyBlue}{\alpha_d}) && + & \\ &\; \textcolor{grey}{(1-x)^{0}} \cdot \textcolor{grey}{x^d} && (\textcolor{LightGreen}{\beta_1}\cdot\textcolor{LightGreen}{\beta_2}\cdots \textcolor{LightGreen}{\beta_{d-1}}\cdot\textcolor{LightGreen}{\beta_d}) && & \end{alignedat}
=

Variable-products

Coefficient-products

bb mults

(d-1)\cdot 2^d

Products in Round \(1\)

\begin{equation*} p(\textcolor{grey}{x}) = \prod_{j=1}^{d}p_j(\textcolor{grey}{x}) := \prod_{j=1}^{d} \left( (1-\textcolor{grey}{x}) \cdot \textcolor{skyblue}{\alpha_j} + \textcolor{FireBrickk}{x} \cdot \textcolor{lightgreen}{\beta_j} \right) \end{equation*}
  • We can do better: evaluate \(p\) in evaluation form!
    • Evaluate each \(p_j\) on \((d + 1)\) points \(\{e_0, e_1, \dots, e_d\}\)
    • Compute point-wise multiplication on all \(d\) points to get \([p(e_0), \dots, p(e_d)]\)

Products in Round \(1\)

\begin{equation*} p(\textcolor{grey}{x}) = \prod_{j=1}^{d}p_j(\textcolor{grey}{x}) := \prod_{j=1}^{d} \left( (1-\textcolor{grey}{x}) \cdot \textcolor{skyblue}{\alpha_j} + \textcolor{FireBrickk}{x} \cdot \textcolor{lightgreen}{\beta_j} \right) \end{equation*}
  • We can do better: compute \(p\) in evaluation form! 
    • Evaluate each \(p_j\) on \((d + 1)\) points \(\{e_0, e_1, \dots, e_d\}\)
    • Compute point-wise multiplication on all \(d\) points to get \([p(e_0), \dots, p(e_d)]\)
\begin{equation*} \left[ \begin{array}{c} p(\textcolor{gray}{e_0}) \\[4pt] p(\textcolor{gray}{e_1}) \\[4pt] \vdots \\[4pt] p(\textcolor{gray}{e_d}) \end{array} \right] = \underbrace{ \left[ \begin{array}{ccccc} 1 & \textcolor{gray}{e_0} & \textcolor{gray}{e_0}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_0}^{\textcolor{gray}{d}} \\[4pt] 1 & \textcolor{gray}{e_1} & \textcolor{gray}{e_1}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_1}^{\textcolor{gray}{d}} \\[4pt] \vdots & \vdots & \vdots & \ddots & \vdots \\[4pt] 1 & \textcolor{gray}{e_d} & \textcolor{gray}{e_d}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_d}^{\textcolor{gray}{d}} \end{array} \right] }_{\text{evaluation matrix } V} \left[ \begin{array}{c} c_0 \\[4pt] c_1 \\[4pt] \vdots \\[4pt] c_d \end{array} \right] \end{equation*}
\implies \begin{equation*} \left[ \begin{array}{c} c_0 \\[4pt] c_1 \\[4pt] \vdots \\[4pt] c_d \end{array} \right] = \underbrace{ \left[ \begin{array}{ccccc} 1 & \textcolor{gray}{e_0} & \textcolor{gray}{e_0}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_0}^{\textcolor{gray}{d}} \\[4pt] 1 & \textcolor{gray}{e_1} & \textcolor{gray}{e_1}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_1}^{\textcolor{gray}{d}} \\[4pt] \vdots & \vdots & \vdots & \ddots & \vdots \\[4pt] 1 & \textcolor{gray}{e_d} & \textcolor{gray}{e_d}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_d}^{\textcolor{gray}{d}} \end{array} \right]^{-1} }_{\text{interpolation matrix } I := V^{-1}} \left[ \begin{array}{c} p(\textcolor{gray}{e_0}) \\[4pt] p(\textcolor{gray}{e_1}) \\[4pt] \vdots \\[4pt] p(\textcolor{gray}{e_d}) \end{array} \right] \end{equation*}

Products in Round \(1\)

\begin{equation*} p(\textcolor{grey}{x}) = \prod_{j=1}^{d}p_j(\textcolor{grey}{x}) := \prod_{j=1}^{d} \left( (1-\textcolor{grey}{x}) \cdot \textcolor{skyblue}{\alpha_j} + \textcolor{FireBrickk}{x} \cdot \textcolor{lightgreen}{\beta_j} \right) \end{equation*}
  • We can do better: compute \(p\) in evaluation form! 
    • Evaluate each \(p_j\) on \((d + 1)\) points \(\{e_0, e_1, \dots, e_d\}\)
    • Compute point-wise multiplication on all \(d\) points to get \([p(e_0), \dots, p(e_d)]\)
\implies \begin{equation*} \left[ \begin{array}{c} c_0 \\[4pt] c_1 \\[4pt] \vdots \\[4pt] c_d \end{array} \right] = \underbrace{ \left[ \begin{array}{ccccc} 1 & \textcolor{gray}{e_0} & \textcolor{gray}{e_0}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_0}^{\textcolor{gray}{d}} \\[4pt] 1 & \textcolor{gray}{e_1} & \textcolor{gray}{e_1}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_1}^{\textcolor{gray}{d}} \\[4pt] \vdots & \vdots & \vdots & \ddots & \vdots \\[4pt] 1 & \textcolor{gray}{e_d} & \textcolor{gray}{e_d}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_d}^{\textcolor{gray}{d}} \end{array} \right]^{-1} }_{\text{interpolation matrix } I := V^{-1}} \left[ \begin{array}{c} p(\textcolor{gray}{e_0}) \\[4pt] p(\textcolor{gray}{e_1}) \\[4pt] \vdots \\[4pt] p(\textcolor{gray}{e_d}) \end{array} \right] \end{equation*}

bb mults

(d-1) (d+1)

Products of Linear Polynomials

\begin{equation*} p(\textcolor{grey}{x}) \ = \ \end{equation*}
\begin{alignedat}{5} &\;\textcolor{grey}{(1-x)^d} \cdot \textcolor{grey}{x^0} &\quad& (\textcolor{SkyBlue}{\alpha_1}\cdot\textcolor{SkyBlue}{\alpha_2}\cdots \textcolor{SkyBlue}{\alpha_{d-1}}\cdot\textcolor{SkyBlue}{\alpha_d}) &\quad& + &\quad& \\ &\; \textcolor{grey}{(1-x)^{d-1}} \cdot \textcolor{grey}{x^1} && (\textcolor{SkyBlue}{\alpha_1}\cdot\textcolor{SkyBlue}{\alpha_2}\cdots \textcolor{SkyBlue}{\alpha_{d-1}}\cdot\textcolor{LightGreen}{\beta_d}) && + & \\ &\; \textcolor{grey}{(1-x)^{d-2}} \cdot \textcolor{grey}{x^1} && (\textcolor{SkyBlue}{\alpha_1}\cdot\textcolor{SkyBlue}{\alpha_2}\cdots \textcolor{LightGreen}{\beta_{d-1}}\cdot\textcolor{SkyBlue}{\alpha_d}) && + & \\ &\; \textcolor{grey}{(1-x)^{d-3}} \cdot \textcolor{grey}{x^2} && (\textcolor{SkyBlue}{\alpha_1}\cdot\textcolor{SkyBlue}{\alpha_2}\cdots \textcolor{LightGreen}{\beta_{d-1}}\cdot\textcolor{LightGreen}{\beta_d}) && + & \\ &\;\vdots && \vdots && + & \\ &\; \textcolor{grey}{(1-x)^{1}} \cdot \textcolor{grey}{x^{d-1}} && (\textcolor{LightGreen}{\beta_1}\cdot\textcolor{LightGreen}{\beta_2}\cdots \textcolor{LightGreen}{\beta_{d-1}}\cdot\textcolor{SkyBlue}{\alpha_d}) && + & \\ &\; \textcolor{grey}{(1-x)^{0}} \cdot \textcolor{grey}{x^d} && (\textcolor{LightGreen}{\beta_1}\cdot\textcolor{LightGreen}{\beta_2}\cdots \textcolor{LightGreen}{\beta_{d-1}}\cdot\textcolor{LightGreen}{\beta_d}) && & \end{alignedat}
  • Schoolbook multiplication
  • Toom-cook multiplication
\begin{equation*} p(x) = \left[ \textcolor{gray}{1} \quad \textcolor{gray}{x} \quad \cdots \quad \textcolor{gray}{x^d} \right] \left[ \begin{array}{ccccc} 1 & \textcolor{gray}{e_0} & \textcolor{gray}{e_0}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_0}^{\textcolor{gray}{d}} \\[4pt] 1 & \textcolor{gray}{e_1} & \textcolor{gray}{e_1}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_1}^{\textcolor{gray}{d}} \\[4pt] \vdots & \vdots & \vdots & \ddots & \vdots \\[4pt] 1 & \textcolor{gray}{e_d} & \textcolor{gray}{e_d}^{\textcolor{gray}{2}} & \cdots & \textcolor{gray}{e_d}^{\textcolor{gray}{d}} \end{array} \right]^{-1} \left[ \begin{array}{c} p(\textcolor{gray}{e_0}) \\[4pt] p(\textcolor{gray}{e_1}) \\[4pt] \vdots \\[4pt] p(\textcolor{gray}{e_d}) \end{array} \right] \end{equation*}
\implies (d - 1) \cdot (d + 1) \ \textsf{bb}
\implies (d - 1) \cdot 2^d \ \textsf{bb}

Products of Linear Polynomials

  • Schoolbook multiplication
  • Toom-cook multiplication
\newcommand{\arraystretch}{2} \begin{array}{|l|c|c|} \hline & \textsf{Schoolbook} & \textsf{Toom-Cook} \\ \hline \textsf{Range } M & 2^{d}-1 & d \\ \hline \textsf{Variable term } V_k(\textcolor{FireBrick}{x}) & (1-\textcolor{FireBrick}{x})^{d-H(k)} \cdot \textcolor{FireBrick}{x}^{H(k)} & L_k(\textcolor{FireBrick}{x})\ \textsf{(interpolation map)} \\ \hline \textsf{Evaluation point } \epsilon_k & b_j(k) \in \{0,1\} & e_k \in E \\ \hline \end{array}
p(\textcolor{FireBrick}{x}) := \sum_{k=0}^{M} V_k(\textcolor{FireBrick}{x}) \cdot \prod_{j=1}^{d} \bigl( (1-\textcolor{grey}{\epsilon_k})\cdot \textcolor{skyblue}{\alpha_j} \;+\; \textcolor{grey}{\epsilon_k} \cdot \textcolor{LightGreen}{\beta_j} \bigr).

Back to Sumcheck

s_i(c) = \sum_{x \in \{0, 1\}^{\ell - i}} \prod_{j=1}^{d} p_j(\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i-1}}, c, x)
  • Round polynomial expression:
\sum_{k_1=0}^{M} V_{k_1}(\textcolor{FireBrick}{r_1}) \cdot \prod_{j=1}^{d} \bigl( (1-\textcolor{grey}{\epsilon_{k_1}})\cdot \textcolor{skyblue}{\alpha_j} \;+\; \textcolor{grey}{\epsilon_{k_1}} \cdot \textcolor{LightGreen}{\beta_j} \bigr)
\sum_{k_1=0}^{M} V_{k_1}(\textcolor{FireBrick}{r_1}) \cdot \prod_{j=1}^{d} \bigl( (1-\textcolor{grey}{\epsilon_{k_1}})\cdot \textcolor{skyblue}{p_j(\textcolor{skyblue}{0}, \textcolor{FireBrick}{r_2, \dots, r_{i-1}}, c, x)} \;+\; \textcolor{grey}{\epsilon_{k_1}} \cdot \textcolor{LightGreen}{p_j(1, \textcolor{FireBrick}{r_2, \dots, r_{i-1}}, c, x)} \bigr)

Product of linear polynomials in \(\textcolor{FireBrick}{r_1}\)

Back to Sumcheck

s_i(c) = \sum_{x \in \{0, 1\}^{\ell - i}} \prod_{j=1}^{d} p_j(\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i-1}}, c, x)
  • Round polynomial expression:
\sum_{k_1=0}^{M} V_{k_1}(\textcolor{FireBrick}{r_1}) \cdot \prod_{j=1}^{d} \bigl( (1-\textcolor{grey}{\epsilon_{k_1}})\cdot \textcolor{skyblue}{\alpha_j} \;+\; \textcolor{grey}{\epsilon_{k_1}} \cdot \textcolor{LightGreen}{\beta_j} \bigr)
\sum_{k_1=0}^{M} V_{k_1}(\textcolor{FireBrick}{r_1}) \cdot \prod_{j=1}^{d} \bigl( (1-\textcolor{grey}{\epsilon_{k_1}})\cdot \textcolor{skyblue}{p_j(\textcolor{skyblue}{0}, \textcolor{FireBrick}{r_2, \dots, r_{i-1}}, c, x)} \;+\; \textcolor{grey}{\epsilon_{k_1}} \cdot \textcolor{LightGreen}{p_j(1, \textcolor{FireBrick}{r_2, \dots, r_{i-1}}, c, x)} \bigr)
\sum_{k_1=0}^{M} V_{k_1}(\textcolor{FireBrick}{r_1}) \cdot \prod_{j=1}^{d} p_j(\textcolor{grey}{\epsilon_{k_1}}, \textcolor{FireBrick}{r_2, \dots, r_{i-1}}, c, x)

Product of linear polynomials in \(\textcolor{FireBrick}{r_1}\)

Back to Sumcheck

s_i(c) = \sum_{x \in \{0, 1\}^{\ell - i}} \prod_{j=1}^{d} p_j(\textcolor{FireBrick}{r_1}, \textcolor{FireBrick}{r_2}, \dots, \textcolor{FireBrick}{r_{i-1}}, c, x)
  • Round polynomial expression:
\sum_{k_1=0}^{M} V_{k_1}(\textcolor{FireBrick}{r_1}) \cdot \prod_{j=1}^{d} p_j(\textcolor{grey}{\epsilon_{k_1}}, \textcolor{FireBrick}{r_2, \dots, r_{i-1}}, c, x)

Product of linear polynomials in \(\textcolor{FireBrick}{r_1}\)

Product of linear polynomials in \(\textcolor{FireBrick}{r_2}\)

\sum_{k_2=0}^{M} V_{k_2}(\textcolor{FireBrick}{r_2}) \cdot \prod_{j=1}^{d} p_j(\textcolor{grey}{\epsilon_{k_1}}, \textcolor{grey}{\epsilon_{k_2}}, \textcolor{FireBrick}{r_3, \dots, r_{i-1}}, c, x)
s_i(c) = \sum_{x \in \{0, 1\}^{\ell - i}} \sum_{k_{1}=0}^{M} V_{k_{1}}(\textcolor{FireBrick}{r_1})\; \sum_{k_{2}=0}^{M} V_{k_{2}}(\textcolor{FireBrick}{r_2})\; \sum_{k_{2}=0}^{M} V_{k_{2}}(\textcolor{FireBrick}{r_3}) \;\cdot\; \prod_{j=1}^{d} p_j\!\left(\textcolor{grey}{\epsilon_{k_1}, \epsilon_{k_2}, \epsilon_{k_3}},\, \ldots, c,\, x\right)
  • After processing 3 challenges

Results

d=2
d=3

                 Toom-cook

                 Schoolbook

Switchover round \(t\)

Factor improvement  \((t_{\textsf{naive}} / t_{\textsf{algo}})\) for \(n=20\)

0.6 \text{ MB}
84 \text{ MB}

Results in Spartan Sumcheck

2-3× speedups for proving the first sum-check of Spartan within Jolt

Sumcheck Optimisations

By Suyash Bagad

Sumcheck Optimisations

  • 28