M-Chain — MPC Ceremonies Specification
M-Chain (MVM) — the chain that runs MPC signing ceremonies for bridge custody of external wallets (CGGMP21, FROST, Pulsar-general). Canonical successor to the MPC half of the removed T-Chain, per LP-134.
Implementation status (code-audited 2026-07-03): PARTIAL mpcvm (renamed from thresholdvm 2026-07-03) with NoUserTxPolicy confirmed (chains/mpcvm/feegate.go:18); protocols shipped: LSS/CGGMP21/BLS/Corona/FROST-experimental/EdDSA (protocols.go:25-37) — PQ leg is Corona (interface-only), not Pulsar; keygen/reshare/refresh RPCs live on mpcvm itself (rpc.go:107-128).
Normative topology + fee model: LP-0130. M-Chain fees are service fees deducted from the originating chain's fee pool (B for bridge, F for threshold decrypt, C for AA), not a user M-balance (LP-0130 §7). Signer rewards settle to X via the epoch fee root reconciled at Q finality. The Go package is
github.com/luxfi/chains/mpcvm(renamed fromthresholdvm2026-07-03).
Abstract
M-Chain (MVM) is the Lux chain that runs multi-party-computation (MPC) signing ceremonies. A quorum of validators jointly produces a single signature over a secret key that no individual party ever holds. M-Chain's job is to authorize transactions on external chains (Bitcoin, Ethereum, Solana, other EVMs, Cosmos) held under bridge custody — the resulting threshold signature is the authorization.
M-Chain owns all application threshold signing on Lux. It is the canonical successor to the MPC half of the removed T-Chain (LP-134; migration map LP-7050). It composes three signing primitives — CGGMP21 threshold ECDSA (LP-4720), FROST threshold Schnorr/EdDSA (LP-4710), and Pulsar-general post-quantum threshold ML-DSA (LP-4450) — over the linear-secret-sharing substrate (LP-7103) and the dynamic-resharing protocol (LP-4730). It is operationally distinct from F-Chain (LP-8200, FHE) and from Q-Chain (consensus Pulsar): same cryptographic families, different purpose.
Motivation — why a dedicated MPC chain
A bridge that holds real funds on an external chain needs a signing
key. If one server holds that key, one compromise drains the bridge.
The standard answer is threshold custody: split the key into n
shares so that any honest t-of-n quorum can sign, but any t−1
colluding parties learn nothing. The validator set already is a
Byzantine-fault-tolerant quorum with stake at risk — so the natural
signers are the validators themselves, running the MPC ceremony as a
first-class chain activity with on-chain session state, committee
selection, and timeouts.
Putting this on its own chain (rather than braiding it into consensus or into an FHE chain) keeps each concern independent: ceremony cadence, gas economics, and validator subset are tuned for signing, not for block production or encrypted compute.
Intuition — the hot path vs. the cold path
- K-Chain (KeyVM, LP-7336) is the cold path: it owns key
lifecycle —
CreateKey(t, n, scheme),RotateKey, share custody records. Keys live here. - M-Chain (MVM) is the hot path: it borrows a key's shares
to run a signing session. It never owns the key; it references a
K-Chain
KeyRecordand drives the ceremony to a combined signature.
This is a strict separation of state (K-Chain) from protocol execution (M-Chain). One operation, one chain:
| Operation | Chain | Rationale |
|---|---|---|
CreateKey(t, n, scheme) | K-Chain | state: key lifecycle (cold) |
SignMessage(keyID, msg) | M-Chain | protocol: session execution (hot) |
RotateKey(keyID) / reshare | K-Chain + LP-4730 | state: cold-path resharing |
Chain parameters
| Parameter | Value |
|---|---|
| Chain letter | M |
| VM ID / name | mvm |
| Consensus | Quasar (Nebula mode — DAG of partial signatures) |
| Substrate | ~/work/lux/chains/mpcvm (Go library, shared with F-Chain) |
| Cert lanes | MChainCGGMP21, MChainFROST, MChainPulsarGen (LP-134) |
Each ceremony runs as a Nebula round: partial signatures form a
DAG, converge to a frontier, and commit as a cert. The lane verifier
in QuasarGPU drain_cert_lane dispatches by cert_lane to the
protocol-specific check. M-Chain commits mchain_ceremony_root per
epoch (LP-134).
Signing protocols (one primitive per external-chain family)
| Protocol | Scheme | External targets | Primitive LP | Cert lane |
|---|---|---|---|---|
| CGGMP21 | ECDSA threshold (secp256k1 / secp256r1) | Bitcoin, Ethereum, EVMs, Cosmos | LP-4720 | MChainCGGMP21 |
| FROST | Schnorr threshold (Ed25519, Ristretto255, Taproot) | Solana, Polkadot, Cosmos, Bitcoin Taproot | LP-4710 (+ 4711, 4712) | MChainFROST |
| Pulsar-general | Module-LWE threshold ML-DSA-65 (PQ) | Lux-internal PQ custody, future PQ-curve chains | LP-4450 | MChainPulsarGen |
M-Chain does not re-specify these primitives — it composes them. For the algorithm, parameters, gas table, and test vectors, read the primitive LP.
Session lifecycle
type SignSession struct {
ID [32]byte
KeyRecordID [32]byte // reference to a K-Chain KeyRecord
Protocol Protocol // CGGMP21 | FROST | PulsarGeneral
Message []byte
Committee []ids.NodeID
Status Status // Pending | InProgress | Complete | Failed | Expired
StartedAt uint64 // block timestamp
ExpiresAt uint64 // StartedAt + SignTimeout
Signatures map[ids.NodeID][]byte // partial signatures
Result []byte // combined signature (when Complete)
}
A session runs for at most SignTimeout (default 5 min). Expired
sessions release their reserved committee seats and are marked
Failed. SignMessage(keyID, msg) opens a session; the combined
signature is published when the quorum's partials converge.
Committee selection
For each session, M-Chain samples a committee from the validators that hold a share of the referenced key (as recorded by K-Chain):
- Small (t ≤ 6): the full group signs — use FROST or threshold ML-DSA directly.
- Medium (t ∈ [7, 32]): deterministic VRF-based unbiasable sampling.
- Large (t > 32): do not use a single monolithic session; use hierarchical quorum certs (LP-142). Thousand-validator monolithic ceremonies are the wrong shape.
Dynamic resharing (proactive security)
Signer sets change and shares must be refreshed without changing the
public key. M-Chain drives LSS dynamic signer rotation (LP-4730)
over the linear-secret-sharing substrate (LP-7103): a proactive
resharing that rotates every party's share, invalidating any t−1
shares an adversary may have gathered, while the group public key —
and therefore the external-chain custody address — is unchanged.
Composition
- Bridge custody: B-Chain (
bridgevm, LP-6000) requests an M-Chain signature to move funds on an external chain. B-Chain owns the messaging/routing; M-Chain owns the signing. - Per-asset keys: LP-4740 binds a distinct threshold key per custodied asset; M-Chain enforces the per-asset policy at session open.
- Post-quantum custody: the
MChainPulsarGenlane gives PQ-safe custody without a new chain — same session machinery, ML-DSA primitive.
Reference implementation
- Substrate:
~/work/lux/chains/mpcvm(Go) - MPC primitives:
github.com/luxfi/threshold(LP-7340),luxfi/crypto - Ceremony driver:
~/work/lux/chains/mvm(planned consolidation)
Open questions
- M-Chain genesis layout (validator set, custody policy registry)
- Cross-chain settlement message format (Warp binding to B-Chain)
- L1 / L2 placement (primary network vs sovereign, per LP-018)
Copyright
Copyright and related rights waived via CC0.