Sampling Module-LWE Instances: A Reference Reproduction
A small, readable reference that samples Module-LWE instances over a power-of-two cyclotomic ring, as a fixture for size and timing experiments.
Before measuring anything about structured-lattice schemes, it helps to have a small, unambiguous generator for the underlying hard instances. This note gives a reference sampler for the Module Learning With Errors (Module-LWE) distribution and nothing more — no scheme, no optimization, just a fixture.
The distribution
Work over the cyclotomic ring with a power of two. A Module-LWE sample of rank is a pair drawn as follows: a uniform vector , a fixed secret , and a small error combine into the second coordinate.
where each coefficient of and is drawn from a small centered distribution (here, a centered binomial). The hardness assumption is that is computationally indistinguishable from for .
A reference sampler
The implementation mirrors the equation line for line: sample uniformly, sample and from , and form in the ring.
import numpy as np
def cbd(eta, shape, rng):
"""Centered binomial distribution with parameter eta."""
a = rng.integers(0, 2, size=(*shape, eta)).sum(-1)
b = rng.integers(0, 2, size=(*shape, eta)).sum(-1)
return a - b
def ring_mul(f, g, q, n):
"""Multiply in Z_q[x]/(x^n + 1) via the negacyclic convolution."""
full = np.convolve(f, g)
lo, hi = full[:n], full[n:]
res = lo.copy()
res[: hi.size] -= hi # x^n = -1
return res % q
def sample_mlwe(k, n, q, eta, rng):
a = rng.integers(0, q, size=(k, n)) # a ~ U(R_q^k)
s = cbd(eta, (k, n), rng) % q # s_i <- chi
e = cbd(eta, (n,), rng) % q # e <- chi
b = np.zeros(n, dtype=np.int64)
for i in range(k):
b = (b + ring_mul(a[i], s[i], q, n)) % q # b = a^T s + e
return a, (b + e) % q
rng = np.random.default_rng(20260603)
a, b = sample_mlwe(k=2, n=256, q=3329, eta=2, rng=rng)
print(a.shape, b.shape) # (2, 256) (256,)
The parameters above (, , ) are deliberately the ML-KEM-512 ring, so the fixture lines up with a real scheme — but this code makes no security claim. It exists to be counted and timed, which is what the Assumption Diversification measurements need next.