Files
papers/lp-stricte2epq/sections/07-pulsar.tex
zooqueen ebe2ebcb3c papers: retire boschini2024corona key -> ringtail (third-party prior art); fix Pulsar/Corona/Ringtail provenance + lattice labels
Ringtail (Boschini et al., ePrint 2024/1113) is third-party prior art; Lux's
Corona (Ring-LWE = Module-LWE rank-1) builds on it; Pulsar is Module-LWE rank-k.
Retired the conflated boschini2024corona/corona2024/coronago/... bib keys to the
single canonical ringtail/corona/pulsar/magnetar keys, rewrote \cite + \bibitem
by context, and fixed 'Pulsar (Ring-LWE)' mislabels (Corona where corona.metal/
single-ring/Ringtail-derived; Pulsar where Module-LWE rank-k/ML-DSA). Cryptographer-led.
2026-06-19 22:33:10 -07:00

165 lines
7.3 KiB
TeX

\section{Pulsar: Module-LWE threshold finality}
\label{sec:pulsar}
\subsection{Why Pulsar and not BLS}
The finality lane in classical Lux Quasar 3.0 \cite{lp020} was BLS12-381
\cite{bls}: a 48-byte aggregate that closes a block in sub-second. BLS is the
right shape (linear aggregation, small certificate, short verification) but
the wrong primitive: it falls to Shor.
Pulsar is the PQ replacement. It is a two-round threshold signature over
the cyclotomic ring $R_q = \mathbb{Z}_q[X]/(X^\varphi+1)$ with $\varphi=256$
and a 48-bit NTT-friendly prime $q$. The structure mirrors FROST
\cite{frost}: Round 1 is offline, Round 2 binds the message, partial
signatures aggregate linearly. The lattice instantiation is closest to the
two-round threshold ML-DSA family \cite{tmldsa2025,dttf2024} but tracks the
hint-bound discipline of \cite{ringtail}.
The reference implementation is \texttt{luxfi/pulsar}. The
production canonical exposes \texttt{keygen}, \texttt{sign}, \texttt{verify},
\texttt{threshold}, \texttt{dkg}, \texttt{reshare}, and \texttt{abort}
operations.
\subsection{Three security levels}
Pulsar ships three security levels:
\begin{table}[H]
\centering
\caption{Pulsar security levels. Parameters from
\texttt{luxfi/pulsar/parameters.go}.}
\label{tab:pulsar-levels}
\begin{tabular}{lrrr}
\toprule
Variant & Module rank & Aggregate size & Use case \\
\midrule
Pulsar-44 & 4 & $\approx$ 22 KB & devnet / fuzzing only \\
Pulsar-65 & 6 & $\approx$ 33 KB & production finality lane \\
Pulsar-87 & 8 & $\approx$ 44 KB & high-value treasury / governance \\
\bottomrule
\end{tabular}
\end{table}
The strict-PQ profile pins \texttt{FinalitySchemeID = Pulsar-65} and
\texttt{HighValueSchemeID = Pulsar-65 or Pulsar-87}. Pulsar-44 is
\emph{forbidden} on locked profiles --- it exists for devnet stress testing
where the 22 KB cert and faster signing cost matter more than the 128-bit
security floor.
\subsection{Two-round protocol}
The protocol structure (Algorithm~\ref{alg:pulsar-two-round}) is
near-identical to the original Pulsar family \cite{lp073}; the difference is
the choice of NTT modulus and the hint-bound discipline. We sketch the
construction; the reference impl carries the byte-exact specification.
\begin{algorithm}
\caption{Pulsar-65 two-round signing}
\label{alg:pulsar-two-round}
\begin{algorithmic}[1]
\Require committee $\mathcal{C}$ of $n=64$ parties; threshold $t=43$
\Require message $m$ (typically the QBlock digest, Sec.~\ref{sec:qchain-finality})
\Require group public key $(\mathbf{A}, \tilde{\mathbf{b}})$ from DKG
\Require each party holds Shamir share $\mathbf{s}_i$
\State \textbf{Round 1 (offline, per party $i$):}
\State \hspace{1em} sample masking matrix $\hat{R}_i$ from Discrete-Gaussian $\sigma_E$
\State \hspace{1em} broadcast $D_i = \mathbf{A} \cdot \hat{R}_i + \hat{E}_i$
\State \hspace{1em} attach BLAKE3-keyed MAC $\textsc{MAC}_{i \to j}$ for each peer $j$
\State \textbf{Round 2 (online, per party $i$):}
\State \hspace{1em} aggregate $D = \sum_j D_j$
\State \hspace{1em} derive challenge vector $u = \textsc{GaussianHash}(D, m, \texttt{ctx})$
\State \hspace{1em} derive ternary challenge $c = \textsc{ChallengeHash}(u, m)$
\State \hspace{1em} compute partial signature $z_i = \mathbf{s}_i \cdot c + \hat{R}_i$
\State \hspace{1em} broadcast $z_i$
\State \textbf{Finalise:}
\State \hspace{1em} aggregate $z = \sum_i z_i$ (linear, no coordinator)
\State \hspace{1em} produce hint $\Delta$ in $R_\nu$
\State \hspace{1em} output certificate $(c, z, \Delta, \text{bitmap})$
\end{algorithmic}
\end{algorithm}
The verifier (\texttt{luxfi/pulsar/verify.go}) reconstructs
$\mathbf{A} z - \tilde{\mathbf{b}} c$ in the rounded-coefficient hint domain
$R_\nu$, applies the per-coefficient $\Delta$ correction, and accepts iff the
$L_2$ bound holds. The bitmap is the indicator vector for which parties
contributed --- at least 43 of 64 must be set.
The threshold $t=43$ is chosen against $n=64$ to give:
\begin{itemize}[leftmargin=2em,nosep]
\item BFT margin: $t > 2n/3$ closes the standard Byzantine quorum.
\item Identifiable abort: $n - t = 21$ allows up to 21 non-contributing
parties to be identified without aborting the round.
\item Lattice slack: the hint discipline tolerates $t$-of-$n$ aggregation
without rejection-sampling rerolls in the $\eta_\varepsilon = 2.65$ slack
regime.
\end{itemize}
\subsection{Identifiable abort}
A party that misbehaves in Round 1 (publishes a malformed $D_i$, fails its
MAC) or Round 2 (publishes a malformed $z_i$) is identified by the protocol
without halting the round. The reference impl exposes the
\texttt{abort} interface (\texttt{luxfi/pulsar/abort.go}) that
returns the identifier of the misbehaving party. The consensus engine then
ejects the party from the active committee and slashes their stake.
This is critical for liveness: a BLS threshold signature that fails to
aggregate has no identifiable culprit and the whole round must be re-run.
Pulsar rounds make progress against $n - t$ misbehaving parties without
re-runs, which is the practical difference between sub-second finality and
multi-second finality under partial failure.
\subsection{No BLS fallback}
The strict-PQ profile sets \texttt{ForbidFallbacks = true}. This bit
specifically refuses the ``fall back to BLS if Pulsar times out'' design
the early Quasar drafts considered. The reasoning: a Shor-capable adversary
could trigger Pulsar failure on purpose to force the fallback path, then
forge under BLS. Refusing the fallback closes the attack at the cost of
slower finality during a Pulsar misconfiguration.
The replacement for the BLS fallback is the identifiable-abort path above:
slow-but-correct under failure, not fast-but-classical.
\subsection{DKG and reshare}
Validator-set rotation requires resharing the Pulsar secret to a new
committee. The reference impl exposes \texttt{dkg}
(\texttt{luxfi/pulsar/dkg.go}) and \texttt{reshare}
(\texttt{reshare.go}). The DKG is a Pedersen-style protocol over $R_q$ with
hiding / binding proofs, closely following the construction in
\cite{krt24,gks24}. Reshare uses the LSS framework \cite{luxlssmpc} so the
group public key $(\mathbf{A}, \tilde{\mathbf{b}})$ is preserved across
the committee transition.
The activation certificate (HIP-0078 ยง6) gates each committee transition on
a Pulsar signature verifying under the unchanged group public key.
Activation proves the new committee \emph{can sign} before the old committee
loses signing capability; complaint and slashing-evidence pipelines are
independent.
\subsection{Reference impl status}
\texttt{luxfi/pulsar} ships:
\begin{itemize}[leftmargin=2em,nosep]
\item \texttt{keygen}: long-term signing key generation.
\item \texttt{sign}: single-party signing under a non-threshold key
(for testing).
\item \texttt{verify}: standalone verifier.
\item \texttt{threshold}: the two-round protocol of
Algorithm~\ref{alg:pulsar-two-round}.
\item \texttt{dkg}: distributed key generation.
\item \texttt{reshare}: secret-share resharing across committee
transitions.
\item \texttt{abort}: identifiable-abort detection.
\end{itemize}
Every operation has KAT (known-answer tests) vectors in the
\texttt{testdata/} directory. The KATs are generated by the reference impl
itself and cross-checked against the C++ port (\texttt{luxfi/pulsar-cpp},
in development) and against the GPU kernels (\texttt{luxfi/p3q-gpu} for the
NTT subroutines).