True no-reconstruction threshold SLH-DSA is impossible in the no-dealer /
no-preprocessing model a public, leaderless, permissionless chain needs
(Kondi-Kumar-Vanegas: extractable hash-based signatures cannot be thresholded
by black-box hash use). Stop pretending otherwise.
De-cheat:
- DELETE the circular/vacuous proofs that manufactured false assurance:
Magnetar_N1_Atom_Refinement.ec, Magnetar_N1_SHAKE_Expand.ec,
Magnetar_N4_KeyDeriveStable.ec, lemmas/{Magnetar_CT,SLHDSA_Functional}.ec.
The headline "strict-atom byte-equality" theorem was `apply <axiom that
restates the theorem>`; the Lean side was `sorry`/`:= True`.
- Re-open MAGNETAR-STRICT-ATOM (BLOCKERS): the public combiner DOES
reconstruct the full FIPS 205 master every signature; the v1.1 "closure"
only renamed identifiers. PROOF-CLAIMS / AXIOM-INVENTORY / TCB docs now say
what the code does.
- Re-label the name-grep "strict-atom" / "CT" checks as identifier-hygiene
lint, NOT security or constant-time properties.
- PVSS-DKG open-reveal (publishes the master to any observer) is gated as a
TEST-ONLY path with HONEST LIMITATIONS; production does not rely on it.
- Remove dead htRootCompute; staticcheck clean.
Honest three-leg posture (SPEC 1.0, BLOCKERS):
- Permissionless production = INDEPENDENT FIPS 205 sigs + the weighted quorum
certificate (luxfi/consensus), optionally STARK/FRI-compressed (luxfi/p3q).
No key sharing, no reconstruction.
- Trusted-hardware custody = TEE-attested combiner (trust-relocation, NOT MPC).
- THBS-SE = RESEARCH-ONLY (transient seed reconstruction at the combiner);
the T-SLH-DSA-MPC track (MPC over SHAKE) is the other research escape hatch.
Tests green (CGO=1, 71s). Net -923 lines.
11 KiB
Magnetar --- Deployment runbook
Operator-facing deployment guidance for Magnetar v1.0. READ THIS BEFORE DEPLOYING.
0. Choose your primitive
Magnetar v1.0 ships TWO distinct signing primitives with different trust models. Picking the wrong one is the single largest deployment risk.
| Primitive | Trust model | No-leak / sound | Use case |
|---|---|---|---|
ValidatorSign + VerifyAggregateCert (per-validator standalone, standalone.go) |
Per-validator standalone keys, no shared seed, NO reconstruction | YES (SOUND) | Lux public-BFT validator quorum (PRODUCTION DEFAULT) |
TEE-attested combiner pool (luxfi/threshold/protocols/slhdsa-tee) |
Seed reconstructed INSIDE a measured enclave on t hosts; trust-relocation (adds a host to the TCB), NOT MPC | YES under attested-hardware trust | Opt-in custody / single-signature certificates |
NewThbsSeKey + ThbsSeRound1 + Combine (THBS-SE, thbsse.go) |
t-of-n committee, public combiner that RECONSTRUCTS the full FIPS 205 master every signature | NO --- RESEARCH-GRADE; whoever runs Combine sees the seed (a host IS effectively in the TCB) | Permissionless threshold ONLY where the combiner host is trusted by policy. NOT no-leak. |
Quick decision
-
Public-BFT consensus on a Lux chain (mainnet, testnet, devnet, white-label) --> per-validator standalone. The consensus layer collects N validator signatures into a
ValidatorAggregateCertand counts valid signers; the quorum policy decision lives at the consumer. Wire cost isN x |sigma|; Z-Chain Groth16 rollup compresses to ~192 bytes. -
Permissionless threshold signing for verifier-side single-signature certificates --> THBS-SE. Read sec 2 below for the v1.0 honest open item on transient seed reconstruction at the public combiner.
-
HSM-attested MPC custody (M-Chain bridge custody, A-Chain confidential compute) --> NOT in this package. Operator-controlled MPC custody uses TEE-attestation-gated variants shipped under
luxfi/threshold/protocols/{slhdsa,mldsa,rlwe}-teevia thelux/mpcsibling tree.
1. Per-validator standalone (production primary)
1.1 Keygen
Each validator runs PerValidatorKeypair ONCE on its own host:
sk, pk, err := magnetar.PerValidatorKeypair(params, rng)
paramsSHOULD bemagnetar.ParamsM192s(smallest signatures at NIST PQ category 3, >=192-bit classical security). UseParamsM192fonly if signing latency is the dominant constraint and you can absorb the 2.2x larger signature; useParamsM256sonly if you need category 5 (>=256-bit classical security).rngSHOULD becrypto/rand.Reader(nil also works; the function defaults tocrypto/rand.Reader). Pass a deterministic reader ONLY for KAT reproducibility.
Persist (sk, pk) durably. Losing sk means dropping out of the
quorum until rotating to a fresh keypair. Standard HSM-backed key
storage applies; CIRCL slhdsa private keys are ~96 bytes at
ModeM192s.
Register pk in the validator-set commitment via the consensus
layer's normal key-registration ceremony.
1.2 Signing
sig, err := magnetar.ValidatorSign(sk, nil, message)
Pass nil for the RNG to get the deterministic variant (FIPS 205
SignDeterministic). The output is the raw params.SignatureSize
bytes; the consensus layer's wire format wraps them.
Bind chain-id / block-height / consensus epoch into the message
upstream of this call --- the consensus layer's transcript-hash
pattern handles this (see luxfi/consensus QuasarCert).
1.3 Verification
cert, _ := magnetar.BuildAggregateCert(params, signers, pubKeys, sigs)
count, err := magnetar.VerifyAggregateCert(cert, message, knownValidators)
if count >= quorumThreshold { ... }
knownValidatorsis the consensus layer's authoritativeNodeID -> pubkeymap.- The function returns the COUNT of valid signers. Unknown / pubkey-mismatched signers are counted as INVALID (not fatal --- a defense against impersonation that does not abort the entire batch).
- The quorum decision lives at the consumer.
2. THBS-SE (permissionless threshold)
2.1 v1.0 honest open item
THBS-SE v1.0 routes the final FIPS 205 byte production via a PUBLIC
COMBINER that holds the seed for the duration of one
slhdsa.SignDeterministic call and zeroizes. The combiner role is
PUBLIC --- anyone can be the combiner --- and there is no
long-lived secret material outside party-local Shamir leaves.
This is materially stronger than a TEE-attested privileged-aggregator model (no host is in the TCB; the combiner is a pure function any peer can run on its own substrate).
This is materially weaker than the strict invariant "no party or
combiner EVER reconstructs SK.seed, even transiently in memory" ---
a peer-local memory-disclosure adversary at exactly the combine
moment could observe the seed. The strict-atom-assembly path is the
v1.1 work item tracked at
BLOCKERS.md::MAGNETAR-STRICT-ATOM-V11.
Operational implications. If your threat model includes "peer-local memory-disclosure adversary at the precise sub-second combine moment," do NOT deploy THBS-SE v1.0 for new committee ceremonies. Either:
- Wait for v1.1 strict-atom-assembly.
- Route the threshold signing via the TEE-attested variants at
luxfi/threshold/protocols/slhdsa-tee(operator-controlled MPC custody, host in TCB by policy). - Use per-validator standalone instead --- the public-BFT primary has no seed reconstruction at any point.
2.2 Setup
key, err := magnetar.NewThbsSeKey(params, threshold, committee, setupRng)
paramsand the thresholdtare the same shape as per-validator standalone.committeeMUST be sorted ascending byNodeIDwith distinct non-zero IDs.setupRngdefaults tocrypto/rand.Reader.
v1.0 reference uses a deterministic-dealer setup. The dealer is in
the TCB FOR SETUP ONLY; once NewThbsSeKey returns, no party
(including the dealer) holds the master seed. The returned
*ThbsSeKey carries: the public key PublicKey, the per-party
shares Shares[], the setup transcript SetupTranscript, and
metadata (Threshold, N, Params).
Production deployments needing the leaderless PVSS-DKG variant
route through the sibling luxfi/threshold DKG package; that
DKG produces shares in the SAME wire-shape envelope. See
BLOCKERS.md::MAGNETAR-PVSS-DKG-V11 for the v1.1 closure path.
2.3 Signing rounds
Each party runs:
r1, r2, err := magnetar.ThbsSeRound1(params, share, binding, msg, guard, rng)
bindingis the slot tuple(chain_id, epoch, slot, height, committee_id, message_domain).guardis a*ThbsSeSlotGuardthe party persists across calls.- Idempotent replay: re-calling with the same
(binding, msg)returns the persisted(r1, r2). A genuine equivocation attempt (same slot, different message) returns*ThbsSeEquivocationErrorcarrying slashable evidence.
The party broadcasts r1 (the commit) and, after the Round-1
quorum is observable, r2 (the reveal).
2.4 Combine
Any peer (validator, block proposer, RPC node, passive watcher) can run:
sig, evidences, err := magnetar.Combine(magnetar.ThbsSeCombineInput{
Key: key, Binding: binding, Message: msg,
Round1: r1s, Round2: r2s,
})
err == nilandevidencesempty: the signature was produced from>=thonest reveals.err == nilandevidencesnon-empty: the signature was produced from>=thonest reveals, AND some malformed reveals were observed; the consensus layer can slash the named parties viaVerifyThbsSeShareEvidence.err == ErrInsufficientQuor: fewer thantvalid reveals were observed.evidencescarries the malformed-share evidence the consensus layer can act on before retrying.
2.5 Verification
ok := magnetar.VerifyBytesCtx(gpkBytes, message, ctxFromSlot(binding), sigBytes)
The VerifyBytesCtx helper is bytes-in, bool-out: it strips the
MAGS/MAGG envelopes and routes through the FIPS 205 verifier
verbatim. Any unmodified slhdsa verifier accepts the inner FIPS 205
bytes.
3. Operational hardening
3.1 RNG sourcing
crypto/rand.Reader on Linux/macOS reads from getrandom(2) /
/dev/urandom. On non-trivial deployments, additionally:
- Use the OS kernel's hardware-RNG entropy when available
(
/dev/hwrngon Linux with a HW source like RDRAND, the TPM, or a Yubikey-Bio). - For HSM-backed keys, route keygen through the HSM's FIPS 140-validated RNG.
3.2 Slot-guard persistence
The ThbsSeSlotGuard is in-memory only. For production deployments
that must survive restarts, persist the guard's state to disk
between Round-1 broadcasts (mirrored from
SlotGuard.Record(slotID, digest, r1, r2) --- ALL four fields are
required to verify slashing evidence after restart).
3.3 Equivocation slashing
VerifyThbsSeEvidence is a pure function. The consensus layer's
slashing pipeline:
- Receive
ThbsSeEvidenceblob via gossip / on-chain submission. - Verify via
VerifyThbsSeEvidence(params, ev, msgPrior, msgNew, bindingPrior, bindingNew). - If valid, slash the party named in
ev.PartyID.
The evidence blob is sufficient on its own --- no committee state, no re-running of the protocol, no membership-proof gymnastics required.
3.4 Mode-mixing prevention
Magnetar's wire codec rejects mode-mismatch at parse time. A
Signature parsed under ModeM192s cannot be cross-verified
against a GroupKey parsed under ModeM256s --- VerifyBytesCtx
returns false on mismatch.
3.5 Race detector
The Magnetar test suite passes under go test -race. SLH-DSA-heavy
tests self-skip via the raceEnabled build tag pattern (race-on
overhead is 5-10x and the tests carry no inter-goroutine
concurrency that would benefit from race coverage); race-on runs
cover the cheap unit tests (transcript, types, wire codec).
4. Migration from Magnetar v0.x
The v0.x CombineWithSeedReconstruction and AggregateSignatures
API surfaces have been removed. v0.x consumers migrate as follows:
| v0.x | v1.0 |
|---|---|
magnetar.GenerateValidatorKey |
magnetar.PerValidatorKeypair |
magnetar.AggregateSignatures + SignedBundle |
magnetar.BuildAggregateCert + ValidatorAggregateCert |
magnetar.VerifyAggregated |
magnetar.VerifyAggregateCert |
magnetar.CombineWithSeedReconstruction |
magnetar.Combine (THBS-SE, different semantics --- see THBS-SPEC.md) |
pkg/thbs (legacy true-HBS) |
DELETED. THBS-SE in pkg/magnetar is the v1.0 threshold construction. |
The signature payload bytes are byte-equal across primitives: a v0.x
AggregateSignatures output and a v1.0 BuildAggregateCert output
carry identical FIPS 205 signature bytes per validator. The only
difference is the envelope shape.