Files
papers/lux-lattice-cryptography-primer/sections/07-corona-threshold-lattice-signatures.tex
zooqueen ac61e71667 Reconcile Corona/Pulsar taxonomy: both are Module-LWE
Scrub residual Ring-LWE mislabels of the Corona/Pulsar threshold
signature family per canonical decision-b (source: ringtail/sign/config.go
M=8,N=7, q=0x1000000004A01).

- Corona = Module-LWE (Ringtail-derived parameter set, A in R_q^{8x7}),
  not Ring-LWE / not "Module-LWE at rank 1".
- Pulsar = Module-LWE (ML-DSA-65, FIPS-204 byte-equal).
- Corona+Pulsar differ by parameter regime/codebase, NOT hardness family:
  intra-lattice parameter/implementation diversity, NOT family-disjoint.
- True family-disjoint defense = Magnetar (hash, SLH-DSA) / HQC (codes).

Reframed the false Corona(R-LWE)-vs-Pulsar(M-LWE) family-independence
across lp-219/lp-220/lp-222/lp-223 (P3Q kinds), lux-quasar-composition
(profile hardness table + composition corollary/proof), lux-magnetar-pq,
and the superseded triple-proof/quasar drafts (anonymous lattice
threshold lane = Corona). Legitimate FHE/TFHE Ring-LWE, NTT citations,
and neutral "rank-1" lattice facts left intact. PDFs rebuilt.
2026-06-20 02:26:47 -07:00

57 lines
1.9 KiB
TeX

\section{Pulsar: Threshold Lattice Signatures}
Pulsar is Lux Network's threshold signature scheme based on Module-LWE
(threshold ML-DSA-65, byte-equal to FIPS-204). It allows
$t$-of-$n$ validators to collaboratively sign messages without any single validator
holding the full secret key.
\subsection{Design Challenges}
Threshold ML-DSA is hard because of rejection sampling: each signer's partial
signature must independently pass the norm bound, and the combined signature must also
pass. Naive approaches have exponentially low success probability as $t$ grows.
Pulsar addresses this through:
\begin{enumerate}[nosep]
\item \textbf{Expanded masking range}: Each signer uses a larger $\gamma_1$ to ensure
individual rejection rarely triggers.
\item \textbf{Aggregation-friendly bounds}: The combined norm bound accounts for the sum
of $t$ partial signatures.
\item \textbf{Share refresh}: Proactive secret sharing allows periodic refresh of shares
without changing the group public key.
\end{enumerate}
\subsection{Key Distribution}
\begin{lstlisting}[language=Go,caption={Pulsar key generation via Shamir's secret sharing over $R_q$}]
func DistributeKey(n, t int) (PublicKey, []SecretShare) {
// Generate master secret
s := sampleSecret()
// Shamir's secret sharing over the ring R_q
// f(x) = s + a_1*x + ... + a_{t-1}*x^{t-1}
coeffs := make([]RingElement, t)
coeffs[0] = s
for i := 1; i < t; i++ {
coeffs[i] = sampleRing()
}
// Evaluate polynomial at n points
shares := make([]SecretShare, n)
for i := 0; i < n; i++ {
xi := ringFromScalar(uint32(i + 1))
shares[i] = SecretShare{
Index: i + 1,
Value: evaluatePoly(coeffs, xi),
}
}
// Public key from master secret
pk := computePublicKey(s)
return pk, shares
}
\end{lstlisting}
%% ============================================================