Files
magnetar/DEPLOYMENT-RUNBOOK.md
Antje Worring df4c537c16 magnetar: remove proof-by-rename + circular proofs; honest threshold status
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.
2026-06-21 13:06:57 -07:00

271 lines
11 KiB
Markdown

# 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 `ValidatorAggregateCert`
and counts valid signers; the quorum policy decision lives at the
consumer. Wire cost is `N 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}-tee` via the
`lux/mpc` sibling tree.
## 1. Per-validator standalone (production primary)
### 1.1 Keygen
Each validator runs `PerValidatorKeypair` ONCE on its own host:
```go
sk, pk, err := magnetar.PerValidatorKeypair(params, rng)
```
- `params` SHOULD be `magnetar.ParamsM192s` (smallest signatures at
NIST PQ category 3, >=192-bit classical security). Use
`ParamsM192f` only if signing latency is the dominant constraint
and you can absorb the 2.2x larger signature; use `ParamsM256s`
only if you need category 5 (>=256-bit classical security).
- `rng` SHOULD be `crypto/rand.Reader` (nil also works; the function
defaults to `crypto/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
```go
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
```go
cert, _ := magnetar.BuildAggregateCert(params, signers, pubKeys, sigs)
count, err := magnetar.VerifyAggregateCert(cert, message, knownValidators)
if count >= quorumThreshold { ... }
```
- `knownValidators` is the consensus layer's authoritative
`NodeID -> pubkey` map.
- 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:
1. Wait for v1.1 strict-atom-assembly.
2. Route the threshold signing via the TEE-attested variants at
`luxfi/threshold/protocols/slhdsa-tee` (operator-controlled MPC
custody, host in TCB by policy).
3. Use per-validator standalone instead --- the public-BFT primary
has no seed reconstruction at any point.
### 2.2 Setup
```go
key, err := magnetar.NewThbsSeKey(params, threshold, committee, setupRng)
```
- `params` and the threshold `t` are the same shape as
per-validator standalone.
- `committee` MUST be sorted ascending by `NodeID` with distinct
non-zero IDs.
- `setupRng` defaults to `crypto/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:
```go
r1, r2, err := magnetar.ThbsSeRound1(params, share, binding, msg, guard, rng)
```
- `binding` is the slot tuple
`(chain_id, epoch, slot, height, committee_id, message_domain)`.
- `guard` is a `*ThbsSeSlotGuard` the 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
`*ThbsSeEquivocationError` carrying 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:
```go
sig, evidences, err := magnetar.Combine(magnetar.ThbsSeCombineInput{
Key: key, Binding: binding, Message: msg,
Round1: r1s, Round2: r2s,
})
```
- `err == nil` and `evidences` empty: the signature was produced
from `>=t` honest reveals.
- `err == nil` and `evidences` non-empty: the signature was
produced from `>=t` honest reveals, AND some malformed reveals
were observed; the consensus layer can slash the named parties
via `VerifyThbsSeShareEvidence`.
- `err == ErrInsufficientQuor`: fewer than `t` valid reveals were
observed. `evidences` carries the malformed-share evidence the
consensus layer can act on before retrying.
### 2.5 Verification
```go
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/hwrng` on 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:
1. Receive `ThbsSeEvidence` blob via gossip / on-chain submission.
2. Verify via `VerifyThbsSeEvidence(params, ev, msgPrior, msgNew,
bindingPrior, bindingNew)`.
3. 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.