mirror of
https://github.com/lux-apps/papers.git
synced 2026-10-30 18:15:21 +00:00
- Pulsar-M qualifier retired (Pulsar is the Module-LWE family; LP-180 rename af3d669). Pulsar-M-65/-87 -> Pulsar-65/-87; sec rename 07-pulsar-m -> 07-pulsar. - Dead repos luxfi/[email protected], luxfi/pulsar-mptc (both 404) -> luxfi/pulsar. - subnet -> chain/L1, Subnet-EVM -> Lux EVM, subnet VM -> L1 VM. - PULSAR-MAC-v1 and other domain-sep constants left intact (lookahead-protected).
170 lines
7.3 KiB
TeX
170 lines
7.3 KiB
TeX
\section{Q-Chain finality: the 23-axis binding}
|
|
\label{sec:qchain-finality}
|
|
|
|
\subsection{What Q-Chain binds}
|
|
|
|
Q-Chain is the chain that produces finality certificates over every other
|
|
chain in the Lux ecosystem. HIP-0079 defines Q-Chain as the
|
|
``post-quantum finality plane'': it consumes EpochCommitments from every
|
|
execution chain (C-Chain, P-Chain, X-Chain, Z-Chain), folds them into a
|
|
canonical QBlock, and produces a Pulsar finality certificate over the
|
|
QBlock digest.
|
|
|
|
The QBlock digest is the single 48-byte commitment that says ``this is the
|
|
state of the Lux Network at epoch $N$ under LUX\_STRICT\_E2E\_PQ.''
|
|
Everything else --- the bridge admission, the cross-chain Warp envelope, the
|
|
Z-Chain commitment binding into a \texttt{TxAuthEnvelope} verification ---
|
|
ultimately points back to this digest.
|
|
|
|
\subsection{The 23 axes}
|
|
|
|
\texttt{ComputeRoundDigest} (\texttt{luxfi/consensus@12097034},
|
|
\texttt{protocol/qchain/round\_digest.go}) binds 23 axes into the QBlock
|
|
hash. The axes are the security-relevant inputs to consensus at this round:
|
|
|
|
\begin{table}[H]
|
|
\centering
|
|
\caption{ComputeRoundDigest axes. The 23 axes are the inputs to consensus
|
|
at a single round. Adding an axis bumps the customization
|
|
\texttt{LUX\_QBLOCK\_V1 $\to$ V2} and is a hard fork.}
|
|
\label{tab:qblock-axes}
|
|
\begin{tabular}{rlp{8cm}}
|
|
\toprule
|
|
\# & Axis & Role \\
|
|
\midrule
|
|
1 & \texttt{ProfileHash} & ChainSecurityProfile digest. \\
|
|
2 & \texttt{Version} & QBlock version. \\
|
|
3 & \texttt{NetworkID} & destination network. \\
|
|
4 & \texttt{Epoch} & monotonic epoch counter. \\
|
|
5 & \texttt{Height} & Q-Chain height. \\
|
|
6 & \texttt{PrevBlockHash} & parent QBlock digest. \\
|
|
7 & \texttt{CChainCommitment} & C-Chain EpochCommitment digest. \\
|
|
8 & \texttt{PChainCommitment} & P-Chain EpochCommitment digest. \\
|
|
9 & \texttt{XChainCommitment} & X-Chain EpochCommitment digest. \\
|
|
10 & \texttt{ZChainCommitment} & Z-Chain EpochCommitment digest (\texttt{ZRegistryRoots.Hash()}). \\
|
|
11 & \texttt{ValidatorSetRoot} & active validator set Merkle root. \\
|
|
12 & \texttt{ValidatorStakeRoot} & per-validator stake commitment. \\
|
|
13 & \texttt{BridgeAdmissionRoot} & bridge admission state root. \\
|
|
14 & \texttt{TxAuthBatchRoot} & accepted \texttt{TxAuthEnvelope} root for epoch. \\
|
|
15 & \texttt{PermitBatchRoot} & accepted \texttt{PQPermit} root for epoch. \\
|
|
16 & \texttt{ZIdentityRoot} & shortcut into \texttt{ZRegistryRoots.IdentityRoot}. \\
|
|
17 & \texttt{P3qProofRoot} & p3q STARK proof aggregator root for this epoch. \\
|
|
18 & \texttt{RandomnessSeed} & DRBG seed for this epoch. \\
|
|
19 & \texttt{PrevFinalityCert} & previous epoch's Pulsar cert digest. \\
|
|
20 & \texttt{Timestamp} & uint64 epoch timestamp (UTC seconds). \\
|
|
21 & \texttt{LineageRoot} & lineage chain digest (HIP-0079 ยง5). \\
|
|
22 & \texttt{GovernanceRoot} & active governance state root. \\
|
|
23 & \texttt{ExtraHash} & 48-byte HIP-future-reserved digest. \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\end{table}
|
|
|
|
Every axis except \texttt{ExtraHash} is consumed by some downstream
|
|
verifier. \texttt{ExtraHash} is reserved for future HIP additions: future
|
|
proposals will bind new axes into the \texttt{ExtraHash} preimage so the
|
|
QBlock layout itself stays stable across the migration window.
|
|
|
|
\subsection{ComputeRoundDigest}
|
|
|
|
The construction:
|
|
|
|
\begin{lstlisting}[language=Go,caption={\texttt{ComputeRoundDigest} for
|
|
QBlock. Source: \texttt{luxfi/consensus@12097034},
|
|
\texttt{protocol/qchain/round\_digest.go}.}]
|
|
func (q *QBlock) ComputeRoundDigest() [48]byte {
|
|
parts := [][]byte{
|
|
[]byte("Lux/QBlock/v1"),
|
|
q.ProfileHash[:],
|
|
u16BE(q.Version),
|
|
u32BE(q.NetworkID),
|
|
u64BE(q.Epoch),
|
|
u64BE(q.Height),
|
|
q.PrevBlockHash[:],
|
|
q.CChainCommitment[:], q.PChainCommitment[:],
|
|
q.XChainCommitment[:], q.ZChainCommitment[:],
|
|
q.ValidatorSetRoot[:], q.ValidatorStakeRoot[:],
|
|
q.BridgeAdmissionRoot[:],
|
|
q.TxAuthBatchRoot[:], q.PermitBatchRoot[:],
|
|
q.ZIdentityRoot[:], q.P3qProofRoot[:],
|
|
q.RandomnessSeed[:],
|
|
q.PrevFinalityCert[:],
|
|
u64BE(q.Timestamp),
|
|
q.LineageRoot[:],
|
|
q.GovernanceRoot[:],
|
|
q.ExtraHash[:],
|
|
}
|
|
return tupleHash48(parts, "LUX_QBLOCK_V1")
|
|
}
|
|
\end{lstlisting}
|
|
|
|
The Pulsar finality lane (Section~\ref{sec:pulsar}) signs over this
|
|
digest. The signature, together with the QBlock body, is the finality
|
|
certificate.
|
|
|
|
\subsection{Canonical QBlock layout}
|
|
|
|
The QBlock body is the wire-serialised form of the struct above plus the
|
|
finality certificate. The wire layout is deterministic big-endian, fixed-width
|
|
except for the certificate trailer:
|
|
|
|
\begin{table}[H]
|
|
\centering
|
|
\caption{QBlock wire layout. The fixed header is 1{,}080 bytes; the
|
|
certificate trailer is the Pulsar aggregate plus committee bitmap, sized
|
|
per the active committee (typically $\approx 33$ KB).}
|
|
\begin{tabular}{lll}
|
|
\toprule
|
|
Offset & Size & Field \\
|
|
\midrule
|
|
0 & 48 & \texttt{profile\_hash} \\
|
|
48 & 2 & \texttt{version} \\
|
|
50 & 4 & \texttt{network\_id} \\
|
|
54 & 8 & \texttt{epoch} \\
|
|
62 & 8 & \texttt{height} \\
|
|
70 & 48 & \texttt{prev\_block\_hash} \\
|
|
118 & 48 & \texttt{cchain\_commitment} \\
|
|
$\vdots$ & $\vdots$ & $\vdots$ (per Table~\ref{tab:qblock-axes}) \\
|
|
1{,}072 & 8 & \texttt{timestamp} \\
|
|
1{,}080 & varies & \texttt{finality\_cert} (Pulsar-65 aggregate + bitmap) \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\end{table}
|
|
|
|
\subsection{Finality cert binding to Pulsar}
|
|
|
|
The Pulsar finality lane (Section~\ref{sec:pulsar}) operates as a
|
|
two-round threshold signature scheme over the 43-of-64 active committee.
|
|
Round 1 commitments hash the QBlock digest as their session id. Round 2
|
|
opens partial signatures that aggregate linearly into a single 33-KB
|
|
certificate. The verifier:
|
|
|
|
\begin{enumerate}[leftmargin=2em,nosep]
|
|
\item Recomputes the QBlock digest from the body.
|
|
\item Looks up the active committee against
|
|
\texttt{ValidatorSetRoot}.
|
|
\item Verifies the Pulsar aggregate signature over the digest under the
|
|
committee's group public key (which is itself anchored in
|
|
\texttt{ZRegistryRoots.IdentityRoot} from the Z-Chain).
|
|
\item Confirms the committee bitmap has at least 43 set bits.
|
|
\end{enumerate}
|
|
|
|
Step 2 binds the certificate's committee to the consensus state \emph{at
|
|
this epoch}. Step 3 verifies the lattice math. Step 4 enforces the
|
|
threshold. The certificate is binding under MLWE.
|
|
|
|
\subsection{Why 23 axes specifically}
|
|
|
|
The 23-axis count is the minimum closure of the dependency graph between
|
|
the Lux chains. Each axis is the only commitment from \emph{one} subsystem
|
|
the verifier needs to confirm that subsystem's state matches what the QBlock
|
|
claims. Dropping any axis would force a downstream verifier to consult the
|
|
subsystem's own state instead of the QBlock, breaking the ``QBlock is the
|
|
single binding'' invariant.
|
|
|
|
Adding axes is forward-compatible via the \texttt{ExtraHash} reservation;
|
|
the next HIP that adds axes binds them into the \texttt{ExtraHash} preimage
|
|
and ships an \texttt{ExtraHashV2} struct with the customization
|
|
\texttt{LUX\_QBLOCK\_EXTRA\_V2}. The QBlock layout itself does not change
|
|
until the migration window closes and a hard-fork to \texttt{LUX\_QBLOCK\_V2}
|
|
absorbs the new fields directly.
|