Skip to content

Commit ee293ed

Browse files
committed
impl + docs
1 parent ef61c7c commit ee293ed

7 files changed

Lines changed: 1127 additions & 14 deletions

File tree

Lines changed: 380 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,380 @@
1+
# Shplemini Masking Lemma
2+
3+
This note states the masking lemma for replacing the current full-size random
4+
`gemini_masking_poly` in the Gemini + Shplonk + KZG PCS transcript.
5+
6+
The proposed replacement is a sparse masking polynomial with $2d$ random
7+
entries placed in a tail-halving layout, where $d = \mathrm{virtual\_log\_n}$.
8+
9+
## Lemma
10+
11+
Let $M$ be the dedicated `gemini_masking_poly`; no relation-bearing witness,
12+
precomputed, lookup, permutation, or shiftable column is used for this mask.
13+
Let $M$ be sampled with $2d$ independent random coefficients on the
14+
tail-halving support defined below, where $d = \mathrm{virtual\_log\_n}$.
15+
16+
Assume the Shplemini Fiat-Shamir challenges avoid the usual denominator-zero
17+
bad events and the tail-halving leakage matrix defined below has rank $2d$.
18+
Then the Gemini + Shplonk + KZG part of Shplemini is zero-knowledge for the
19+
messages masked by $M$.
20+
21+
## Proof
22+
23+
The proof has three steps.
24+
25+
**1. Bound the required rank.** Work in the algebraic / AGM model for KZG: a
26+
commitment $[P]$ is replaced by the scalar leakage $P(\tau)$, where $\tau$ is
27+
the KZG trapdoor. The visible masking messages before Shplonk/KZG derivation
28+
are
29+
30+
$$
31+
M(u),\quad M(\tau),\quad M_1(\tau),\,\ldots,\,M_{d-1}(\tau),\quad
32+
M_0(-r_0),\,\ldots,\,M_{d-1}(-r_{d-1}).
33+
$$
34+
35+
This list has $2d + 1$ entries, but the leakage map
36+
37+
$$
38+
\Phi:\ \mathrm{span}(E_j : j \in S)\ \longrightarrow\ \mathbb{F}^{2d+1}
39+
$$
40+
41+
has domain dimension $|S| = 2d$, so $\mathrm{rank}(\Phi) \le 2d$
42+
automatically. The target of the proof is to show this bound is tight.
43+
44+
`Shplonk:Q` and `KZG:W` add no independent rank. Concretely, Shplonk batches
45+
the opening claims at points $z_t$ with challenge $\nu$:
46+
47+
$$
48+
Q(X) \;=\; \sum_{t} \nu^{\,t}\, \frac{P_t(X) - v_t}{X - z_t},
49+
$$
50+
51+
so the $M$-contribution $Q_M(\tau)$ is a linear combination of the
52+
already-listed scalars $M(\tau)$, $M_t(\tau)$, $M_t(-r_t)$, $M(u)$ with
53+
coefficients that depend only on the Shplonk challenges $(\nu, z_t)$ and the
54+
public points. The KZG quotient is
55+
56+
$$
57+
W(X) \;=\; \frac{G(X)}{X - z},\qquad W_M(\tau) \;=\; \frac{G_M(\tau)}{\tau - z},
58+
$$
59+
60+
again a fixed scalar multiple of a linear combination of the same leakages.
61+
Hence the full transcript leakage from $M$ factors through $\Phi$, and showing
62+
$\mathrm{rank}(\Phi) = 2d$ is sufficient.
63+
64+
**2. Show the layout achieves rank $2d$.** Form the $(2d+1) \times 2d$ matrix
65+
$B$ by applying $\Phi$ to each basis entry in the tail-halving support. The
66+
matrix entries are explicit. Let $E_j$ be the stored coefficient basis vector
67+
with a $1$ in position $j$. After $t$ Gemini folds,
68+
69+
$$
70+
\mathrm{fold}_t(E_j) \;=\; \lambda_t(j)\, E_{\lfloor j / 2^t \rfloor},
71+
\qquad
72+
\lambda_t(j) \;=\; \prod_{a=0}^{t-1}
73+
\begin{cases} 1 - u_a & \text{if } \mathrm{bit}_a(j) = 0,\\ u_a & \text{otherwise.}\end{cases}
74+
$$
75+
76+
The column of $B$ for support entry $s$ is therefore
77+
78+
$$
79+
\Bigl(\,\lambda_d(s),\ \tau^s,\ \lambda_1(s)\,\tau^{\lfloor s/2\rfloor},\ \ldots,\
80+
\lambda_{d-1}(s)\,\tau^{\lfloor s/2^{d-1}\rfloor},\
81+
(-r_0)^s,\ \lambda_1(s)\,(-r_1)^{\lfloor s/2\rfloor},\ \ldots,\
82+
\lambda_{d-1}(s)\,(-r_{d-1})^{\lfloor s/2^{d-1}\rfloor}\,\Bigr)^\top.
83+
$$
84+
85+
This is the Gemini matrix whose rank must be $2d$.
86+
87+
**Analytical rank argument.** Index the support as $d$ pairs, ordered by
88+
level. For $k = 1, \ldots, d-1$ let $\mathrm{pair}_k = (2^k,\ 2^k - 1)$, and
89+
let $\mathrm{pair}_d = (E - 1,\ E - 2)$ (the top tail pair, with $E$ even).
90+
The $d$ rows $M(\tau), M_1(\tau), \ldots, M_{d-1}(\tau)$ of $B$ already
91+
suffice for rank $2d$: we exhibit a block-lower-triangular $2d \times 2d$
92+
submatrix formed from these $d$ rows and the $2d$ support columns.
93+
94+
- For $k < d$, consider row $M_{k-1}(\tau)$, whose entry at column $s$ is
95+
$\lambda_{k-1}(s)\,\tau^{\lfloor s / 2^{k-1}\rfloor}$. For $\mathrm{pair}_k$,
96+
97+
$$
98+
\lfloor 2^k / 2^{k-1}\rfloor = 2,\qquad
99+
\lfloor (2^k - 1) / 2^{k-1}\rfloor = 1.
100+
$$
101+
102+
For any smaller pair $k' < k$, every entry $s' < 2^k$ satisfies
103+
$\lfloor s' / 2^{k-1}\rfloor = 0$. So at row $M_{k-1}(\tau)$, the two
104+
columns of $\mathrm{pair}_k$ contribute $\tau^2$ and $\tau$ while all
105+
smaller pairs contribute only $\tau^0$. The $2 \times 2$ block at the
106+
intersection of row $M_{k-1}(\tau)$ and the two columns of
107+
$\mathrm{pair}_k$ is, up to a non-zero $\lambda$ factor in
108+
$(u_0, \ldots, u_{k-1})$,
109+
110+
$$
111+
\begin{pmatrix}
112+
\lambda_{k-1}(2^k)\,\tau^2 & 0 \\
113+
0 & \lambda_{k-1}(2^k - 1)\,\tau
114+
\end{pmatrix},
115+
$$
116+
117+
after using that the off-diagonal $\tau^0$ entries from smaller pairs sit
118+
in *other* columns. Each $\lambda_{k-1}$ factor is a non-trivial product of
119+
$u_a$ and $(1 - u_a)$, non-zero as a polynomial in $u$.
120+
121+
- For $\mathrm{pair}_d = (E - 1,\ E - 2)$, use row $M(\tau)$ itself: its
122+
entries are $\tau^{E-1}$ and $\tau^{E-2}$, monomials of strictly higher
123+
degree than anything contributed by smaller pairs (which have
124+
$s < N/2 \le E/2$). The corresponding $2 \times 2$ block is diagonal in
125+
$\tau$ with non-zero entries.
126+
127+
Order pairs $k = 1, 2, \ldots, d$. By construction, in the row chosen for
128+
$\mathrm{pair}_k$, all columns of smaller pairs vanish in the relevant
129+
coordinates (they sit at strictly lower $\tau$-degrees). The resulting
130+
$2d \times 2d$ submatrix is block-lower-triangular with $2 \times 2$ diagonal
131+
blocks whose determinants are non-zero monomials in $\tau$ times non-zero
132+
polynomials in $u$. Their product is therefore a non-zero element of
133+
$\mathbb{F}[u_0, \ldots, u_{d-1}, \tau]$, of total degree at most
134+
$2(E - 1) + \sum_{k=0}^{d-1} 2k$.
135+
136+
Hence $\mathrm{rank}(B) = 2d$ over the rational-function field
137+
$\mathbb{F}(u, r, \tau)$, and over $\mathbb{F}$ the bad set of Fiat-Shamir
138+
challenges where rank drops is the zero set of this explicit determinant. By
139+
Schwartz–Zippel the bad-event probability is bounded by $\deg / |\mathbb{F}|$,
140+
which is negligible over the BN254 scalar field. The $r_t$ challenges play no
141+
role in the argument above, so the additional $d$ rows $M_t(-r_t)$ are
142+
redundant for rank — they are used below by the simulator.
143+
144+
**Optional finite-field sanity check.** The script
145+
`shplemini_zk_mask_rank.py` evaluates $B$ at random
146+
$(u, r, \tau) \in \mathbb{F}_{\mathrm{BN254}}^{\,2d+1}$ and confirms full
147+
rank for the supported $d$. Example:
148+
149+
```text
150+
d= 8 halving-tail support size= 16: [(16, 16, 16, 19)]
151+
d=10 halving-tail support size= 20: [(20, 20, 20, 23)]
152+
```
153+
154+
The tuple is (rank of Gemini block, rank after appending `Shplonk:Q` row,
155+
rank after appending `KZG:W` row, total rows in $B$). All three rank values
156+
equal $2d$, confirming that $Q$ and $W$ add no independent rank, as proved in
157+
step 1.
158+
159+
**3. Simulate.** Since $\mathrm{rank}(B) = 2d$, the random coefficients on
160+
$S$ induce a uniform mask over the $2d$-dimensional leakage subspace
161+
$\mathrm{image}(\Phi)$. A simulator with access to $\tau$ samples a uniform
162+
$y \in \mathrm{image}(\Phi)$, solves $B\,c = y$ (uniquely, since $B$ has full
163+
column rank $2d$), and derives consistent `Shplonk:Q` and `KZG:W` from the
164+
same masked Gemini data. Therefore the verifier sees a transcript distributed
165+
independently of the unmasked witness contribution, except with negligible
166+
probability from bad challenge events.
167+
168+
## Layout and implementation
169+
170+
Use a sparse masking polynomial with fixed support:
171+
172+
$$
173+
K = 2d \quad (d = \mathrm{virtual\_log\_n}),\qquad
174+
S = \{ s_0, s_1, \ldots, s_{K-1} \},\qquad
175+
M(X) = \sum_{j \in S} c_j\, E_j(X).
176+
$$
177+
178+
Use the tail-halving support:
179+
180+
$$
181+
N = 2^d,\qquad
182+
e = \mathrm{max\_end\_index}\ \text{of the masked polynomial data},\qquad
183+
E = \min\bigl(N,\ \mathrm{round\_up}(e, 2)\bigr),
184+
$$
185+
186+
$$
187+
S = \bigl[\,E - 1,\ E - 2,\ N/2,\ N/2 - 1,\ N/4,\ N/4 - 1,\ \ldots,\ 2,\ 1\,\bigr],
188+
$$
189+
190+
truncated or deterministically tail-filled to exactly $2d$ entries. In code:
191+
192+
```text
193+
E = min(N, round_up(e, 2))
194+
add(E - 1)
195+
add(E - 2)
196+
for level = 1 .. d - 1:
197+
base = N >> level
198+
add(base)
199+
add(base - 1)
200+
fill from E - 1 downward until len(S) = 2d, skipping duplicates
201+
```
202+
203+
The intuition is that these entries sit on different paths of the Gemini
204+
folding tree. Pairing each chosen position with its neighbor gives the fold at
205+
that level both an even and odd component, rather than letting later folds see
206+
only constants or repeated low-degree fragments.
207+
208+
The rounding is important: Gemini's first fold groups $(0,1)$, $(2,3)$,
209+
$\ldots$ as even/odd pairs. If $e$ is odd, the entries $e - 1$ and $e - 2$ are
210+
not in the same first-fold pair. Rounding to even makes $(E - 2, E - 1)$ one
211+
pair. This keeps the masking extent close to the existing maximum extent
212+
instead of always forcing $\mathrm{end\_index}() = N$.
213+
214+
The polynomial should retain virtual size $n$:
215+
216+
```text
217+
start = min(S)
218+
length = max(S) - min(S) + 1
219+
Polynomial masking_poly(length, n, start)
220+
```
221+
222+
where `start`, `length`, and the populated entries are determined by the
223+
selected support. This simple representation has $\mathrm{end\_index}() = E$,
224+
because the top pair is $E - 1,\ E - 2$. That cost is acceptable as a first
225+
implementation: it is one masking polynomial among many committed
226+
polynomials, and Pippenger commitment time depends mainly on the number of
227+
non-zero scalars rather than the virtual size.
228+
229+
The final proof should have the same transcript shape as today. Only the
230+
internal representation of the masking polynomial changes from full random to
231+
sparse random.
232+
233+
## IPA variant
234+
235+
The IPA setting has a different leakage model from KZG. There is no scalar
236+
trapdoor $\tau$. Instead, view every IPA group message algebraically, in the
237+
basis consisting of the CRS generators and the IPA auxiliary generator $U$.
238+
239+
For the dyadic case $N = 2^d$, use the support
240+
241+
$$
242+
S_{\mathrm{ipa}} \;=\; \{N - 4,\ N - 3,\ N - 2,\ N - 1\}
243+
\,\cup\, \bigcup_{q=1}^{d-1} \{2^q - 2,\ 2^q - 1,\ 2^q,\ 2^q + 1\},
244+
$$
245+
246+
with entries outside $[0, N-1]$ and duplicates removed. This is the "four
247+
adjacent entries around every dyadic cut" layout.
248+
249+
### Lemma
250+
251+
Let $M = \sum_{s \in S_{\mathrm{ipa}}} c_s\, E_s$ be the dedicated Gemini
252+
masking polynomial, with the $c_s$ sampled independently and uniformly.
253+
Assume:
254+
255+
1. $N = 2^d$;
256+
2. Fiat-Shamir challenges avoid the usual denominator-zero bad events;
257+
3. the CRS generators and the IPA auxiliary generator are algebraically
258+
independent for the rank argument.
259+
260+
Then the Gemini + Shplonk + IPA transcript is zero-knowledge for the messages
261+
masked by $M$, except on a proper algebraic bad set of Fiat-Shamir challenges.
262+
263+
### Proof
264+
265+
All transcript entries contributed by $M$ are linear in the coefficients
266+
$(c_s)_{s \in S_{\mathrm{ipa}}}$ once the challenges are fixed. It is
267+
therefore enough to show that the linear leakage map has rank
268+
$|S_{\mathrm{ipa}}|$.
269+
270+
The Gemini part is explicit. For a basis vector $E_j$, after $t$ Gemini folds,
271+
272+
$$
273+
\mathrm{fold}_t(E_j) \;=\; \lambda_t(j)\, E_{\lfloor j / 2^t\rfloor},\qquad
274+
\lambda_t(j) \;=\; \prod_{a=0}^{t-1}
275+
\begin{cases} 1 - u_a & \text{if } \mathrm{bit}_a(j) = 0,\\ u_a & \text{otherwise.}\end{cases}
276+
$$
277+
278+
**Shplonk batching is full-rank on the coefficient side.** Shplonk batches
279+
the Gemini opening claims at points $z_t \in \{r,\ -r_0,\ \ldots,\ -r_{d-1}\}$
280+
with challenge $\nu$:
281+
282+
$$
283+
A(X) \;=\; \sum_{t} \nu^{\,t}\, \frac{M_t(X) - M_t(z_t)}{X - z_t}.
284+
$$
285+
286+
After IPA folding, the prover opens $A(X)$ at a single point. As a function
287+
of $c$, the coefficient vector of $A \in \mathbb{F}[X]_{< N}$ is a linear map
288+
$\Psi: \mathbb{F}^{S_{\mathrm{ipa}}} \to \mathbb{F}^N$.
289+
290+
Isolate the $t = 0$ summand, which uses $M_0 = M$ directly. The identity
291+
$\frac{X^s - z_0^s}{X - z_0} = \sum_{k=0}^{s-1} z_0^{\,s-1-k}\, X^k$ shows
292+
that the $E_s$-column of $\Psi$ has coefficient $\nu^0 \cdot 1 = 1$ at
293+
degree $X^{s-1}$, and any other column $E_{s'}$ with $s' < s$ contributes
294+
$0$ at $X^{s-1}$ (since $s'-1 < s-1$). Higher-$t$ summands use folded
295+
polynomials $M_t$ of degree $< N/2^t$, so they contribute only to
296+
$X^{k}$ for $k < N/2^t - 1 \le N/2 - 1 < s - 1$ once $s \ge N/2$, and more
297+
generally cannot raise the top-degree column entry above $X^{s-1}$.
298+
299+
Order $S_{\mathrm{ipa}}$ by decreasing $s$ and read the rows $X^{s-1}$ for
300+
$s \in S_{\mathrm{ipa}}$. The induced $|S_{\mathrm{ipa}}| \times
301+
|S_{\mathrm{ipa}}|$ submatrix of $\Psi$ is upper-triangular with diagonal
302+
$1$, hence has full rank $|S_{\mathrm{ipa}}|$ identically — no Shplonk
303+
challenge specialization can drop it. In particular, the four support
304+
entries around every dyadic cut remain linearly independent before IPA
305+
starts, and the Shplonk step contributes no bad events to the ZK error.
306+
307+
Now write the IPA folding map. If the current vector has length $2^m$, one
308+
IPA round splits it as
309+
310+
$$
311+
a = (a_{\mathrm{low}},\ a_{\mathrm{high}}),
312+
$$
313+
314+
$$
315+
L = \langle a_{\mathrm{low}},\ G_{\mathrm{high}}\rangle
316+
+ \langle a_{\mathrm{low}},\ b_{\mathrm{high}}\rangle\, U,
317+
\qquad
318+
R = \langle a_{\mathrm{high}},\ G_{\mathrm{low}}\rangle
319+
+ \langle a_{\mathrm{high}},\ b_{\mathrm{low}}\rangle\, U,
320+
$$
321+
322+
$$
323+
a' = a_{\mathrm{low}} + \rho\, a_{\mathrm{high}}.
324+
$$
325+
326+
After $t$ IPA folds, a basis vector $E_j$ maps to
327+
328+
$$
329+
\mathrm{ipa}_t(E_j) \;=\; \mu_t(j)\, E_{\,j \bmod 2^{d-t}},
330+
$$
331+
332+
where $\mu_t(j)$ is the product of the IPA round challenges selected by the
333+
high bits of $j$.
334+
335+
Consider the dyadic cut at $2^q$. The four support entries
336+
$2^q - 2$, $2^q - 1$, $2^q$, $2^q + 1$ are the last two entries on one side
337+
of that cut and the first two entries on the other side. At the IPA round
338+
whose split separates this cut, the first two entries contribute to $L$ in
339+
two distinct $G_{\mathrm{high}}$ coordinates, and the second two entries
340+
contribute to $R$ in two distinct $G_{\mathrm{low}}$ coordinates. These four
341+
coordinates are algebraically independent of all later IPA messages and of
342+
the $U$ coordinates.
343+
344+
Order the dyadic cuts from the largest split to the smallest split, and for
345+
each cut select the four generator coordinates just described. A support
346+
entry chosen for a larger cut is already isolated before smaller-cut
347+
coordinates are examined. A support entry chosen for a smaller cut has not
348+
yet contributed to the selected coordinates of the larger cuts. The selected
349+
submatrix is therefore block triangular, with one full-rank $4 \times 4$
350+
block for each dyadic cut, up to the duplicate/removal effects at the
351+
boundary of $[0, N-1]$. The top tail block $\{N - 4, N - 3, N - 2, N - 1\}$
352+
is handled the same way at the outermost IPA split.
353+
354+
Thus the IPA leakage matrix has rank $|S_{\mathrm{ipa}}|$ over the field of
355+
rational functions in the challenges. Specializing the challenges only lowers
356+
rank on the zero set of a non-zero determinant minor. The masking
357+
coefficients therefore induce a uniform mask over the full independent
358+
leakage subspace. A simulator samples that leakage, solves the full-rank
359+
linear system for the $c_s$, and derives the Gemini, Shplonk, and IPA
360+
messages from the same masked opening vector. This gives the claimed
361+
zero-knowledge statement.
362+
363+
## Checks before implementation
364+
365+
Before replacing the full random polynomial, add tests that:
366+
367+
1. Build the matrix $B$ for many random samples of $(u, r, \tau)$ and verify
368+
rank $2d$ for the selected fixed support.
369+
2. Prove and verify ordinary Shplemini tests with the sparse mask.
370+
3. Tamper independently with:
371+
- `Gemini:masking_poly_comm`,
372+
- one `Gemini:FOLD_i`,
373+
- one `Gemini:a_i`,
374+
- `Shplonk:Q`,
375+
- `KZG:W`,
376+
377+
and verify rejection.
378+
4. Include at least one ZK flavor with `RepeatedCommitmentsData`, since the
379+
verifier offsets assume the masking commitment is the first unshifted PCS
380+
entity after `Shplonk:Q`.

0 commit comments

Comments
 (0)