mirror of
https://github.com/lux-apps/papers.git
synced 2026-11-03 05:07:46 +00:00
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.
57 lines
1.9 KiB
TeX
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}
|
|
|
|
%% ============================================================
|