Files
zeekayandHanzo Dev 178febad68 papers: reconcile T-Chain -> M-Chain / F-Chain / B-Chain per LP-134
Every rendered "T-Chain" / "ThresholdVM" / "teleportvm" reference across
the paper corpus is rewritten to the correct canonical chain by concern:
threshold signing / MPC / bridge custody / key recovery -> M-Chain (MVM);
FHE / encrypted compute / threshold decryption -> F-Chain (FVM); teleport
/ cross-chain messaging -> B-Chain (bridgevm); consensus Pulsar stays
Q-Chain. Section lux-trust-kernel/03-t-chain-threshold-governance.tex
renamed -> 03-f-chain-encrypted-policy.tex (with \input + xref fixes).
Braided "T-Chain" sections split by concern (M vs F). Only lp-020's
chain-separation rationale and the shared lux/chains/thresholdvm library
path retain the name, to record the removal. All changed papers rebuilt
(pdflatex, rc=0, no undefined refs).

§09 of lux-dao-governance-framework reframed: fabricated "production
deployment" metrics ($50M/$240k/$12M, survey %s, "as of Oct 2024")
relabeled as illustrative design configurations with no invented
replacements; reality noted (DAO treasury is a 1/1 Safe); conclusion
echo + one "first production" overclaim softened.

This commit also captures concurrent corpus workstreams on the same tree.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-02 00:57:09 -07:00

191 lines
9.1 KiB
TeX

\section{Pulsar: Module-LWE threshold finality}
\label{sec:pulsar}
\paragraph{Canonical status (\texttt{pulsar v1.7.1}).} This section
describes the original two-round lattice kernel at the 48-bit Ringtail
parameter set. The \emph{shipped} canonical Pulsar is now byte-equal to
FIPS-204 ML-DSA (prime $q = 8380417$, ML-DSA-65 / ML-DSA-87) and verifies
under the \emph{stock} FIPS-204 verifier; its threshold output is one
$\sim 3.3$~KB (ML-DSA-65) or $\sim 4.6$~KB (ML-DSA-87) signature, not the
$\sim 33$~KB $(c,z,\Delta)$ kernel certificate below. Key generation is
dealerless via Mithril short replicated secret sharing, and signing is
no-reconstruct (the hyperball three-round signer,
$\mathbf{z}_j = \mathbf{y}_j + c\,\mathbf{s}_1^{(j)}$); no trusted dealer
at either end. Lux Pulsar's repeated-subsampling committee model (a
technique analogous to Avalanche's repeated small-sample consensus,
applied here to lattice threshold signing) samples many small
RSS committees (default $n{=}8$, $t{=}7$, with $m{=}12$ committees and an
$r{=}8$-of-$m$ acceptance rule, $P_{\text{fail}} \approx 2^{-60}$) rather
than a single $n{=}64$ committee. See LP-073~\cite{lp073} for the canonical
construction; the 48-bit kernel exposition below is retained as the shared
mechanism Pulsar holds in common with Corona.
\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. Aggregate size is the \emph{byte-equal
FIPS-204 ML-DSA signature} (the shipped canonical output), not the
$\sim 33$~KB 48-bit-kernel certificate. The BCC/CEF byte-equal threshold
supports ML-DSA-65 and ML-DSA-87 only: ML-DSA-44's $c\mathbf{s}_2$ /
$c\mathbf{t}_0$ bound is out of scope (LP-073).}
\label{tab:pulsar-levels}
\begin{tabular}{lrrr}
\toprule
Variant & Module $(k,\ell)$ & Aggregate size & Use case \\
\midrule
Pulsar-44 & $(4,4)$ & $\approx$ 2.4 KB & out of scope for byte-equal (kernel/devnet only) \\
Pulsar-65 & $(6,5)$ & $\approx$ 3.3 KB & production finality lane \\
Pulsar-87 & $(8,7)$ & $\approx$ 4.6 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 is out of scope for the
byte-equal threshold (the mode restriction of LP-073) and survives only as
a 48-bit-kernel devnet stress-testing variant.
\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 the following (this
single-committee sizing illustrates the kernel; the canonical
repeated-subsampling model instead samples many small $n{=}8$, $t{=}7$
committees with an $r$-of-$m$ acceptance rule, per the note opening this
section and LP-073~\cite{lp073}):
\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).