# Soundness Failures in LaBRADOR Implementations from NTT -Friendly Rings

- **Authors**: Georgios Raikos
- **Date**: April 30, 2026
- **Tags**: zk, pqc, lattice

![Labrador Bugs](https://blog.zksecurity.xyz/posts/labrador-bugs/labrador-bugs.jpg)

[Recent advances in quantum algorithms](https://www.quantamagazine.org/new-advances-bring-the-era-of-quantum-computers-closer-than-ever-20260403/) have pushed post-quantum cryptography into the spotlight. Amidst rising concerns, cryptography engineers will now have to navigate this transition, with the [standardization efforts](https://csrc.nist.gov/projects/post-quantum-cryptography) from recent years as a guide. And while the area of public key encryption has (with good reason) been the primary focus of such efforts, other areas, such as post-quantum proof systems, remain active but still open research areas.

Lattice-based proof systems fall into this category. Research-wise, many new protocols have been proposed in recent years. However, there are still very few (if any) production-ready libraries implementing them, and no real-world deployments at scale as of yet. And while parameter selection is always mentioned in the papers, the slightest ambiguity can mislead implementers and lead to catastrophic results.

In a [previous post](https://blog.zksecurity.xyz/posts/labrador/), we saw the [LaBRADOR](https://eprint.iacr.org/2022/1341) proof system. In this post, we'll see that **three implementations of LaBRADOR are broken**. Interestingly, we'll see that the instinct to use NTT-friendly rings, a widely recommended choice for efficiency in lattice-based cryptography, breaks the soundness of the protocol.

The following table lists various LaBRADOR implementations found on GitHub. Some of the affected libraries are not production-ready, so by "soundness bits" we only refer to the impact of the insecure ring selection we explore in this post.

| Library                                                             | Language | Affected | Soundness bits         | Note                                                                                                                                                                       |
|---------------------------------------------------------------------|----------|----------|------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Lazarus](https://github.com/lattice-complete/Lazarus/)             | Rust     | Yes      | **1 bit**              |                                                                                                                                                                            |
| [condor-rs](https://github.com/NethermindEth/condor-rs)             | Rust     | Yes      | **$\approx$ 6 bits**   |                                                                                                                                                                            |
| [icicle-labrador](https://github.com/ingonyama-zk/icicle-labrador/) | C++      | Yes      | **$\approx$ 31 bits**  |                                                                                                                                                                            |
| [lattirust/labrador](https://github.com/lattirust/labrador)         | Rust     | No*      | **$\approx$ 18 bits*** | * The core protocol is not directly affected, as there are no hard-coded parameters. However, the parameters selected for an example in the repository have the same flaw. |
| [lattice-dogs/labrador](https://github.com/lattice-dogs/labrador)   | C        | No       | 128 bits               |                                                                                                                                                                            |
| [lazer](https://github.com/lazer-crypto/lazer)                      | C        | No       | 128 bits               |                                                                                                                                                                            |

## The ring pitfalls

Polynomial rings are ubiquitous in lattice-based cryptography, mainly for the efficient multiplication enabled by the NTT transform. The ring used by LaBRADOR is of the form:
$$
\mathcal{R}*{q}:\; \mathbb{Z}*{q}[X] / (X^d + 1)
$$
We can view the ring elements as polynomials with degree at most $d-1$, with coefficients in $\mathbb{Z}_{q}$.

It is natural for researchers to translate techniques from the "classic" proof systems literature, usually operating over finite fields, to lattice-based proof systems, operating over polynomial rings. Indeed, LaBRADOR uses such a technique: **random linear combinations** to aggregate the prover's claims into a single claim.

### The first random linear combination (over scalars)

The first such occurrence in the protocol is in the aggregation of constant term constraints ([ePrint, p.12](https://eprint.iacr.org/2022/1341.pdf#page=12)). In the simplified protocol:

- The verifier samples random vectors of scalars: $\vec{\psi} \stackrel{\$}{\gets} \mathbb{Z}*{q}^{L}, \vec{\omega} \stackrel{\$}{\gets} \mathbb{Z}*{q}^{256}$.
- The prover uses them as random coefficients to compute the linear combination over the claims.
- If the result is equal to zero, then the constraints are satisfied *with probability $1-p$*.

What exactly is the probability $p$ that a cheating prover passes the check here? To get an upper bound, we assume a maximally cheating prover. There will, thus, be a claim $(v_{\text{cheating}} - v_{\text{expected}}) \neq 0 \in \mathbb{Z}*{q}$, but to pass: $\omega ' (u*{\text{cheating}} - u_{\text{expected}}) = 0$[1](#fn:wlog-omega). Since $\omega'$ is uniformly random in $\mathbb{Z}_{q}$, this happens with probability $1 /q$ for any prover, **assuming $q$ is a prime**. Crucially, the LaBRADOR paper on [ePrint](https://eprint.iacr.org/2022/1341.pdf) is not explicit about $q$ needing to be a prime, but implicitly assumes it. 

With this implicit assumption, the paper specifies $q \approx 2^{32}$. 32 bits of soundness is not considered secure, so it proceeds with soundness amplification to 128 bits by executing multiple rounds of this aggregation. The number of rounds with a target of 128 bits is computed as:
$$
k = \left\lceil  \frac{128}{\log q}  \right\rceil 
$$
Notice that $q$ is assumed to provide $\log q$ bits of soundness, implicitly treating $q$ as a prime again. If $q$ were composite, $\mathbb{Z}_{q}$ would be a ring, not a field, so it would contain zero divisors. In that case the probability **is not** simply $1/ q$, and we would have to take into account the specific modulus $q$.

### The second random linear combination (over the ring)

The second critical step utilizing a random linear combination for batch-checking constraints is in the final constraint aggregation step ([ePrint, p.12-13](https://eprint.iacr.org/2022/1341.pdf#page=12)). In this case, the randomly sampled coefficients are **ring elements**. Again, we simplify the protocol:

- The verifier samples $\boldsymbol{\alpha}*{k}, \boldsymbol{\beta}*{k} \stackrel{\$}{\gets} \mathcal{R}_{q}$.
- The prover uses them as random coefficients to compute the linear combination of all the constraints, and combine them into one final check.
- If the result is equal to zero, then the constraints are satisfied *with probability $1-p$*.

Here, the probability $p$ is not straightforward to see. The cheater would pass the check if $\boldsymbol{\alpha}*{k'}(\mathbf{u}*{\text{cheating}}-\mathbf{u}*{\text{expected}}) = \mathbf{0} \in \mathcal{R}*{q}$, with $(\mathbf{u}*{\text{cheating}} - \mathbf{u}*{\text{expected}}) \neq \mathbf{0}$.[2](#fn:wlog-alpha) In this case, we need to analyze the polynomial ring and its zero divisors in detail.

LaBRADOR is explicit with regards to the polynomial ring: $q, d$ are selected such that $X^d+1$ splits into **exactly two irreducible** factors $\mod q$. Thus, we have the isomorphism:
$$
\frac{\mathbb{Z}*{q}[X]}{X^d+1} \cong \frac{\mathbb{Z}*{q}[X]}{P_{1}(x)} \times \frac{\mathbb{Z}*{q}[X]}{P*{2}(x)}
$$

where $q$ and $d$ are chosen so that $P_{1}, P_{2}$ are both irreducible polynomials $\mod q$ of degree $d /2$.

In simpler terms, we can view a ring element $\boldsymbol{\alpha} \in \mathcal{R}*{q}$ as a tuple $(\boldsymbol{\alpha}*{1}, \boldsymbol{\alpha}*{2}) \in (\mathcal{R}*{1} \times \mathcal{R}*{2})$. Now, multiplication over $\mathcal{R}*{q}$ can be seen as entry-wise multiplication in the tuple form.

A cheating prover in this case can construct $(\mathbf{u}*{\text{cheating}} - \mathbf{u}*{\text{expected}}) = (\mathbf{0}, \mathbf{u}') \in \mathcal{R}*{1}\times \mathcal{R}*{2}$. Since $q$ **is prime** and $P_{1}, P_{2}$ **are irreducible** $\mod q$, there are no zero divisors in either of these two rings[3](#fn:extension-fields). As a result, the check will only pass if the randomly sampled $\boldsymbol{\alpha}*{k} = (\boldsymbol{\alpha}*{1}, \mathbf{0}) \in \mathcal{R}*{1}\times \mathcal{R}*{2}$. That is, we only care about the second "slot", which needs to be $\mathbf{0}$ to "cancel out" the $\mathbf{u'}$, and result in the product: $(\mathbf{0} \cdot \boldsymbol{\alpha}_{1}, \mathbf{u}'\cdot \mathbf{0}) = (\mathbf{0}, \mathbf{0})$.

This is equal to the probability of randomly drawing the zero ring element in $\mathcal{R}*{2}$, which is a polynomial of degree $d/ 2$ with all coefficients in $\mathbb{Z}*{q}$ equal to zero. Thus, $p = \frac{1}{q^{d/2}}$, which is negligible.[4](#fn:biggest-slot) 

#### The NTT pitfall

Recall that the Number Theoretic Transform can be seen as an isomorphism between the coefficient form of a polynomial and its evaluations over the $2d$-th roots of unity $\zeta^i$:
$$
\frac{\mathbb{Z}*{q}[X]}{X^d + 1} \cong \prod*{i=0}^{d-1} \frac{\mathbb{Z}*{q}[X]}{X-\zeta^{2i+1}} \cong \mathbb{Z}*{q}^{d}
$$
Whether a polynomial ring supports this transform depends on the modulus $q$ and the degree $d$: for this specific ring, $2d$ must divide $q-1$, assuming $q$ is a prime. When the NTT is supported, the ring **splits fully** into the smallest possible rings, polynomial rings with a quotient polynomial of degree 1. 

Notice that, as we saw earlier, the security of the random linear combination depends on the order of the smallest ring factor. In the NTT-friendly case, **this will be $q$ instead of the $q^{d/2}$ required by the LaBRADOR paper.** 

## Falling in the pitfalls

### Power-of-2 modulus - The deadly sin of [Lazarus](https://github.com/lattice-complete/Lazarus/)

The ring that Lazarus uses is:
$$
\mathcal{R}: \mathbb{Z}_{2^{32}}[X] / (X^{64}+1)
$$

#### Wrong number of aggregation steps

Recall that the number of aggregation steps for constant term constraint aggregation is computed as:
$$
k = \left\lceil  \frac{128}{\log q}  \right\rceil 
$$
with the **implicit assumption that $q$ is prime**. In this case, however, $q=2^{32}$. 

For the first random linear combination, the random coefficients are sampled from $\mathbb{Z}*{2^{32}}$. Thus, a cheating prover can construct $(u*{\text{cheating}} - u_{\text{expected}}) = 2^{31}$. Now, the check will pass if:
$$
\begin{align}
\omega'\cdot(u_{\text{cheating}} - u_{\text{expected}}) &= 0 \pmod q \
\implies \omega' \cdot 2^{31} &= 0 \pmod{ 2^{32}}
\end{align}
$$
Thus, **any even $\omega'$** will result in: $2\ell\cdot {2}^{31} = 2^{32} \cdot \ell = 0 \mod 2^{32}$. **The cheater passes the check with probability $\frac{1}{2}$!**

The soundness amplification will not account for this; the aggregation steps are still computed as defined previously, with $\log q$ as denominator. There will be $k=4$ rounds of aggregation, with every round achieving only 1 bit of soundness, so the total soundness will **be only 4 bits**, instead of the target 128 bits.

#### Insecure linear combination over rings

The soundness of the second random linear combination, the one over rings, collapses in similar fashion. The simplified check is $\mathbf{u} \cdot \boldsymbol{\alpha} = \mathbf{0}$, with $\mathbf{u} \neq \mathbf{0}$ controlled by the prover and $\boldsymbol{\alpha}$ the random challenge sampled by the verifier.

For the ring Lazarus chooses, the malicious prover can construct the polynomial with all coefficients being $2^{31}$. Let $\vec{u}$ be the vector of coefficients:
$$
\vec{u} = (2^{31}, 2^{31}, \dots, 2^{31}) \in \left(  \mathbb{Z}*{2^{32}}\right)^{64}
$$
The ring multiplication is essentially polynomial multiplication $\mod (X^{64} +1)$. The coefficients of the product $\mathbf{c} = \mathbf{u} \cdot \boldsymbol{\alpha}$ can be computed by using a negacyclic convolution over the coefficient vectors. Each coefficient $c*{k}$ will be:
$$
c_{k} = \left( \sum_{i=0}^{k} u_{i} \cdot a_{k-i} \right)  - \left( \sum_{i=k+1}^{63} u_{i} \cdot a_{64+k-i} \right) 
$$
Since $\vec{u} = (2^{31}, \dots, 2^{31})$:
$$
\begin{align}
c_{k} &= \left( \sum_{i=0}^{k} 2^{31} \cdot a_{k-i}  \right) - \left( \sum_{i=k+1}^{63} 2^{31} \cdot a_{64+k-i} \right) =  \
& = 2^{31} \cdot \left( \sum_{i=0}^{k}a_{k-i} - \sum_{i=k+1}^{63} a_{64+k-i} \right)
\end{align}
$$

Let $P = \sum_{i=0}^{k}a_{k-i}$ and $N = \sum_{i=k+1}^{63} a_{64+{k}-i}$. Then:
$$
\begin{align}
c_{k} &=  2^{31} \left( P - N \right)  = 2^{31} (P + N - 2N) =  \
&= 2^{31}(P+N) - 2^{32}N = 2^{31}(P+N) \pmod{2 ^{32}}
\end{align}
$$

But, $P+N$ is the sum of all the coefficients of $\boldsymbol{\alpha}$:
$$
P+N = \sum_{i=0}^{k}a_{k-i} + \sum_{i=k+1}^{63}a_{64+k - i} = \sum_{i=0}^{63}a_{i}
$$

Finally, the product coefficients will be:
$$
c_{k} = 2^{31} \cdot \sum_{i=0}^{63} a_{i}
$$
Notice the similarity with the cheating prover of the previous section: once again, $2^{31}$ is used to exploit the modulus being $2^{32}$. Now, since $\boldsymbol{\alpha}$ is uniformly random, the sum of its coefficients is even with probability $\frac{1}{2}$. That is, for some integer $\ell$:
$$
c_{k} = 2^{31} \cdot 2 \cdot \ell = 2^{32} \cdot \ell = 0 \pmod{2^{32}}
$$
Since all coefficients are zero, $\mathbf{c} = \mathbf{0} \in \mathcal{R}$. Thus, the cheating prover **will once again pass the check with probability $1 /2$**. This is a devastating result, since there are no soundness amplification rounds here. **The soundness of the full protocol will be only 1 bit!**

> [!note] Lazarus - Summary
>
> - Power-of-2 modulus $q$ causes half of the elements in $\mathbb{Z}_{q}$ to be zero divisors. 
> - This compromises both aggregation steps (**only 4 bits** of soundness in constant term aggregation, **only 1 bit** of soundness in final aggregation).

In the remaining three affected libraries ([icicle-labrador](https://github.com/ingonyama-zk/icicle-labrador/), [condor-rs](https://github.com/NethermindEth/condor-rs), [lattirust/labrador](https://github.com/lattirust/labrador) only in an example), the selected ring is insecure because it splits into smaller rings, either fully, through intentional support of NTT, or partially, through the Chinese Remainder Theorem and NTT on the ring factors.

### CRT+NTT - The deadly sin of [icicle-labrador](https://github.com/ingonyama-zk/icicle-labrador/), [condor-rs](https://github.com/NethermindEth/condor-rs), and [lattirust/labrador](https://github.com/lattirust/labrador) (almost)

#### icicle-labrador

[icicle-labrador](https://github.com/ingonyama-zk/icicle-labrador/) selects $d=64$ and the modulus $q$ to be a composite, the product of the KoalaBear prime and the BabyBear prime:
$$
q = p_{kb} \cdot p_{bb}
$$
where:
$$
\begin{align}
& p_{kb} = 2^{31} - 2^{24} + 1  \
& p_{bb} = 2^{31} - 2^{27} + 1
\end{align}
$$

##### Wrong number of aggregation steps

Once again, the composite $q$ hurts the constant term aggregation. The number of steps $k$ is computed in the code with $\log q \approx 62$, so $k=3$. But, with $q$ being a composite, the soundness provided by each step will be $\approx 31$ bits. Thus, the resulting soundness of the aggregation **will be 93 bits** instead of the target 128.

##### Insecure linear combination over rings

The biggest harm to the soundness of the linear combination of the ring comes from the two ring factors supporting NTT. [icicle-labrador](https://github.com/ingonyama-zk/icicle-labrador) intentionally picks such a ring, for efficient polynomial multiplication. But, by combining the Chinese Remainder Theorem and the NTT, we have the following isomorphism for this ring:
$$
\frac{\mathbb{Z}*{q}[X]}{X^{64}+1} \cong \frac{\mathbb{Z}*{p_{kb}}[X]}{X^{64}+1} \times \frac{\mathbb{Z}*{p*{bb}}[X]}{X^{64}+1}

\cong \mathbb{Z}*{p*{kb}}^{64} \times \mathbb{Z}*{p*{bb}}^{64} \cong\mathbb{Z}_{q}^{64} 
$$

The ring splits fully, and the smallest factor will now be $\mathbb{Z}*{p*{bb}}$. A malicious prover can now construct:
$$
\vec{u} = (\kappa \cdot p_{kb}, 0, \dots, 0) \in \mathbb{Z}*{q}^{64}
$$
This can also be seen as having only one non-zero slot in the CRT representation. Now, the check will pass if the randomly drawn $\boldsymbol{\alpha}$ has a coefficient in $\mathbb{Z}*{q}$ in this slot that is a multiple of $p_{bb}$:
$$
\mathbf{u} \cdot \boldsymbol{\alpha} = (\kappa \cdot p_{kb} \cdot l \cdot p_{bb}, 0, \dots, 0) = (\kappa \cdot l \cdot q, 0, \dots, 0) = (0, \dots, 0) \in \mathbb{Z}*{q}^{64}
$$
There are $p*{kb}$ multiples of $p_{bb}$ in $\mathbb{Z}*{q}$, so the probability of the check passing will be:
$$
\frac{p*{kb}}{p_{bb} \cdot p_{kb}} = \frac{1}{p_{bb}}
$$
Thus, the soundness of this random linear combination is **only $\approx 31$ bits**.

> [!note] icicle-labrador - Summary
>
> - Composite modulus $q$ and NTT-friendly ring factors chosen for efficiency make the ring split fully, with a base ring of an insufficiently big order.
> - Both aggregation steps are affected, with the final aggregation step compromising the protocol, offering **only 31 bits** of soundness.

#### condor-rs

The modulus selected by [condor-rs](https://github.com/NethermindEth/condor-rs) has a similar flaw. Specifically:
$$
q = 2^{32}-1 = 3 \cdot 5 \cdot 17 \cdot 257 \cdot 65537
$$

##### Wrong number of aggregation steps

Once again, $q$ is not a prime. The smallest ring factor of $\mathbb{Z}*{q}$ is $\mathbb{Z}*{3}$, thus the soundness of a single round is only $\frac{1}{3}$, $\approx 1.58$ bits. But again, in computing $k$, $\log q$ is used. Thus:
$$
k = \left\lceil  \frac{128}{\log q}  \right\rceil = 4
$$
The resulting soundness of all the rounds **will be only $\approx 6$ bits**, instead of the target 128.

##### Insecure linear combination over rings

Similarly to [icicle-labrador](https://github.com/ingonyama-zk/icicle-labrador), we can first use the CRT isomorphism:
$$
\frac{\mathbb{Z}_{q}[X]}{X^{64}+1} \cong

\frac{\mathbb{Z}*{3}[X]}{X^{64}+1} \times
\frac{\mathbb{Z}*{5}[X]}{X^{64}+1} \times
\frac{\mathbb{Z}*{17}[X]}{X^{64}+1} \times
\frac{\mathbb{Z}*{257}[X]}{X^{64}+1} \times
\frac{\mathbb{Z}*{65537}[X]}{X^{64}+1} 
$$
Notice that $\frac{\mathbb{Z}*{257}[X]}{X^{64}+1}$ supports the NTT. Thus:
$$
\frac{\mathbb{Z}*{257}[X]}{X^{64}+1} \cong \mathbb{Z}*{257}^{64}
$$

which results in the original ring splitting:
$$
\frac{\mathbb{Z}_{q}[X]}{X^{64}+1} \cong

\frac{\mathbb{Z}*{3}[X]}{X^{64}+1} \times
\frac{\mathbb{Z}*{5}[X]}{X^{64}+1} \times
\frac{\mathbb{Z}*{17}[X]}{X^{64}+1} \times
\mathbb{Z}^{64}*{257} \times
\frac{\mathbb{Z}_{65537}[X]}{X^{64}+1} 
$$

We can now see that the smallest ring factor is $\mathbb{Z}*{257}$. The cheating prover can construct $\mathbf{u}$ in a similar manner to the previous section, by only having one non-zero slot in $\mathbb{Z}*{257}$. Then, the check will pass with probability $\frac{1}{257}$. **That is only $\approx 8$ bits of soundness.**

> [!note] condor-rs - Summary
>
> - Composite modulus $q$ has many small factors, among which $257$. The polynomial ring factor resulting from CRT with base ring $\mathbb{Z}_{257}$ is NTT-friendly.
> - Both aggregation steps are affected (**only 6 bits** of soundness because of the small factor in the first step, **only 8 bits** because of CRT + NTT-friendly ring factor).

#### lattirust/labrador

[lattirust/labrador](https://github.com/lattirust/labrador) does not have this issue at its core, since the implementation of LaBRADOR is decoupled from the actual choice of parameters. The pitfalls above, however, are still there, as the implementation allows similar insecure parameters. For the number of aggregation steps, $k$ is again computed with $\log{q}$ as the denominator, implicitly assuming that $q$ is prime.

The test included in the repository does, indeed, have insecure parameters, similar to [icicle-labrador](https://github.com/ingonyama-zk/icicle-labrador). Specifically,
$$
q = q_{1} \cdot q_{2}
$$
where:
$$
\begin{align}
& q_{1} = 274177 \
& q_{2} = 67280421310721
\end{align}
$$
For the constant term aggregation, the soundness will be $\approx 36$ bits, after 2 rounds of $\approx 18$ bits each.

As for the random linear combination over the ring, both resulting rings $\frac{\mathbb{Z}*{q*{1}}[X]}{X^{64}+1}$ and $\frac{\mathbb{Z}*{q*{2}}[X]}{X^{64}+1}$ support NTT. The smallest ring factor will be $\mathbb{Z}*{q*{1}}$, and similarly to before, with a cheating prover the check will pass with probability $\frac{1}{q_{1}}$, resulting in only $\approx 18$ bits of soundness.

> [!note] lattirust/labrador - Summary
>
> - Composite modulus $q$ and NTT-friendly ring, similar to icicle-labrador.
> - Both aggregation steps are affected (**only 36 bits** of soundness in the first step, **only 18 bits** because of CRT + NTT-friendly ring).

### A quick note on exploiting the pitfalls in practice

The slot-wise view of the ring elements is helpful to see why the soundness analysis of the random linear combination over rings breaks down when the ring splits. In practice, this is not trivial. Manipulating a single slot in the evaluation domain (slot-wise, that is) causes a blow-up in the coefficient form, and LaBRADOR only allows "short" witnesses. As a consequence, the forged proof would fail verification because of the shortness check, even though the aggregation check would pass.

To see how the theoretical attack translates to a proof-of-concept attack, we could instead focus on a family of statements. In LaBRADOR, the simplified $\mathbf{u}$ is actually:
$$
\sum_{i,j=1}^{r} \mathbf{a}*{ij}^{(k)}\langle \vec{\mathbf{x}}*{i}, \vec{\mathbf{x}}*{j} \rangle  + \sum*{i=1}^{r}\langle \vec{\boldsymbol{\phi}}*{i}, \vec{\mathbf{x}} \rangle - \mathbf{b}^{(k)}
$$
This equation encodes one constraint. We can focus on the families of statements where there are no cross-term constraints ($\mathbf{a}*{ij} = \mathbf{0}$), and where the "trap" of the malicious prover (e.g., the multiple of $p_{kb}$ in the icicle-labrador section) is part of the statement $\vec{\boldsymbol{\phi}}$. Intuitively, by picking a slightly different cheating witness, the difference between the cheating and expected values will have the desired properties slot-wise (they were "encoded" in the statement), while the cheating witness will still be short. Both the shortness check and the random linear combination check would pass, resulting in a forged proof.

## Final notes

In this post, we saw how protocols over polynomial rings can be challenging to implement securely. Parameters chosen for efficient ring multiplication may unexpectedly lead to soundness issues, and the slightest ambiguity can mislead implementers into making the wrong choice, highlighting once again the merits of standardization.

For an approach that leverages the NTT optimization while maintaining the security guarantees of the protocol, we highly recommend reading [this paper by Chung et al.](https://tches.iacr.org/index.php/TCHES/article/view/8791)

---

1. 
$\omega$ is selected without loss of generality; analysis is similar for $\psi$.qq3936677670287331zz[zz1337820767766393qq](#fnref:wlog-omega)

   $\omega$ is selected without loss of generality; analysis is similar for $\psi$.qq3936677670287331zz[zz1337820767766393qq](#fnref:wlog-omega)
2. 
$\boldsymbol{\alpha}*{k'}$ is selected without loss of generality; analysis is similar for $\boldsymbol{\beta}*{k'}$.qq3936677670287331zz[zz1337820767766393qq](#fnref:wlog-alpha)

   $\boldsymbol{\alpha}*{k'}$ is selected without loss of generality; analysis is similar for $\boldsymbol{\beta}*{k'}$.qq3936677670287331zz[zz1337820767766393qq](#fnref:wlog-alpha)
3. 
They are extension fields $\mathbb{F}_{q^{d/2}}$.qq3936677670287331zz[zz1337820767766393qq](#fnref:extension-fields)

   They are extension fields $\mathbb{F}_{q^{d/2}}$.qq3936677670287331zz[zz1337820767766393qq](#fnref:extension-fields)
4. 
Of course, in this case the cheating prover could pick any of the two rings. In the general case, however, they would pick the ring with the biggest order to be the $\mathbf{0}$ slot to maximize their advantage.qq3936677670287331zz[zz1337820767766393qq](#fnref:biggest-slot)

   Of course, in this case the cheating prover could pick any of the two rings. In the general case, however, they would pick the ring with the biggest order to be the $\mathbf{0}$ slot to maximize their advantage.qq3936677670287331zz[zz1337820767766393qq](#fnref:biggest-slot)

---

This article was published on the [ZK/SEC Quarterly](https://blog.zksecurity.xyz) blog by [ZK Security](https://www.zksecurity.xyz), a leading security firm specialized in zero-knowledge proofs, MPC, FHE, and advanced cryptography. ZK Security has audited some of the most critical ZK systems in production, discovered vulnerabilities in major protocols including Aleo, Solana, and Halo2, and built open-source tools like [Clean](https://github.com/Verified-zkEVM/clean) for formally verified ZK circuits. For more articles, see the [full list of posts](https://blog.zksecurity.xyz/llms.txt).
