Documentation
¶
Overview ¶
service.go carves the (currently single, overloaded) threshold VM into three orthogonal SERVICE surfaces — ThresholdService, MPCService, FHEService — per LP-134 / LP-7050. This is the "separate what the primitive IS from where it is APPLIED" decomposition (Hammock-driven composition, not inheritance).
It changes NO behavior and NO genesis: the interfaces are carved directly from the methods *VM already implements, and *VM is asserted to satisfy all three at the bottom of this file (the compatibility bridge). The physical VM split — moving each surface's implementation onto its own package (github.com/luxfi/chains/mpcvm implementing MPCService, .../fhevm implementing FHEService) behind these exact interfaces — is the follow-up; until then the one *VM backs all three surfaces and the M-Chain / F-Chain runtime adapters (runtime/{m,f}_chain_adapter.go) delegate to it.
Layering mirrors the primitive-library stack that already exists upstream (github.com/luxfi/threshold is consumed by github.com/luxfi/mpc; FHE ⊥ MPC):
- ThresholdService — PURE threshold primitives: DKG, committee formation, key/committee lookup. The substrate the other two consume. Owns no custody, no bridge business logic, no FHE.
- MPCService — threshold SIGNING, bridge-custody attestation. CONSUMES ThresholdService committees to produce signatures/attestations over cross-chain subjects. This is M-Chain's surface (LP-7100).
- FHEService — confidential compute / encrypted state. CONSUMES ThresholdService key/decryption committees; owns FHE jobs and threshold-decrypt. This is F-Chain's surface (LP-8200).
mpcvm itself remains a LIBRARY: there is no T-Chain, no teleportvm.
Package mpcvm implements the shared threshold VM substrate — a LIBRARY, not a chain — consumed by M-Chain (MPC: CGGMP21/FROST/Pulsar-general threshold signing for bridge custody of external wallets, LP-7100) and F-Chain (FHE: TFHE compute / threshold decrypt, LP-8200). Per LP-134 / LP-7050 there is NO T-Chain and NO teleportvm; teleport IS bridgevm (B-Chain, LP-6000). Any live identifier still naming "T-Chain" or "ThresholdVM-as-a-chain" is stale. See ../README.md.
Index ¶
- Constants
- Variables
- func ComputeAttestationPayload(domain AttestationDomain, subjectID, commitmentRoot [32]byte, epoch uint64) [32]byte
- func DetectEquivocation(a, b *QuantumAttestation) bool
- func KeyCommitDigest(r *KeyRecord) [32]byte
- func NewLocalMesh(parties []party.ID) *localMesh
- func VerifyBridgeAttestation(groupPubKey []byte, bt BridgeTransfer, sig []byte) bool
- type AppNetwork
- type AttestationDomain
- type BLSHandler
- func (h *BLSHandler) Keygen(ctx context.Context, partyID party.ID, partyIDs []party.ID, threshold int) (KeyShare, error)
- func (h *BLSHandler) Name() Protocol
- func (h *BLSHandler) Refresh(ctx context.Context, share KeyShare) (KeyShare, error)
- func (h *BLSHandler) Reshare(ctx context.Context, share KeyShare, newPartyIDs []party.ID, newThreshold int) (KeyShare, error)
- func (h *BLSHandler) Sign(ctx context.Context, share KeyShare, message []byte, signers []party.ID) (Signature, error)
- func (h *BLSHandler) SupportedCurves() []string
- func (h *BLSHandler) Verify(pubKey []byte, message []byte, signature Signature) (bool, error)
- type Block
- func (b *Block) Accept(ctx context.Context) error
- func (b *Block) Bytes() []byte
- func (b *Block) ChoicesStatus() choices.Status
- func (b *Block) Height() uint64
- func (b *Block) ID() ids.ID
- func (b *Block) Marshal() ([]byte, error)
- func (b *Block) Parent() ids.ID
- func (b *Block) ParentID() ids.ID
- func (b *Block) Reject(ctx context.Context) error
- func (b *Block) SetStatus(status choices.Status)
- func (b *Block) Status() uint8
- func (b *Block) Timestamp() time.Time
- func (b *Block) Verify(ctx context.Context) error
- type BridgeReleaseRequest
- type BridgeTransfer
- type BridgeTransferAttestation
- type CGGMP21Handler
- func (h *CGGMP21Handler) Keygen(ctx context.Context, partyID party.ID, partyIDs []party.ID, threshold int) (KeyShare, error)
- func (h *CGGMP21Handler) Name() Protocol
- func (h *CGGMP21Handler) Refresh(ctx context.Context, share KeyShare) (KeyShare, error)
- func (h *CGGMP21Handler) Reshare(ctx context.Context, share KeyShare, newPartyIDs []party.ID, newThreshold int) (KeyShare, error)
- func (h *CGGMP21Handler) SetExecutor(executor *ProtocolExecutor)
- func (h *CGGMP21Handler) SetMessageRouter(router MessageRouter)
- func (h *CGGMP21Handler) Sign(ctx context.Context, share KeyShare, message []byte, signers []party.ID) (Signature, error)
- func (h *CGGMP21Handler) SupportedCurves() []string
- func (h *CGGMP21Handler) Verify(pubKey []byte, message []byte, signature Signature) (bool, error)
- type CMPKeyShare
- type CeremonyInfo
- type CeremonyRecord
- type ChainPermissions
- type Client
- func (c *Client) GetAddress(ctx context.Context, keyID string) ([]byte, error)
- func (c *Client) GetCeremony(ctx context.Context, ceremonyID string) (*CeremonyInfo, error)
- func (c *Client) GetInfo(ctx context.Context) (*ThresholdInfo, error)
- func (c *Client) GetKey(ctx context.Context, keyID string) (*KeyInfo, error)
- func (c *Client) GetProtocolInfo(ctx context.Context, protocol string) (*ProtocolInfo, error)
- func (c *Client) GetProtocols(ctx context.Context) ([]ProtocolInfo, error)
- func (c *Client) GetPublicKey(ctx context.Context, keyID string) ([]byte, error)
- func (c *Client) GetQuota(ctx context.Context) (*QuotaInfo, error)
- func (c *Client) GetStats(ctx context.Context) (*NetworkStats, error)
- func (c *Client) Health(ctx context.Context) (map[string]interface{}, error)
- func (c *Client) Keygen(ctx context.Context, req KeygenRequest) (*KeygenResponse, error)
- func (c *Client) ListCeremonies(ctx context.Context) ([]CeremonyInfo, error)
- func (c *Client) ListKeys(ctx context.Context) ([]KeyInfo, error)
- func (c *Client) Sign(ctx context.Context, req SignRequest) (*CeremonyInfo, error)
- func (c *Client) StateRoot(ctx context.Context) (string, error)
- type CoronaHandler
- func (h *CoronaHandler) Keygen(ctx context.Context, partyID party.ID, partyIDs []party.ID, threshold int) (KeyShare, error)
- func (h *CoronaHandler) Name() Protocol
- func (h *CoronaHandler) Refresh(ctx context.Context, share KeyShare) (KeyShare, error)
- func (h *CoronaHandler) Reshare(ctx context.Context, share KeyShare, newPartyIDs []party.ID, newThreshold int) (KeyShare, error)
- func (h *CoronaHandler) Sign(ctx context.Context, share KeyShare, message []byte, signers []party.ID) (Signature, error)
- func (h *CoronaHandler) SupportedCurves() []string
- func (h *CoronaHandler) Verify(pubKey []byte, message []byte, signature Signature) (bool, error)
- type CrossChainMPCRequest
- type ECDSASignature
- type EpochBeaconAttestation
- type FHEService
- type FROSTKeyShare
- func (s *FROSTKeyShare) Generation() uint64
- func (s *FROSTKeyShare) PartyID() party.ID
- func (s *FROSTKeyShare) Protocol() Protocol
- func (s *FROSTKeyShare) PublicKey() []byte
- func (s *FROSTKeyShare) Serialize() ([]byte, error)
- func (s *FROSTKeyShare) Threshold() int
- func (s *FROSTKeyShare) TotalParties() int
- type Factory
- type GPUBackend
- func (g *GPUBackend) CeremonyApply(desc *GPUMPCVMRoundDescriptor, ceremonyOps []GPUCeremonyOp, ...) (applied uint32, err error)
- func (g *GPUBackend) ContributionApply(desc *GPUMPCVMRoundDescriptor, contributionOps []GPUContributionOp, ...) (applied uint32, err error)
- func (g *GPUBackend) IsAvailable() bool
- func (g *GPUBackend) KeyShareApply(desc *GPUMPCVMRoundDescriptor, ceremonies []GPUCeremony, ...) (roundAdvance, finalized, failed uint32, err error)
- func (g *GPUBackend) MPCTransition(desc *GPUMPCVMRoundDescriptor, ceremonies []GPUCeremony, ...) (*GPUMPCVMTransitionResult, error)
- type GPUBackendKind
- type GPUCeremony
- type GPUCeremonyOp
- type GPUContribution
- type GPUContributionOp
- type GPUKeyShare
- type GPUMPCVMRoundDescriptor
- type GPUMPCVMState
- type GPUMPCVMTransitionResult
- type Genesis
- type GetCeremonyParams
- type GetChainPermissionsParams
- type GetKeyParams
- type GetProtocolInfoParams
- type GetQuotaParams
- type KeyInfo
- type KeyRecord
- type KeyShare
- type KeygenParams
- type KeygenRequest
- type KeygenResponse
- type KeygenResult
- type LSSHandler
- func (h *LSSHandler) Keygen(ctx context.Context, partyID party.ID, partyIDs []party.ID, threshold int) (KeyShare, error)
- func (h *LSSHandler) Name() Protocol
- func (h *LSSHandler) Refresh(ctx context.Context, share KeyShare) (KeyShare, error)
- func (h *LSSHandler) Reshare(ctx context.Context, share KeyShare, newPartyIDs []party.ID, newThreshold int) (KeyShare, error)
- func (h *LSSHandler) Sign(ctx context.Context, share KeyShare, message []byte, signers []party.ID) (Signature, error)
- func (h *LSSHandler) SupportedCurves() []string
- func (h *LSSHandler) Verify(pubKey []byte, message []byte, signature Signature) (bool, error)
- type LSSKeyShare
- type MPCService
- type MessageRouter
- type NetworkStats
- type Operation
- type OracleCommitAttestation
- type PartyInfo
- type Protocol
- type ProtocolConfig
- type ProtocolExecutor
- func (pe *ProtocolExecutor) AcceptMessage(sessionID string, msg *protocol.Message) error
- func (pe *ProtocolExecutor) CMPKeygenStartFunc(selfID party.ID, participants []party.ID, threshold int) protocol.StartFunc
- func (pe *ProtocolExecutor) CMPRefreshStartFunc(config *cmpconfig.Config) protocol.StartFunc
- func (pe *ProtocolExecutor) CMPSignStartFunc(config *cmpconfig.Config, signers []party.ID, messageHash []byte) protocol.StartFunc
- func (pe *ProtocolExecutor) CreateHandler(ctx context.Context, sessionID string, startFunc protocol.StartFunc) (*protocol.Handler, error)
- func (pe *ProtocolExecutor) FROSTKeygenStartFunc(selfID party.ID, participants []party.ID, threshold int) protocol.StartFunc
- func (pe *ProtocolExecutor) FROSTKeygenTaprootStartFunc(selfID party.ID, participants []party.ID, threshold int) protocol.StartFunc
- func (pe *ProtocolExecutor) FROSTRefreshStartFunc(config *frostconfig.Config, participants []party.ID) protocol.StartFunc
- func (pe *ProtocolExecutor) FROSTSignStartFunc(config *frostconfig.Config, signers []party.ID, messageHash []byte) protocol.StartFunc
- func (pe *ProtocolExecutor) GetHandler(sessionID string) (*protocol.Handler, bool)
- func (pe *ProtocolExecutor) LSSKeygenStartFunc(selfID party.ID, participants []party.ID, threshold int) protocol.StartFunc
- func (pe *ProtocolExecutor) LSSRefreshStartFunc(config *lssconfig.Config) protocol.StartFunc
- func (pe *ProtocolExecutor) LSSReshareStartFunc(config *lssconfig.Config, newParticipants []party.ID, newThreshold int) protocol.StartFunc
- func (pe *ProtocolExecutor) LSSSignStartFunc(config *lssconfig.Config, signers []party.ID, messageHash []byte) protocol.StartFunc
- func (pe *ProtocolExecutor) RemoveHandler(sessionID string)
- func (pe *ProtocolExecutor) RunCMPKeygen(ctx context.Context, sessionID string, selfID party.ID, ...) (*cmpconfig.Config, error)
- func (pe *ProtocolExecutor) RunCMPRefresh(ctx context.Context, sessionID string, config *cmpconfig.Config, ...) (*cmpconfig.Config, error)
- func (pe *ProtocolExecutor) RunCMPSign(ctx context.Context, sessionID string, config *cmpconfig.Config, ...) (*ECDSASignature, error)
- func (pe *ProtocolExecutor) RunFROSTKeygen(ctx context.Context, sessionID string, selfID party.ID, ...) (*frostconfig.Config, error)
- func (pe *ProtocolExecutor) RunLSSKeygen(ctx context.Context, sessionID string, selfID party.ID, ...) (*lssconfig.Config, error)
- func (pe *ProtocolExecutor) RunLSSSign(ctx context.Context, sessionID string, config *lssconfig.Config, ...) (*ECDSASignature, error)
- type ProtocolHandler
- type ProtocolInfo
- type ProtocolOptions
- type ProtocolRegistry
- type QuantumAttestation
- type QuotaInfo
- type RPCError
- type RPCRequest
- type RPCResponse
- type SchnorrSignature
- type SessionCompleteAttestation
- type SignParams
- type SignRequest
- type Signature
- type State
- func (s *State) BlockIDAtHeight(height uint64) (ids.ID, error)
- func (s *State) Ceremonies() ([]*CeremonyRecord, error)
- func (s *State) GetBlock(id ids.ID) ([]byte, error)
- func (s *State) GetCeremony(id string) (*CeremonyRecord, error)
- func (s *State) GetKey(keyID string) (*KeyRecord, error)
- func (s *State) GetShare(keyID string) ([]byte, error)
- func (s *State) HasKey(keyID string) (bool, error)
- func (s *State) HasShare(keyID string) (bool, error)
- func (s *State) Keys() ([]*KeyRecord, error)
- func (s *State) LastAccepted() (id ids.ID, found bool, err error)
- func (s *State) PutBlock(id ids.ID, height uint64, raw []byte) error
- func (s *State) PutCeremony(c *CeremonyRecord) error
- func (s *State) PutKey(r *KeyRecord) error
- func (s *State) PutShare(keyID string, share []byte) error
- func (s *State) ReplaceKey(r *KeyRecord) error
- func (s *State) Root() [32]byte
- func (s *State) SetLastAccepted(id ids.ID, root [32]byte) error
- type ThresholdConfig
- type ThresholdInfo
- type ThresholdService
- type VM
- func (vm *VM) Address(keyID string) ([]byte, error)
- func (vm *VM) AttestBridgeTransfer(ctx context.Context, requestingChain string, keyID string, bt BridgeTransfer) (*BridgeTransferAttestation, error)
- func (vm *VM) AttestEpochBeacon(ctx context.Context, requestingChain string, keyID string, epoch uint64, ...) (*QuantumAttestation, error)
- func (vm *VM) AttestNFTOwnership(ctx context.Context, requestingChain string, keyID string, ...) (*ownership.Attestation, error)
- func (vm *VM) AttestOracleCommit(ctx context.Context, requestingChain string, keyID string, requestID [32]byte, ...) (*QuantumAttestation, error)
- func (vm *VM) AttestSessionComplete(ctx context.Context, requestingChain string, keyID string, sessionID [32]byte, ...) (*QuantumAttestation, error)
- func (vm *VM) BuildBlock(ctx context.Context) (chain.Block, error)
- func (vm *VM) Ceremonies() ([]*CeremonyRecord, error)
- func (vm *VM) Ceremony(id string) (*CeremonyRecord, error)
- func (vm *VM) Committee(ctx context.Context, height uint64) ([]party.ID, error)
- func (vm *VM) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *chain.VersionInfo) error
- func (vm *VM) CreateHandlers(ctx context.Context) (map[string]http.Handler, error)
- func (vm *VM) CreateStaticHandlers(ctx context.Context) (map[string]http.Handler, error)
- func (vm *VM) CrossChainRequest(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, ...) error
- func (vm *VM) CrossChainRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *warp.Error) error
- func (vm *VM) CrossChainResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error
- func (vm *VM) Disconnected(ctx context.Context, nodeID ids.NodeID) error
- func (vm *VM) FeePolicy() fee.Policy
- func (vm *VM) GetBlock(ctx context.Context, id ids.ID) (chain.Block, error)
- func (vm *VM) GetBlockIDAtHeight(ctx context.Context, height uint64) (ids.ID, error)
- func (vm *VM) Gossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error
- func (vm *VM) HealthCheck(ctx context.Context) (chain.HealthResult, error)
- func (vm *VM) Initialize(ctx context.Context, init vmcore.Init) error
- func (vm *VM) Key(keyID string) (*KeyRecord, error)
- func (vm *VM) Keys() ([]*KeyRecord, error)
- func (vm *VM) LastAccepted(ctx context.Context) (ids.ID, error)
- func (vm *VM) NewHTTPHandler(ctx context.Context) (http.Handler, error)
- func (vm *VM) ParseBlock(ctx context.Context, bytes []byte) (chain.Block, error)
- func (vm *VM) Policy() quorum.Policy
- func (vm *VM) PublicKey(keyID string) ([]byte, error)
- func (vm *VM) Request(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, ...) error
- func (vm *VM) RequestBridgeRelease(ctx context.Context, req BridgeReleaseRequest) (*BridgeTransferAttestation, error)
- func (vm *VM) RequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *warp.Error) error
- func (vm *VM) RequestSignature(ctx context.Context, requestingChain, keyID string, messageHash []byte) (*Operation, error)
- func (vm *VM) Response(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error
- func (vm *VM) RunKeygen(ctx context.Context, keyID string, policy quorum.Policy, ...) (*Operation, error)
- func (vm *VM) RunSign(ctx context.Context, keyID string, digest []byte, requestingChain string) (*Operation, error)
- func (vm *VM) SetPreference(ctx context.Context, id ids.ID) error
- func (vm *VM) SetState(ctx context.Context, state uint32) error
- func (vm *VM) Shutdown(ctx context.Context) error
- func (vm *VM) StartKeygen(ctx context.Context, keyID, requestedBy string) (*Operation, error)
- func (vm *VM) StartKeygenWithPolicy(ctx context.Context, keyID string, policy quorum.Policy, requestedBy string) (*Operation, error)
- func (vm *VM) StateRoot() [32]byte
- func (vm *VM) VerifyAttestation(a *QuantumAttestation) error
- func (vm *VM) Version(ctx context.Context) (string, error)
- func (vm *VM) WaitForEvent(ctx context.Context) (vmcore.Message, error)
Constants ¶
const ( OpTypeKeygen = "keygen" OpTypeSign = "sign" )
Operation kinds recorded on M-Chain.
const ( RPCErrorInvalidRequest = -32600 RPCErrorMethodNotFound = -32601 RPCErrorInvalidParams = -32602 RPCErrorInternal = -32603 RPCErrorQuotaExceeded = -32003 RPCErrorCeremonyNotFound = -32004 RPCErrorKeyNotFound = -32005 RPCErrorProtocolNotFound = -32006 )
Error codes. Only codes this server can actually return are declared: a published code that nothing emits reads as a contract to callers who then write dead branches against it.
const KindCGGMP21 = "cggmp21"
KindCGGMP21 names the threshold-ECDSA protocol used for bridge custody of external wallets. It is the value stored in KeyRecord.Kind.
Variables ¶
var ( ErrInvalidOperation = errors.New("mpcvm: invalid operation") ErrBadArtifact = errors.New("mpcvm: ceremony artifact does not verify") ErrQuorumTooSmall = errors.New("mpcvm: signer set smaller than the key's policy requires") )
var ( ErrNoCommittee = errors.New("mpcvm: no validator committee available") ErrNotParticipant = errors.New("mpcvm: this node is not in the ceremony committee") ErrNotInQuorum = errors.New("mpcvm: this node is not in this task's signing quorum") ErrPolicyTooLarge = errors.New("mpcvm: policy requires more parties than the committee has") )
var ( ErrKeyExists = errors.New("mpcvm: key already registered") ErrUnknownKey = errors.New("mpcvm: key not registered") ErrCeremonyExists = errors.New("mpcvm: ceremony already recorded") ErrPolicyMismatch = errors.New("mpcvm: key policy does not match its participant set") ErrRootMismatch = errors.New("mpcvm: post-state root mismatch") )
var ( Version = &version.Semantic{ Major: 1, Minor: 0, Patch: 0, } // Errors this VM owns. Everything about a KEY (unknown, already registered, // share not held) is state.go's vocabulary and is not restated here: two // spellings of "no such key" is one spelling too many. ErrInvalidThreshold = errors.New("mpcvm: invalid threshold configuration") ErrQuotaExceeded = errors.New("mpcvm: signing quota exceeded") )
var ErrGPUNotAvailable = errors.New("mpcvm: GPU backend not available (no plugin dlopened)")
ErrGPUNotAvailable is returned by GPUBackend methods when no plugin was resolved at init() time. Callers check this to fall back to the CPU reference (the protocol/ + executor.go state machine, which is unchanged by this bridge).
var VMID = constants.MPCVMID
VMID identifies M-Chain: MPC threshold signing and bridge custody of external wallets (LP-7100). It is constants.MPCVMID and nothing else.
A vmID is an immutable one-way door: it is baked into the CreateChainTx at genesis, it is the plugin binary's filename, and it is what the P-Chain stores forever. Every declaration of it must agree, so there is exactly one — this alias — and it points at the single source of truth in luxfi/constants.
This VM previously declared a private `thresholdvm` literal here that matched no other declaration in the stack. Per LP-7050 the thresholdvm package was split into mpcvm (M-Chain) and fhevm (F-Chain); "ThresholdVM" and "mvm" are stale names. constants.MPCVMID, node/genesis/builder/registry.go and node/node/vms.go all say mpcvm.
Functions ¶
func ComputeAttestationPayload ¶
func ComputeAttestationPayload(domain AttestationDomain, subjectID, commitmentRoot [32]byte, epoch uint64) [32]byte
ComputeAttestationPayload computes the payload to be signed for an attestation
func DetectEquivocation ¶
func DetectEquivocation(a, b *QuantumAttestation) bool
DetectEquivocation checks if two attestations represent equivocation (slashable) Two attestations are equivocating if they have the same domain, subject, and epoch but different commitment roots
func KeyCommitDigest ¶ added in v1.7.10
KeyCommitDigest is the message a newly generated group key signs to prove possession of itself. Binding the policy, the participant set and the group key together means a proposer cannot register a key under a policy or a committee other than the one the ceremony actually ran with and still produce a verifying proof.
What this proves and what it does not: a valid proof-of-possession shows that whoever produced it can sign under GroupPublicKey, which rules out a proposer registering a public key it does not control (rogue-key registration). It does NOT by itself prove the declared degree — a single party holding the whole secret could also sign. Degree is established by the participant cross-check in Block.Verify: a validator that holds a share for this key compares the record against its own config and rejects a mismatch, so one honest participant is enough to stop a mis-declared key.
func NewLocalMesh ¶ added in v1.7.10
NewLocalMesh builds an in-process bus over a fixed committee.
func VerifyBridgeAttestation ¶
func VerifyBridgeAttestation(groupPubKey []byte, bt BridgeTransfer, sig []byte) bool
VerifyBridgeAttestation is B's gate: it returns true iff sig is a valid threshold signature by the group key over THIS transfer's domain-bound digest. Accepts r‖s (64) or r‖s‖v (65). No interaction with M — a threshold ECDSA signature verifies exactly like a single-key one.
Types ¶
type AppNetwork ¶
type AppNetwork interface {
// Broadcast reliably gossips an app message to the chain's validators.
Broadcast(ctx context.Context, msg []byte) error
// SendTo sends an app message to a single validator.
SendTo(ctx context.Context, nodeID ids.NodeID, msg []byte) error
}
AppNetwork is the minimal consensus-gossip send capability the gossipRouter needs. The VM implements it over the node AppSender it receives at Initialize. Kept as an interface so this file imports no node packages and stays unit-testable.
type AttestationDomain ¶
type AttestationDomain string
AttestationDomain defines the domain for a threshold attestation
const ( // DomainOracleWrite attests to external write request commitments DomainOracleWrite AttestationDomain = "oracle/write" // DomainOracleRead attests to external read request commitments DomainOracleRead AttestationDomain = "oracle/read" // DomainSessionComplete attests to session completion (output hash + oracle obs + receipts root) DomainSessionComplete AttestationDomain = "session/complete" // DomainEpochBeacon attests to epoch beacon signatures for randomness DomainEpochBeacon AttestationDomain = "epoch/beacon" )
const DomainBridgeTransfer AttestationDomain = "bridge/transfer"
DomainBridgeTransfer registers the bridge domain with the attestation domain registry so QuantumAttestation-style tooling recognises it.
const DomainNFTOwnership AttestationDomain = ownership.Domain
DomainNFTOwnership registers the ownership domain with the attestation domain registry. The name and the separator both come from chains/ownership, which is also what every verifier hashes — one constant, so M and its verifiers cannot drift into signing and checking different bytes.
type BLSHandler ¶
type BLSHandler struct{}
BLSHandler implements ProtocolHandler for BLS threshold signatures
func (*BLSHandler) Name ¶
func (h *BLSHandler) Name() Protocol
func (*BLSHandler) SupportedCurves ¶
func (h *BLSHandler) SupportedCurves() []string
type Block ¶
type Block struct {
ID_ ids.ID
ParentID_ ids.ID
BlockHeight uint64
BlockTimestamp int64
// StateRoot is the root AFTER applying Operations. Every validator
// recomputes it; a proposer that applied something different is rejected.
StateRoot [32]byte
Operations []*Operation
// contains filtered or unexported fields
}
Block is one M-Chain block.
func (*Block) Accept ¶
Accept applies the transition and durably records it. Verify has already run, so every precondition holds; anything that fails here is an I/O fault, not a validation failure, and must not be swallowed — a block the engine believes is accepted but whose state was not written is exactly the divergence the state root exists to catch.
func (*Block) ChoicesStatus ¶
func (*Block) Marshal ¶ added in v1.7.4
Marshal encodes the block (excluding the derived ID_) to canonical wire.
type BridgeReleaseRequest ¶ added in v1.7.4
type BridgeReleaseRequest struct {
RequestingChain string `json:"requestingChain"` // authorised chain id in M's permission table (e.g. "B-Chain")
// KeyID names the custody key that must sign. It is REQUIRED: there is no
// "active key" for a request to fall back to, because a fallback means the
// chain, not the requester, chose which vault to spend from — and a key
// rotation would silently redirect releases to a different custody address.
KeyID string `json:"keyId"`
SrcChainID uint32 `json:"srcChainId"`
DstChainID uint32 `json:"dstChainId"`
Asset [32]byte `json:"asset"`
Amount uint64 `json:"amount"`
Recipient [20]byte `json:"recipient"`
Nonce uint64 `json:"nonce"`
}
BridgeReleaseRequest is the clean, self-contained request B hands M to authorise a cross-chain release. It carries exactly the fields that bind the release (both chain ids, asset, amount, recipient, per-route nonce) plus the M-Chain routing context (which authorised chain is asking, and which custody key must sign). Everything the digest commits to travels here; nothing else can be minted from the resulting attestation.
type BridgeTransfer ¶
type BridgeTransfer struct {
SrcChainID uint32 `json:"srcChainId"` // source network id
DstChainID uint32 `json:"dstChainId"` // destination network id
Asset [32]byte `json:"asset"` // canonical asset id
Amount uint64 `json:"amount"` // units locked on source == minted on dest
Recipient [20]byte `json:"recipient"` // destination recipient (20-byte account)
Nonce uint64 `json:"nonce"` // per-route monotonic nonce (replay guard)
}
BridgeTransfer is the domain-bound message B commits to on lock and M signs as its attestation. Field layout is fixed so the digest is canonical across validators and across the B/M boundary.
func (BridgeTransfer) Digest ¶
func (bt BridgeTransfer) Digest() [32]byte
Digest is the canonical, domain-separated signing preimage for a transfer.
type BridgeTransferAttestation ¶
type BridgeTransferAttestation struct {
Transfer BridgeTransfer `json:"transfer"`
Digest [32]byte `json:"digest"`
Signature []byte `json:"signature"` // secp256k1 r(32)‖s(32)‖v(1)
GroupPubKey []byte `json:"groupPubKey"` // 33-byte compressed group key
Signers []party.ID `json:"signers"` // the quorum that signed
KeyID string `json:"keyId"`
// CeremonyID is this attestation's entry in M-Chain's replicated ceremony
// log — the audit handle that turns "B was handed a signature" into "B can
// point at the consensus record that produced it".
CeremonyID string `json:"ceremonyId"`
CreatedAt int64 `json:"createdAt"`
}
BridgeTransferAttestation is M's threshold signature over a transfer, plus the context B needs to verify it. Self-describing so B (or a relayer) can verify without re-querying M.
type CGGMP21Handler ¶
type CGGMP21Handler struct {
// contains filtered or unexported fields
}
CGGMP21Handler implements ProtocolHandler for CGGMP21/CMP
func (*CGGMP21Handler) Name ¶
func (h *CGGMP21Handler) Name() Protocol
func (*CGGMP21Handler) SetExecutor ¶
func (h *CGGMP21Handler) SetExecutor(executor *ProtocolExecutor)
SetExecutor sets the protocol executor for the handler
func (*CGGMP21Handler) SetMessageRouter ¶
func (h *CGGMP21Handler) SetMessageRouter(router MessageRouter)
SetMessageRouter sets the message router for multi-party communication
func (*CGGMP21Handler) SupportedCurves ¶
func (h *CGGMP21Handler) SupportedCurves() []string
type CMPKeyShare ¶
type CMPKeyShare struct {
}
CMPKeyShare wraps cmpconfig.Config to implement KeyShare.
func (*CMPKeyShare) Generation ¶
func (s *CMPKeyShare) Generation() uint64
Generation returns the key generation number.
func (*CMPKeyShare) PartyID ¶
func (s *CMPKeyShare) PartyID() party.ID
PartyID returns this party's ID.
func (*CMPKeyShare) Protocol ¶
func (s *CMPKeyShare) Protocol() Protocol
Protocol returns which protocol this share is for.
func (*CMPKeyShare) PublicKey ¶
func (s *CMPKeyShare) PublicKey() []byte
PublicKey returns the group public key.
func (*CMPKeyShare) Serialize ¶
func (s *CMPKeyShare) Serialize() ([]byte, error)
Serialize converts the share to bytes for storage.
func (*CMPKeyShare) Threshold ¶
func (s *CMPKeyShare) Threshold() int
Threshold returns the threshold t.
func (*CMPKeyShare) TotalParties ¶
func (s *CMPKeyShare) TotalParties() int
TotalParties returns total parties n.
type CeremonyInfo ¶ added in v1.7.10
type CeremonyInfo struct {
CeremonyID string `json:"ceremonyId"`
Kind string `json:"kind"` // keygen | sign
KeyID string `json:"keyId"`
Digest string `json:"digest"` // 0x-hex, 32 bytes
Signature string `json:"signature"` // 0x-hex, 65 bytes r‖s‖v
R string `json:"r,omitempty"`
S string `json:"s,omitempty"`
V int `json:"v,omitempty"`
// Signers is the participating quorum, canonically ordered.
Signers []string `json:"signers"`
RequestingChain string `json:"requestingChain,omitempty"`
Height uint64 `json:"height,omitempty"`
}
CeremonyInfo is one ceremony as the chain records it: what was signed, by whom, and the signature it produced. It is the shape returned both by a ceremony that just ran and by a lookup in the replicated ceremony log, so a caller parses one thing.
Height is 0 for a ceremony that has completed but whose block has not been accepted yet — the signature is valid, it just has no place in history yet.
type CeremonyRecord ¶ added in v1.7.10
type CeremonyRecord struct {
// ID is the derived ceremony id — H(tag ‖ keyID ‖ digest ‖ sorted signers).
// Derived, not announced: every validator computing the same task lands on
// the same id with no coordination round and no coordinator.
ID string
// Kind is the operation: OpTypeKeygen or OpTypeSign.
Kind string
// KeyID is the custody key the ceremony created or used.
KeyID string
// Digest is the 32-byte message that was signed (sign ceremonies) or the
// key-commit digest (keygen ceremonies).
Digest []byte
// Signers are the parties that participated, in canonical order.
Signers []party.ID
// Artifact is the ceremony's verifiable output: for a sign ceremony the
// 65-byte r‖s‖v signature; for a keygen ceremony the proof-of-possession
// over KeyCommitDigest.
Artifact []byte
// RequestingChain names the chain that asked for this ceremony (B-Chain for
// bridge custody). Empty for locally initiated ceremonies.
RequestingChain string
// Height is the M-Chain height at which the ceremony was recorded.
Height uint64
}
CeremonyRecord is the replicated record of one completed ceremony. It is the audit trail: which key, over which digest, by which signers, producing what.
type ChainPermissions ¶
type ChainPermissions struct {
ChainID string `json:"chainId"`
ChainName string `json:"chainName"`
CanSign bool `json:"canSign"` // Can request signatures
CanKeygen bool `json:"canKeygen"` // Can request new key generation
AllowedKeyTypes []string `json:"allowedKeyTypes"` // secp256k1, ed25519, etc.
MaxSigningSize int `json:"maxSigningSize"` // Max message size to sign
RequirePreHash bool `json:"requirePreHash"` // Require pre-hashed messages
DailySigningLimit uint64 `json:"dailySigningLimit"` // Override global quota
}
ChainPermissions defines what a chain can do with MPC services
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client provides access to mpcvm services. Per LP-134, this serves M-Chain (MPC mode) and F-Chain (FHE mode); legacy T-Chain MPC routes here.
func (*Client) GetAddress ¶
GetAddress retrieves the address for a key ID
func (*Client) GetCeremony ¶ added in v1.7.10
GetCeremony reads one recorded ceremony from replicated state.
func (*Client) GetInfo ¶
func (c *Client) GetInfo(ctx context.Context) (*ThresholdInfo, error)
GetInfo retrieves M-Chain information.
func (*Client) GetProtocolInfo ¶
GetProtocolInfo retrieves info for a specific protocol
func (*Client) GetProtocols ¶
func (c *Client) GetProtocols(ctx context.Context) ([]ProtocolInfo, error)
GetProtocols retrieves all supported protocols
func (*Client) GetPublicKey ¶
GetPublicKey retrieves the public key for a key ID
func (*Client) GetStats ¶
func (c *Client) GetStats(ctx context.Context) (*NetworkStats, error)
GetStats retrieves T-Chain statistics
func (*Client) Keygen ¶
func (c *Client) Keygen(ctx context.Context, req KeygenRequest) (*KeygenResponse, error)
Keygen runs a distributed key generation and returns when the key exists. There is no status to poll afterwards: the ceremony either produced a registered key or returned an error.
func (*Client) ListCeremonies ¶ added in v1.7.10
func (c *Client) ListCeremonies(ctx context.Context) ([]CeremonyInfo, error)
ListCeremonies reads the whole ceremony log.
func (*Client) Sign ¶
func (c *Client) Sign(ctx context.Context, req SignRequest) (*CeremonyInfo, error)
Sign runs a threshold signing ceremony and returns the finished signature.
The call blocks for the duration of the ceremony. The returned CeremonyID is the durable handle: GetCeremony re-reads the same signature from replicated state once the block carrying it is accepted.
type CoronaHandler ¶
type CoronaHandler struct{}
CoronaHandler implements ProtocolHandler for post-quantum threshold signatures
func (*CoronaHandler) Name ¶
func (h *CoronaHandler) Name() Protocol
func (*CoronaHandler) SupportedCurves ¶
func (h *CoronaHandler) SupportedCurves() []string
type CrossChainMPCRequest ¶
type CrossChainMPCRequest struct {
Type string `json:"type"` // sign, keygen, reshare
RequestingChain string `json:"requestingChain"`
KeyID string `json:"keyId"`
KeyType string `json:"keyType,omitempty"`
MessageHash []byte `json:"messageHash,omitempty"`
MessageType string `json:"messageType,omitempty"`
}
CrossChainMPCRequest is the request format for cross-chain MPC operations
func (*CrossChainMPCRequest) Marshal ¶ added in v1.7.4
func (r *CrossChainMPCRequest) Marshal() ([]byte, error)
type ECDSASignature ¶
ECDSASignature wraps ECDSA signature from threshold library.
type EpochBeaconAttestation ¶
type EpochBeaconAttestation struct {
Epoch uint64 `json:"epoch"`
Randomness [32]byte `json:"randomness"`
PreviousRef [32]byte `json:"previousRef"`
}
EpochBeaconAttestation contains details for epoch beacon attestations
type FHEService ¶
type FHEService interface {
ThresholdService
}
FHEService is the F-Chain surface: confidential compute over encrypted state. It CONSUMES ThresholdService key/decryption committees; it owns FHE jobs and threshold-decrypt. The FHE execution primitives live in the fhe/ subpackage (fhe.FHEAccelerator); this interface is the chain-facing surface the physical fhevm package will implement in the follow-up split. Kept minimal and honest: today the single *VM exposes the ThresholdService substrate that F-Chain's FHE runtime consumes, so FHEService embeds it and the FHE-execution methods are added as the fhevm package is carved out.
type FROSTKeyShare ¶
type FROSTKeyShare struct {
}
FROSTKeyShare wraps frostconfig.Config to implement KeyShare.
func (*FROSTKeyShare) Generation ¶
func (s *FROSTKeyShare) Generation() uint64
Generation returns the key generation number.
func (*FROSTKeyShare) PartyID ¶
func (s *FROSTKeyShare) PartyID() party.ID
PartyID returns this party's ID.
func (*FROSTKeyShare) Protocol ¶
func (s *FROSTKeyShare) Protocol() Protocol
Protocol returns which protocol this share is for.
func (*FROSTKeyShare) PublicKey ¶
func (s *FROSTKeyShare) PublicKey() []byte
PublicKey returns the group public key.
func (*FROSTKeyShare) Serialize ¶
func (s *FROSTKeyShare) Serialize() ([]byte, error)
Serialize converts the share to bytes for storage.
func (*FROSTKeyShare) Threshold ¶
func (s *FROSTKeyShare) Threshold() int
Threshold returns the threshold t.
func (*FROSTKeyShare) TotalParties ¶
func (s *FROSTKeyShare) TotalParties() int
TotalParties returns total parties n.
type GPUBackend ¶
type GPUBackend struct {
Kind GPUBackendKind
Path string // dlopen'd library path, for diagnostics
// contains filtered or unexported fields
}
GPUBackend is the resolved plugin substrate. Zero value = not available.
func Backend ¶
func Backend() *GPUBackend
Backend returns the resolved GPU plugin. nil means no plugin was loaded.
func (*GPUBackend) CeremonyApply ¶
func (g *GPUBackend) CeremonyApply( desc *GPUMPCVMRoundDescriptor, ceremonyOps []GPUCeremonyOp, ceremonies []GPUCeremony, ) (applied uint32, err error)
CeremonyApply applies ceremony begin/cancel ops to the ceremony table. Contribution slots are not touched (callers passing nil contribution_ops get the lean ceremony-admin dispatch).
ceremonies is the open-addressed ceremony hash table (must be a power-of-2 length on the device-side; the Go caller owns the buffer). The kernel mutates it in place; the round descriptor's CeremonyOpCount tells the kernel how many ops to consume from ceremonyOps.
next_contribution_id_in is the substrate's monotonically increasing contribution-id counter at the start of the round; the kernel doesn't advance it on the ceremony-only path but the parameter is part of the shared launcher signature.
func (*GPUBackend) ContributionApply ¶
func (g *GPUBackend) ContributionApply( desc *GPUMPCVMRoundDescriptor, contributionOps []GPUContributionOp, ceremonies []GPUCeremony, contributions []GPUContribution, nextContributionID uint64, ) (applied uint32, err error)
ContributionApply applies contribution payloads to the contribution table. Ceremony slots are not touched (callers passing nil ceremonyOps get the lean contribution-only dispatch). Uses the same ceremony_apply kernel because the dedup-and-write path is the same on the device side; only the op stream differs.
func (*GPUBackend) IsAvailable ¶
func (g *GPUBackend) IsAvailable() bool
IsAvailable reports whether the bridge has a usable plugin with at least the ceremony_apply and ceremony_sweep launchers resolved. compute_leaves and compose_root are required for MPCTransition but are checked per-method to allow partial GPU coverage when a plugin ships fewer symbols (e.g. an early Vulkan port).
func (*GPUBackend) KeyShareApply ¶
func (g *GPUBackend) KeyShareApply( desc *GPUMPCVMRoundDescriptor, ceremonies []GPUCeremony, keyShares []GPUKeyShare, contributions []GPUContribution, nextShareID uint64, ) (roundAdvance, finalized, failed uint32, err error)
KeyShareApply runs the per-slot fan-out sweep that advances ceremonies, finalizes keygens (assigning canonical share_ids), and times out expired ceremonies. Backed by lux_<X>_mpcvm_ceremony_sweep.
On DKG finalize, fresh KeyShare slots are written into keyShares with the share_data_len matching the scheme (Frost=65, CGGMP21=65, Corona=256). next_share_id_in seeds the prefix-sum scheme that gives every finalized share a deterministic share_id.
func (*GPUBackend) MPCTransition ¶
func (g *GPUBackend) MPCTransition( desc *GPUMPCVMRoundDescriptor, ceremonies []GPUCeremony, keyShares []GPUKeyShare, contributions []GPUContribution, state *GPUMPCVMState, ) (*GPUMPCVMTransitionResult, error)
MPCTransition runs the per-leaf keccak pass and the canonical-order fold pass, producing the round's MPCVMTransitionResult and advancing the substrate state. This is the composition of compute_leaves and compose_root — one substrate state transition per call.
Returns the result envelope written by compose_root. The substrate state in `state` is also updated in place (cur_epoch, now_ns, counts, all four roots).
type GPUBackendKind ¶
type GPUBackendKind uint8
GPUBackendKind is the resolved plugin family. Matches the dlopen probe order in backend.go: cuda → hip → metal → vulkan → webgpu.
const ( GPUBackendNone GPUBackendKind = 0 GPUBackendCUDA GPUBackendKind = 1 GPUBackendHIP GPUBackendKind = 2 GPUBackendMetal GPUBackendKind = 3 GPUBackendVulkan GPUBackendKind = 4 GPUBackendWebGPU GPUBackendKind = 5 )
func (GPUBackendKind) String ¶
func (k GPUBackendKind) String() string
String returns the launcher prefix used in symbol resolution.
type GPUCeremony ¶
type GPUCeremony struct {
CeremonyID uint64
StartedAtNs uint64
DeadlineNs uint64
ParticipantsBitmap uint64
Kind uint32
Round uint32
Threshold uint32
TotalParticipants uint32
Status uint32
ContributionCount uint32
Subject [32]byte
CeremonySeed [32]byte
// contains filtered or unexported fields
}
GPUCeremony is the on-GPU ceremony state. 128 bytes, __align__(16). The GPU prefix distinguishes the wire mirror from the domain-level Ceremony types in protocols.go / runtime/. ONLY the GPU bridge ever touches these.
type GPUCeremonyOp ¶
type GPUCeremonyOp struct {
CeremonyID uint64
DeadlineNs uint64
Kind uint32
CeremonyKind uint32
Threshold uint32
TotalParticipants uint32
Subject [32]byte
CeremonySeed [32]byte
}
GPUCeremonyOp is one inbound ceremony op (begin/cancel). 96 bytes.
type GPUContribution ¶
type GPUContribution struct {
ContributionID uint64
CeremonyID uint64
HolderAddr uint64
Round uint32
HolderIndex uint32
PayloadLen uint32
Status uint32
Payload [384]byte
Pad0 uint64
}
GPUContribution is the on-GPU contribution record. 432 bytes, __align__(16).
type GPUContributionOp ¶
type GPUContributionOp struct {
CeremonyID uint64
HolderAddr uint64
Round uint32
HolderIndex uint32
PayloadLen uint32
Pad0 uint32
Payload [384]byte
}
GPUContributionOp is one inbound contribution payload. 416 bytes.
type GPUKeyShare ¶
type GPUKeyShare struct {
}
GPUKeyShare is the on-GPU key share record. 368 bytes, __align__(16).
type GPUMPCVMRoundDescriptor ¶
type GPUMPCVMRoundDescriptor struct {
ChainID uint64
Round uint64
TimestampNs uint64
Epoch uint64
Mode uint32
CeremonyOpCount uint32
ContributionOpCount uint32
ClosingFlag uint32
Pad0 uint32
Pad1 uint32
Pad2 uint64
ParentStateRoot [32]byte
}
GPUMPCVMRoundDescriptor describes one round's input envelope. 96 bytes.
type GPUMPCVMState ¶
type GPUMPCVMState struct {
CurrentEpoch uint64
NowNs uint64
ActiveCeremonyCount uint32
FinalizedCeremonyCount uint32
FailedCeremonyCount uint32
CeremonyRoot [32]byte
ContributionRoot [32]byte
MPCVMStateRoot [32]byte
}
GPUMPCVMState is the on-GPU substrate state. 160 bytes, __align__(16).
type GPUMPCVMTransitionResult ¶
type GPUMPCVMTransitionResult struct {
Status uint32
CeremonyApplyCount uint32
ContributionApplyCount uint32
FinalizedThisRound uint32
FailedThisRound uint32
ActiveCeremonyCount uint32
RoundAdvanceCount uint32
Epoch uint64
NowNs uint64
CeremonyRoot [32]byte
ContributionRoot [32]byte
MPCVMStateRoot [32]byte
}
GPUMPCVMTransitionResult is the transition envelope written by compose_root. 176 bytes.
type Genesis ¶
type Genesis struct {
Timestamp int64 `json:"timestamp"`
Policy quorum.Policy `json:"policy,omitempty"`
}
Genesis represents the genesis state.
Policy is here rather than only in each node's config file because the chain's quorum must be the same value on every validator: a policy that lives per-node can differ per-node, and the first symptom is a key whose declared quorum is not the quorum it was generated with. An absent or malformed policy leaves the config default in place (see Initialize).
type GetCeremonyParams ¶ added in v1.7.10
type GetCeremonyParams struct {
CeremonyID string `json:"ceremonyId"`
}
GetCeremonyParams contains parameters for reading one ceremony.
type GetChainPermissionsParams ¶
type GetChainPermissionsParams struct {
ChainID string `json:"chainId"`
}
GetChainPermissionsParams contains parameters for getting chain permissions
type GetKeyParams ¶
type GetKeyParams struct {
KeyID string `json:"keyId"`
}
GetKeyParams contains parameters for getting a key.
type GetProtocolInfoParams ¶
type GetProtocolInfoParams struct {
Protocol string `json:"protocol"`
}
GetProtocolInfoParams contains parameters for getting protocol info
type GetQuotaParams ¶
type GetQuotaParams struct {
ChainID string `json:"chainId"`
}
GetQuotaParams contains parameters for getting quota
type KeyInfo ¶
type KeyInfo struct {
KeyID string `json:"keyId"`
Kind string `json:"kind"` // threshold protocol that generated it, e.g. cggmp21
// Policy is the operator form, "3-of-5". Degree is the polynomial degree
// (K-1) it was generated with, reported so the two can be checked against
// each other rather than inferred.
Policy string `json:"policy"`
Degree int `json:"degree"`
GroupPublicKey string `json:"groupPublicKey"` // 0x-hex, 33-byte compressed
Address string `json:"address"` // 0x-hex, 20-byte custody address
Participants []string `json:"participants"`
Generation uint64 `json:"generation"`
CreatedHeight uint64 `json:"createdHeight"`
}
KeyInfo is a custody key's replicated public record. It carries no secret and no per-node bookkeeping: every field here is identical on every validator.
type KeyRecord ¶ added in v1.7.10
type KeyRecord struct {
KeyID string
// Kind is the threshold protocol that generated the key (cggmp21, frost,
// ...). A key is bound to its protocol: cross-scheme reuse of a share is
// prohibited (LP-4700), and Kind is what enforces the binding at signing.
Kind string
// Policy is the quorum in operator form: K signers of N parties. The
// polynomial degree the protocol was parameterised with is Policy.Degree(),
// derived — never stored independently, because two stored numbers can
// disagree and one cannot.
Policy quorum.Policy
// Participants are the parties holding a share, in canonical (sorted) order
// so every validator hashes the same bytes. len(Participants) == Policy.N.
Participants []party.ID
// GroupPublicKey is the compressed secp256k1 point (33 bytes) that
// signatures verify under.
GroupPublicKey []byte
// Address is the 20-byte Ethereum-style address of GroupPublicKey — the
// external-chain custody address that actually holds bridged funds.
Address []byte
// Generation increments on each resharing/refresh of the same public key.
Generation uint64
// CreatedHeight is the M-Chain height at which the key was registered.
CreatedHeight uint64
}
KeyRecord is the replicated, public record of one custody key.
It is deliberately share-free: the group public key and the policy are everything a validator needs to check a signature and everything B-Chain needs to know who the custodian is. The share that produced it lives in node state and never leaves the node that generated it.
type KeyShare ¶
type KeyShare interface {
PublicKey() []byte
PartyID() party.ID
Threshold() int
TotalParties() int
Generation() uint64
Protocol() Protocol
Serialize() ([]byte, error)
}
KeyShare represents a threshold key share (abstract)
type KeygenParams ¶
type KeygenParams struct {
KeyID string `json:"keyId"`
RequestedBy string `json:"requestedBy"` // Chain ID; must be authorised to keygen
// Policy is the quorum in operator form, "3-of-5". Omit it to use the
// chain's default. It is deliberately not a pair of numbers: a caller
// cannot express the quorum ambiguously, and the polynomial degree is
// derived from it inside the ceremony rather than passed alongside it.
Policy quorum.Policy `json:"policy,omitempty"`
}
KeygenParams contains parameters for key generation.
type KeygenRequest ¶
type KeygenRequest struct {
KeyID string `json:"keyId"`
// Policy is the quorum in operator form, "3-of-5". Empty means the chain's
// default.
Policy string `json:"policy,omitempty"`
}
KeygenRequest contains parameters for key generation.
type KeygenResponse ¶
type KeygenResponse struct {
Ceremony CeremonyInfo `json:"ceremony"`
Key KeyInfo `json:"key"`
}
KeygenResponse is a COMPLETED key generation.
type KeygenResult ¶
type KeygenResult struct {
Ceremony CeremonyInfo `json:"ceremony"`
Key KeyInfo `json:"key"`
}
KeygenResult is a COMPLETED key generation: the ceremony that ran and the key it registered. There is no status to poll — a keygen that returns has a key, and one that fails returns an error.
type LSSHandler ¶
type LSSHandler struct {
// contains filtered or unexported fields
}
LSSHandler implements ProtocolHandler for LSS
func (*LSSHandler) Name ¶
func (h *LSSHandler) Name() Protocol
func (*LSSHandler) SupportedCurves ¶
func (h *LSSHandler) SupportedCurves() []string
type LSSKeyShare ¶
type LSSKeyShare struct {
}
LSSKeyShare wraps lssconfig.Config to implement KeyShare.
func (*LSSKeyShare) Generation ¶
func (s *LSSKeyShare) Generation() uint64
Generation returns the key generation number.
func (*LSSKeyShare) PartyID ¶
func (s *LSSKeyShare) PartyID() party.ID
PartyID returns this party's ID.
func (*LSSKeyShare) Protocol ¶
func (s *LSSKeyShare) Protocol() Protocol
Protocol returns which protocol this share is for.
func (*LSSKeyShare) PublicKey ¶
func (s *LSSKeyShare) PublicKey() []byte
PublicKey returns the group public key.
func (*LSSKeyShare) Serialize ¶
func (s *LSSKeyShare) Serialize() ([]byte, error)
Serialize converts the share to bytes for storage.
func (*LSSKeyShare) Threshold ¶
func (s *LSSKeyShare) Threshold() int
Threshold returns the threshold t.
func (*LSSKeyShare) TotalParties ¶
func (s *LSSKeyShare) TotalParties() int
TotalParties returns total parties n.
type MPCService ¶
type MPCService interface {
ThresholdService
// RequestSignature asks the custody committee for keyID to threshold-sign
// messageHash on behalf of requestingChain. It returns when the ceremony
// has produced a signature that verifies under the registered group key.
RequestSignature(ctx context.Context, requestingChain, keyID string, messageHash []byte) (*Operation, error)
// Ceremony returns one recorded ceremony — the replicated, durable evidence
// that a signature was produced, including the signature. Ceremonies
// returns the whole log.
Ceremony(id string) (*CeremonyRecord, error)
Ceremonies() ([]*CeremonyRecord, error)
// StateRoot is the value two validators compare to know whether they agree
// about custody.
StateRoot() [32]byte
// RequestBridgeRelease is the B→M seam: a bridge release request in, a
// threshold-signed self-describing attestation out.
RequestBridgeRelease(ctx context.Context, req BridgeReleaseRequest) (*BridgeTransferAttestation, error)
// AttestOracleCommit produces a threshold attestation over an oracle
// read/write commitment for requestingChain.
AttestOracleCommit(ctx context.Context, requestingChain, keyID string, requestID [32]byte, kind uint8, commitRoot [32]byte, epoch uint64) (*QuantumAttestation, error)
// AttestSessionComplete attests that a bridge/custody session finished with
// the given output/oracle/receipts roots.
AttestSessionComplete(ctx context.Context, requestingChain, keyID string, sessionID [32]byte, outputHash, oracleRoot, receiptsRoot [32]byte, epoch uint64) (*QuantumAttestation, error)
// AttestEpochBeacon produces the per-epoch beacon attestation.
AttestEpochBeacon(ctx context.Context, requestingChain, keyID string, epoch uint64, previousRef [32]byte) (*QuantumAttestation, error)
// VerifyAttestation verifies a QuantumAttestation against this node's
// custody registry.
VerifyAttestation(attestation *QuantumAttestation) error
}
MPCService is the M-Chain surface: threshold signing and bridge-custody attestation. It CONSUMES ThresholdService committees to sign / attest over cross-chain subjects. Owns no FHE.
type MessageRouter ¶
type MessageRouter interface {
// Send sends a message to the specified party (or broadcasts if To is empty)
Send(msg *protocol.Message) error
// Receive returns a channel for receiving incoming messages
Receive() <-chan *protocol.Message
}
MessageRouter defines the interface for routing MPC messages between parties.
type NetworkStats ¶
type NetworkStats struct {
TotalSignatures uint64 `json:"totalSignatures"`
TotalKeygens uint64 `json:"totalKeygens"`
StagedCeremonies int `json:"stagedCeremonies"`
SignaturesByChain map[string]uint64 `json:"signaturesByChain"`
}
NetworkStats counts what this node did: ceremonies it completed, and the ceremonies it has finished but not yet gotten into a block.
type Operation ¶
type Operation struct {
Type string
// CeremonyID is derived from (keyID, digest, signer set) — never announced
// by a coordinator. It is the ceremony log's primary key.
CeremonyID string
KeyID string
// RequestingChain names the chain that asked for this ceremony. Empty when
// the ceremony was initiated on M-Chain itself.
RequestingChain string
// Digest is the 32 bytes the ceremony signed: the caller's message digest
// for a sign, the key-commit digest for a keygen.
Digest []byte
// Artifact is the 65-byte r‖s‖v secp256k1 signature the ceremony produced.
Artifact []byte
// Signers is the participating set, canonically ordered.
Signers []party.ID
// Key is the registration carried by a keygen operation; nil otherwise.
Key *KeyRecord
Timestamp int64
}
Operation is one verifiable state transition.
Key is non-nil exactly when Type is OpTypeKeygen: the operation carries the registration it is asking consensus to make, so there is no second place a key record can enter state.
type OracleCommitAttestation ¶
type OracleCommitAttestation struct {
RequestID [32]byte `json:"requestId"`
Kind uint8 `json:"kind"` // 0 = write, 1 = read
Root [32]byte `json:"root"`
RecordCount uint32 `json:"recordCount"`
}
OracleCommitAttestation contains details for oracle commit attestations
type PartyInfo ¶
type PartyInfo struct {
// PartyID and NodeID are the same value in two spellings — party.ID IS the
// NodeID string — and both are reported so a caller reading either column
// needs no side table to join them.
PartyID string `json:"partyId"`
NodeID string `json:"nodeId"`
IsLocal bool `json:"isLocal"`
}
PartyInfo contains party information.
type Protocol ¶
type Protocol string
Protocol represents a threshold signing protocol
const ( // ECDSA Threshold Protocols ProtocolLSS Protocol = "lss" // Lux Secret Sharing - optimized for Lux ProtocolCGGMP21 Protocol = "cggmp21" // Canetti-Gennaro-Goldfeder-Makriyannis-Peled 2021 // BLS Threshold (for validators) ProtocolBLS Protocol = "bls" // BLS threshold signatures // Post-Quantum Threshold ProtocolCorona Protocol = "corona" // Post-quantum lattice-based threshold // Experimental ProtocolFrost Protocol = "frost" // FROST (Flexible Round-Optimized Schnorr Threshold) ProtocolEDDSA Protocol = "eddsa" // EdDSA threshold (Ed25519) )
type ProtocolConfig ¶
type ProtocolConfig struct {
Protocol Protocol `json:"protocol"`
Threshold int `json:"threshold"` // t: number of parties required
TotalParties int `json:"totalParties"` // n: total parties
Curve string `json:"curve"` // secp256k1, ed25519, bls12-381, etc.
Options ProtocolOptions `json:"options"`
}
ProtocolConfig contains configuration for a specific protocol
type ProtocolExecutor ¶
type ProtocolExecutor struct {
// contains filtered or unexported fields
}
ProtocolExecutor manages MPC protocol execution using the threshold library. It provides the bridge between ThresholdVM session management and the actual MPC protocol implementations.
func NewProtocolExecutor ¶
func NewProtocolExecutor(workerPool *pool.Pool, logger log.Logger) *ProtocolExecutor
NewProtocolExecutor creates a new protocol executor.
func (*ProtocolExecutor) AcceptMessage ¶
func (pe *ProtocolExecutor) AcceptMessage(sessionID string, msg *protocol.Message) error
AcceptMessage routes an incoming message to the appropriate handler.
func (*ProtocolExecutor) CMPKeygenStartFunc ¶
func (pe *ProtocolExecutor) CMPKeygenStartFunc( selfID party.ID, participants []party.ID, threshold int, ) protocol.StartFunc
CMPKeygenStartFunc returns a StartFunc for CMP key generation.
func (*ProtocolExecutor) CMPRefreshStartFunc ¶
func (pe *ProtocolExecutor) CMPRefreshStartFunc(config *cmpconfig.Config) protocol.StartFunc
CMPRefreshStartFunc returns a StartFunc for CMP key refresh.
func (*ProtocolExecutor) CMPSignStartFunc ¶
func (pe *ProtocolExecutor) CMPSignStartFunc( config *cmpconfig.Config, signers []party.ID, messageHash []byte, ) protocol.StartFunc
CMPSignStartFunc returns a StartFunc for CMP signing.
func (*ProtocolExecutor) CreateHandler ¶
func (pe *ProtocolExecutor) CreateHandler( ctx context.Context, sessionID string, startFunc protocol.StartFunc, ) (*protocol.Handler, error)
CreateHandler creates a new protocol handler for a session.
func (*ProtocolExecutor) FROSTKeygenStartFunc ¶
func (pe *ProtocolExecutor) FROSTKeygenStartFunc( selfID party.ID, participants []party.ID, threshold int, ) protocol.StartFunc
FROSTKeygenStartFunc returns a StartFunc for FROST key generation.
func (*ProtocolExecutor) FROSTKeygenTaprootStartFunc ¶
func (pe *ProtocolExecutor) FROSTKeygenTaprootStartFunc( selfID party.ID, participants []party.ID, threshold int, ) protocol.StartFunc
FROSTKeygenTaprootStartFunc returns a StartFunc for FROST Taproot key generation.
func (*ProtocolExecutor) FROSTRefreshStartFunc ¶
func (pe *ProtocolExecutor) FROSTRefreshStartFunc( config *frostconfig.Config, participants []party.ID, ) protocol.StartFunc
FROSTRefreshStartFunc returns a StartFunc for FROST key refresh.
func (*ProtocolExecutor) FROSTSignStartFunc ¶
func (pe *ProtocolExecutor) FROSTSignStartFunc( config *frostconfig.Config, signers []party.ID, messageHash []byte, ) protocol.StartFunc
FROSTSignStartFunc returns a StartFunc for FROST signing.
func (*ProtocolExecutor) GetHandler ¶
func (pe *ProtocolExecutor) GetHandler(sessionID string) (*protocol.Handler, bool)
GetHandler retrieves an active handler by session ID.
func (*ProtocolExecutor) LSSKeygenStartFunc ¶
func (pe *ProtocolExecutor) LSSKeygenStartFunc( selfID party.ID, participants []party.ID, threshold int, ) protocol.StartFunc
LSSKeygenStartFunc returns a StartFunc for LSS key generation.
func (*ProtocolExecutor) LSSRefreshStartFunc ¶
func (pe *ProtocolExecutor) LSSRefreshStartFunc(config *lssconfig.Config) protocol.StartFunc
LSSRefreshStartFunc returns a StartFunc for LSS key refresh.
func (*ProtocolExecutor) LSSReshareStartFunc ¶
func (pe *ProtocolExecutor) LSSReshareStartFunc( config *lssconfig.Config, newParticipants []party.ID, newThreshold int, ) protocol.StartFunc
LSSReshareStartFunc returns a StartFunc for LSS resharing.
func (*ProtocolExecutor) LSSSignStartFunc ¶
func (pe *ProtocolExecutor) LSSSignStartFunc( config *lssconfig.Config, signers []party.ID, messageHash []byte, ) protocol.StartFunc
LSSSignStartFunc returns a StartFunc for LSS signing.
func (*ProtocolExecutor) RemoveHandler ¶
func (pe *ProtocolExecutor) RemoveHandler(sessionID string)
RemoveHandler removes a handler from active tracking.
func (*ProtocolExecutor) RunCMPKeygen ¶
func (pe *ProtocolExecutor) RunCMPKeygen( ctx context.Context, sessionID string, selfID party.ID, participants []party.ID, threshold int, messageRouter MessageRouter, ) (*cmpconfig.Config, error)
RunCMPKeygen executes a complete CMP key generation protocol.
func (*ProtocolExecutor) RunCMPRefresh ¶
func (pe *ProtocolExecutor) RunCMPRefresh( ctx context.Context, sessionID string, config *cmpconfig.Config, messageRouter MessageRouter, ) (*cmpconfig.Config, error)
RunCMPRefresh executes a complete CMP key refresh protocol.
func (*ProtocolExecutor) RunCMPSign ¶
func (pe *ProtocolExecutor) RunCMPSign( ctx context.Context, sessionID string, config *cmpconfig.Config, signers []party.ID, messageHash []byte, messageRouter MessageRouter, ) (*ECDSASignature, error)
RunCMPSign executes a complete CMP signing protocol.
func (*ProtocolExecutor) RunFROSTKeygen ¶
func (pe *ProtocolExecutor) RunFROSTKeygen( ctx context.Context, sessionID string, selfID party.ID, participants []party.ID, threshold int, messageRouter MessageRouter, ) (*frostconfig.Config, error)
RunFROSTKeygen executes a complete FROST key generation protocol.
func (*ProtocolExecutor) RunLSSKeygen ¶
func (pe *ProtocolExecutor) RunLSSKeygen( ctx context.Context, sessionID string, selfID party.ID, participants []party.ID, threshold int, messageRouter MessageRouter, ) (*lssconfig.Config, error)
RunLSSKeygen executes a complete LSS key generation protocol. This is a convenience method that creates a handler and waits for completion. For multi-party scenarios, use CreateHandler and manage message routing manually.
func (*ProtocolExecutor) RunLSSSign ¶
func (pe *ProtocolExecutor) RunLSSSign( ctx context.Context, sessionID string, config *lssconfig.Config, signers []party.ID, messageHash []byte, messageRouter MessageRouter, ) (*ECDSASignature, error)
RunLSSSign executes a complete LSS signing protocol.
type ProtocolHandler ¶
type ProtocolHandler interface {
// Keygen generates a new threshold key
Keygen(ctx context.Context, partyID party.ID, partyIDs []party.ID, threshold int) (KeyShare, error)
// Sign creates a threshold signature
Sign(ctx context.Context, share KeyShare, message []byte, signers []party.ID) (Signature, error)
// Verify verifies a threshold signature
Verify(pubKey []byte, message []byte, signature Signature) (bool, error)
Reshare(ctx context.Context, share KeyShare, newPartyIDs []party.ID, newThreshold int) (KeyShare, error)
// Refresh refreshes the key shares without changing the public key
Refresh(ctx context.Context, share KeyShare) (KeyShare, error)
// Name returns the protocol name
Name() Protocol
// SupportedCurves returns the curves this protocol supports
SupportedCurves() []string
}
ProtocolHandler defines the interface for all threshold protocols. Real implementations are in github.com/luxfi/threshold (LSS, CMP, FROST). Use ProtocolExecutor in executor.go for actual protocol execution.
type ProtocolInfo ¶
type ProtocolInfo struct {
Name string `json:"name"`
Description string `json:"description"`
SupportedCurves []string `json:"supportedCurves"`
KeySize int `json:"keySize"`
SignatureSize int `json:"signatureSize"`
IsPostQuantum bool `json:"isPostQuantum"`
SupportsRefresh bool `json:"supportsRefresh"`
}
ProtocolInfo contains protocol information
func GetProtocolInfo ¶
func GetProtocolInfo() []ProtocolInfo
GetProtocolInfo returns information about all supported protocols
type ProtocolOptions ¶
type ProtocolOptions struct {
// LSS Options
LSSGeneration uint64 `json:"lssGeneration,omitempty"` // LSS generation number
// CGGMP21 Options
CMPPrecompute bool `json:"cmpPrecompute,omitempty"` // Enable precomputation for faster signing
// BLS Options
BLSScheme string `json:"blsScheme,omitempty"` // basic, min-pk, min-sig
// Corona Options
CoronaSecurityLevel int `json:"coronaSecurityLevel,omitempty"` // 128, 192, 256
// General Options
TimeoutSeconds int `json:"timeoutSeconds,omitempty"`
RetryOnFailure bool `json:"retryOnFailure,omitempty"`
}
ProtocolOptions contains protocol-specific options
type ProtocolRegistry ¶
type ProtocolRegistry struct {
// contains filtered or unexported fields
}
ProtocolRegistry manages available protocols
func NewProtocolRegistry ¶
func NewProtocolRegistry(workerPool *pool.Pool) *ProtocolRegistry
NewProtocolRegistry creates a new protocol registry
func (*ProtocolRegistry) Available ¶
func (r *ProtocolRegistry) Available() []Protocol
Available returns all available protocols
func (*ProtocolRegistry) Get ¶
func (r *ProtocolRegistry) Get(protocol Protocol) (ProtocolHandler, error)
Get retrieves a protocol handler
func (*ProtocolRegistry) Register ¶
func (r *ProtocolRegistry) Register(handler ProtocolHandler)
Register adds a protocol handler
type QuantumAttestation ¶
type QuantumAttestation struct {
// Domain specifies what is being attested (oracle/write, session/complete, etc.)
Domain AttestationDomain `json:"domain"`
// AttestationID is a unique identifier for this attestation
AttestationID [32]byte `json:"attestationId"`
// SubjectID is the ID of what is being attested (request_id, session_id, epoch number)
SubjectID [32]byte `json:"subjectId"`
// CommitmentRoot is the Merkle root being attested
CommitmentRoot [32]byte `json:"commitmentRoot"`
// Epoch in which this attestation was created
Epoch uint64 `json:"epoch"`
// Timestamp when attestation was created
Timestamp time.Time `json:"timestamp"`
// KeyID of the custody key that signed.
KeyID string `json:"keyId"`
// CeremonyID is the ceremony that produced Signature — the primary key of
// the replicated ceremony log, so an attestation handed to another chain
// can be looked up and re-checked against M-Chain state.
CeremonyID string `json:"ceremonyId"`
// Policy is the key's quorum in operator form ("3-of-5"). It is what
// VerifyAttestation checks Signers against; a bare threshold number would
// be ambiguous between signer count and polynomial degree.
Policy quorum.Policy `json:"policy"`
// Signers are the parties that participated, canonically ordered.
Signers []party.ID `json:"signers"`
// Signature is the 65-byte r‖s‖v threshold signature over the attestation
// payload — the same encoding every ceremony artifact uses.
Signature []byte `json:"signature"`
}
QuantumAttestation represents a threshold attestation over a commitment.
type QuotaInfo ¶
type QuotaInfo struct {
ChainID string `json:"chainId"`
DailyLimit uint64 `json:"dailyLimit"`
UsedToday uint64 `json:"usedToday"`
Remaining uint64 `json:"remaining"`
ResetTime int64 `json:"resetTime"`
}
QuotaInfo contains quota information
type RPCError ¶
type RPCError struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
RPCError represents a JSON-RPC error
type RPCRequest ¶
type RPCRequest struct {
JSONRPC string `json:"jsonrpc"`
ID interface{} `json:"id"`
Method string `json:"method"`
Params json.RawMessage `json:"params"`
}
RPCRequest represents a JSON-RPC request
type RPCResponse ¶
type RPCResponse struct {
JSONRPC string `json:"jsonrpc"`
ID interface{} `json:"id"`
Result interface{} `json:"result,omitempty"`
Error *RPCError `json:"error,omitempty"`
}
RPCResponse represents a JSON-RPC response
type SchnorrSignature ¶
SchnorrSignature wraps Schnorr signature from FROST.
type SessionCompleteAttestation ¶
type SessionCompleteAttestation struct {
SessionID [32]byte `json:"sessionId"`
OutputHash [32]byte `json:"outputHash"`
OracleRoot [32]byte `json:"oracleRoot"`
ReceiptsRoot [32]byte `json:"receiptsRoot"`
StepCount uint32 `json:"stepCount"`
}
SessionCompleteAttestation contains details for session completion attestations
type SignParams ¶
type SignParams struct {
KeyID string `json:"keyId"`
// MessageHash is the exact 32 bytes to sign, hex encoded. M-Chain does not
// hash on the caller's behalf: the caller owns its signing domain, and a
// chain that re-hashed would sign a preimage nobody authorised.
MessageHash string `json:"messageHash"`
RequestingChain string `json:"requestingChain"`
}
SignParams contains parameters for signing.
type SignRequest ¶
type SignRequest struct {
KeyID string `json:"keyId"`
// MessageHash is the exact 32 bytes to sign. The caller owns its signing
// domain; M-Chain signs what it is given and never re-hashes.
MessageHash []byte `json:"messageHash"`
}
SignRequest contains parameters for signing.
type Signature ¶
type Signature interface {
// Bytes returns the raw signature bytes
Bytes() []byte
// R returns R component (for ECDSA)
R() *big.Int
// S returns S component (for ECDSA)
S() *big.Int
// V returns recovery ID (for ECDSA/Ethereum)
V() byte
// Protocol returns which protocol created this signature
Protocol() Protocol
}
Signature represents a threshold signature (abstract)
type State ¶ added in v1.7.10
type State struct {
// contains filtered or unexported fields
}
State is M-Chain's persisted state over one database. It owns the encoding and the root; it does not know what a ceremony means.
State is not safe for concurrent use; the VM holds it under its own lock. That is deliberate — a state machine with its own internal locking invites callers to interleave reads and writes across a transition and observe a half-applied block.
func NewState ¶ added in v1.7.10
NewState opens state over db, resuming from whatever is already persisted. chainID seeds the genesis root so two different chains running the same operations do not produce the same root.
func (*State) BlockIDAtHeight ¶ added in v1.7.10
BlockIDAtHeight resolves a height to its accepted block id. This is the height index the engine relies on across restarts, so it is persisted rather than held in a map that empties on reboot.
func (*State) Ceremonies ¶ added in v1.7.10
func (s *State) Ceremonies() ([]*CeremonyRecord, error)
Ceremonies returns every recorded ceremony in id order.
func (*State) GetCeremony ¶ added in v1.7.10
func (s *State) GetCeremony(id string) (*CeremonyRecord, error)
GetCeremony reads a recorded ceremony.
func (*State) HasShare ¶ added in v1.7.10
HasShare reports whether this node participates in keyID's committee.
func (*State) LastAccepted ¶ added in v1.7.10
LastAccepted returns the persisted accepted tip. found is false on a fresh database, which is the caller's signal to install genesis.
func (*State) PutBlock ¶ added in v1.7.10
PutBlock persists an accepted block and its height index entry.
func (*State) PutCeremony ¶ added in v1.7.10
func (s *State) PutCeremony(c *CeremonyRecord) error
PutCeremony records a completed ceremony. Ceremony ids are derived from (key, digest, signer set), so a repeat id means a genuine replay of an identical task and is rejected: recording it twice would double-count a bridge release.
func (*State) PutKey ¶ added in v1.7.10
PutKey registers a custody key. Registration is once-only: a key id is a permanent binding to a group public key, and silently rebinding it would let a later ceremony redirect custody of live funds. Rotation is a new Generation of the same record via ReplaceKey, never a fresh PutKey.
func (*State) PutShare ¶ added in v1.7.10
PutShare stores this node's secret key share for keyID.
This is the one secret M-Chain writes to disk, and it is written under the node/ prefix so it is structurally outside consensus state and outside Root(). The trust model is the validator's own disk — the same place its staking key lives. A node that loses this cannot sign for keyID and must be re-shared in; a node that leaks it has leaked one share, which is below the policy's corruption bound unless K-1 others leak too.
func (*State) ReplaceKey ¶ added in v1.7.10
ReplaceKey overwrites an existing key record — the resharing/refresh path, where the group public key is unchanged but the shares and generation move.
func (*State) SetLastAccepted ¶ added in v1.7.10
SetLastAccepted records the accepted tip and the root that came with it, in that order: the root is durable before the tip that claims it, so a crash between the two leaves a tip whose root is already stored rather than a tip pointing at a root that was never written.
type ThresholdConfig ¶
type ThresholdConfig struct {
// Policy is the default signing policy for keys created on this chain,
// written the way operators say it: "7-of-10" — seven of ten parties must
// cooperate to produce one signature.
//
// It is deliberately NOT a bare number. A field called `threshold: 7` is
// read as the signer count by operators and as the polynomial degree by
// every threshold library, and those differ by one; a config that meant
// 7-of-10 and was read as a degree produces an 8-of-10 key, silently. The
// operator form cannot be misread, and the degree is derived from it at one
// place (quorum.Policy.Degree) at the keygen boundary.
Policy quorum.Policy `json:"policy"`
// Session Configuration
SessionTimeout time.Duration `json:"sessionTimeout"` // Max wall-clock for one ceremony
MaxActiveSessions int `json:"maxActiveSessions"` // Max concurrent ceremonies
MaxSessionsPerChain int `json:"maxSessionsPerChain"` // Max concurrent ceremonies per requesting chain
MaxOpsPerBlock int `json:"maxOpsPerBlock"` // Max operations in one block
// Quota Configuration (daily limits)
DailySigningQuota map[string]uint64 `json:"dailySigningQuota"` // ChainID -> daily signing limit
// Authorized Chains that can request MPC services
AuthorizedChains map[string]*ChainPermissions `json:"authorizedChains"`
// Key Management
KeyRotationPeriod time.Duration `json:"keyRotationPeriod"` // How often to rotate keys
MaxKeyAge time.Duration `json:"maxKeyAge"` // Maximum age of a key before forced rotation
}
ThresholdConfig contains VM configuration.
type ThresholdInfo ¶
type ThresholdInfo struct {
Version string `json:"version"`
NodeID string `json:"nodeId"`
ChainID string `json:"chainId"`
PartyID string `json:"partyId"`
Policy string `json:"policy"` // default quorum, "3-of-5"
AuthorizedChains []string `json:"authorizedChains"`
TotalKeys int `json:"totalKeys"`
StagedCeremonies int `json:"stagedCeremonies"`
StateRoot string `json:"stateRoot"`
}
ThresholdInfo describes one M-Chain node: what the chain agrees on (policy, authorized chains, key count, state root) and what is true of THIS node (party id, shares held, staged ceremonies). The two are reported separately because conflating them is how an operator concludes the chain is broken when in fact this one validator holds no share.
type ThresholdService ¶
type ThresholdService interface {
// StartKeygen runs a distributed key-generation ceremony for keyID under
// the chain's default policy, attributed to requestedBy.
StartKeygen(ctx context.Context, keyID, requestedBy string) (*Operation, error)
// StartKeygenWithPolicy runs DKG under an explicit k-of-n policy. The
// polynomial degree is derived from the policy, never passed alongside it.
StartKeygenWithPolicy(ctx context.Context, keyID string, policy quorum.Policy, requestedBy string) (*Operation, error)
// Policy returns the chain's default signing policy.
Policy() quorum.Policy
// Committee returns the ceremony party set at a P-Chain height: this
// chain's validators. Joining the signing ring is joining the validator
// set — there is no separate operator registry.
Committee(ctx context.Context, height uint64) ([]party.ID, error)
// Key returns one custody key's replicated public record; Keys returns all
// of them.
Key(keyID string) (*KeyRecord, error)
Keys() ([]*KeyRecord, error)
// PublicKey returns the compressed group public key for keyID.
PublicKey(keyID string) ([]byte, error)
// Address returns the external-chain custody address derived from keyID's
// group public key.
Address(keyID string) ([]byte, error)
}
ThresholdService is the pure threshold-primitive surface — the substrate M-Chain (MPC) and F-Chain (FHE) both consume. It is distributed key generation, committee formation, and lookup of the artifacts those ceremonies produce. It deliberately excludes signing-for-custody (MPCService) and FHE execution (FHEService).
Every ceremony method takes a context and returns the COMPLETED ceremony's operation: a ceremony either finished (and its verifiable artifact is in hand) or it failed. There is no third "in progress" state to poll, because a handle to an unfinished ceremony is a handle to state that only one node has.
type VM ¶
type VM struct {
// contains filtered or unexported fields
}
VM implements the Threshold VM for MPC-as-a-service
func (*VM) AttestBridgeTransfer ¶
func (vm *VM) AttestBridgeTransfer( ctx context.Context, requestingChain string, keyID string, bt BridgeTransfer, ) (*BridgeTransferAttestation, error)
AttestBridgeTransfer produces a threshold attestation over a bridge transfer: compute the domain-bound digest, run the ceremony across the committee, and return the self-describing attestation B verifies.
The ceremony is complete when this returns — the signature is in the returned operation, and the same signature is recorded in the replicated ceremony log under op.CeremonyID once the block carrying it is accepted. B can therefore verify immediately (VerifyBridgeAttestation, no interaction) and audit later (Ceremony(id), against consensus state).
func (*VM) AttestEpochBeacon ¶
func (vm *VM) AttestEpochBeacon( ctx context.Context, requestingChain string, keyID string, epoch uint64, previousRef [32]byte, ) (*QuantumAttestation, error)
AttestEpochBeacon creates a threshold attestation for epoch beacon randomness.
func (*VM) AttestNFTOwnership ¶ added in v1.7.16
func (vm *VM) AttestNFTOwnership( ctx context.Context, requestingChain string, keyID string, claim ownership.Claim, ) (*ownership.Attestation, error)
AttestNFTOwnership threshold-signs an ownership claim and returns it in the portable, self-describing form a verifier consumes — the claim, the quorum that signed, and the group key, so verification needs no callback to M.
The claim's Block is used as the attestation epoch. That makes the temporal binding exactly the block the ownership read was taken at, which gives equivocation a precise meaning: two different facts about one node at one block are contradictory and slashable (DetectEquivocation), while re-attesting the same node at a LATER block is the legitimate way ownership changes hands.
func (*VM) AttestOracleCommit ¶
func (vm *VM) AttestOracleCommit( ctx context.Context, requestingChain string, keyID string, requestID [32]byte, kind uint8, commitRoot [32]byte, epoch uint64, ) (*QuantumAttestation, error)
AttestOracleCommit creates a threshold attestation for an oracle commitment.
func (*VM) AttestSessionComplete ¶
func (vm *VM) AttestSessionComplete( ctx context.Context, requestingChain string, keyID string, sessionID [32]byte, outputHash [32]byte, oracleRoot [32]byte, receiptsRoot [32]byte, epoch uint64, ) (*QuantumAttestation, error)
AttestSessionComplete creates a threshold attestation for session completion.
func (*VM) BuildBlock ¶
BuildBlock implements the chain.ChainVM interface
func (*VM) Ceremonies ¶ added in v1.7.10
func (vm *VM) Ceremonies() ([]*CeremonyRecord, error)
Ceremonies returns the whole ceremony log.
func (*VM) Ceremony ¶ added in v1.7.10
func (vm *VM) Ceremony(id string) (*CeremonyRecord, error)
Ceremony returns a recorded ceremony — the durable, replicated evidence that a signature was produced, including the signature itself.
func (*VM) Committee ¶ added in v1.7.10
Committee returns the ceremony party set: every validator of this chain at the given P-Chain height, in canonical order.
party.ID is the NodeID string, so the mapping from a signer back to the peer that runs it is the exact inverse with no side table to drift out of sync. Canonical ordering makes the set order-independent, which is what lets every validator derive the same ceremony id without exchanging one.
func (*VM) Connected ¶
func (vm *VM) Connected(ctx context.Context, nodeID ids.NodeID, nodeVersion *chain.VersionInfo) error
Connected implements the common.VM interface
func (*VM) CreateHandlers ¶
CreateHandlers implements the common.VM interface
func (*VM) CreateStaticHandlers ¶
CreateStaticHandlers implements the common.VM interface
func (*VM) CrossChainRequest ¶
func (vm *VM) CrossChainRequest(ctx context.Context, chainID ids.ID, requestID uint32, deadline time.Time, request []byte) error
CrossChainRequest implements the common.VM interface. This is how another chain (B-Chain for bridge custody) asks M-Chain for a ceremony.
The ceremony runs to completion here and its result is staged for the next block; the requester reads the outcome from the ceremony log, which is replicated, rather than from a reply that only this node would remember.
func (*VM) CrossChainRequestFailed ¶
func (vm *VM) CrossChainRequestFailed(ctx context.Context, chainID ids.ID, requestID uint32, appErr *warp.Error) error
CrossChainRequestFailed implements the common.VM interface
func (*VM) CrossChainResponse ¶
func (vm *VM) CrossChainResponse(ctx context.Context, chainID ids.ID, requestID uint32, response []byte) error
CrossChainResponse implements the common.VM interface
func (*VM) Disconnected ¶
Disconnected implements the common.VM interface
func (*VM) FeePolicy ¶
FeePolicy exposes the chain's declared fee policy for diagnostics and the boot-time Validate gate.
func (*VM) GetBlockIDAtHeight ¶
GetBlockIDAtHeight implements the chain.HeightIndexedChainVM interface. The index is persisted, so it survives a restart — a purely in-memory height map answers "not found" for every accepted block after a reboot.
func (*VM) Gossip ¶
Gossip implements the common.VM interface. It is the single receive path for cross-validator MPC: every ceremony message (broadcast or directed) arrives here as app-gossip, is decoded to (sessionID, protocol.Message) and handed to the ceremony's router. Messages that arrive before our own router for that ceremony is registered are buffered and drained on register, so no round-one broadcast is lost to a start-order race.
func (*VM) HealthCheck ¶
HealthCheck implements the common.VM interface.
Health is "can this node read its own state", not "does this node hold a key". M-Chain is a custody REGISTRY first and a signer second: a validator that holds no share still serves reads and still verifies every block, so gating health on key material would take healthy nodes out of rotation for doing their job correctly. What a share-less node cannot do — contribute a partial signature — is visible in sharesHeld.
func (*VM) Initialize ¶
Initialize implements the chain.ChainVM interface
func (*VM) LastAccepted ¶
LastAccepted implements the chain.ChainVM interface
func (*VM) NewHTTPHandler ¶
NewHTTPHandler returns HTTP handlers for the VM
func (*VM) ParseBlock ¶
ParseBlock implements the chain.ChainVM interface
func (*VM) PublicKey ¶ added in v1.7.10
PublicKey returns a custody key's compressed group public key.
func (*VM) Request ¶
func (vm *VM) Request(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, request []byte) error
Request implements the common.VM interface
func (*VM) RequestBridgeRelease ¶ added in v1.7.4
func (vm *VM) RequestBridgeRelease(ctx context.Context, req BridgeReleaseRequest) (*BridgeTransferAttestation, error)
RequestBridgeRelease is THE B→M seam: B calls this with a release request and gets back a threshold-signed, self-describing attestation. M computes the domain-bound digest, threshold-signs it across the committee, and returns the signature plus the group key and quorum B needs to verify — no callback to M. B's gate on the return value is VerifyBridgeAttestation.
The signature is a standard secp256k1 ECDSA signature over the domain-bound digest, so a destination-chain gateway contract verifies it exactly like a single-key signature (ecrecover to the custody address).
func (*VM) RequestFailed ¶
func (vm *VM) RequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, appErr *warp.Error) error
RequestFailed implements the common.VM interface
func (*VM) RequestSignature ¶
func (vm *VM) RequestSignature(ctx context.Context, requestingChain, keyID string, messageHash []byte) (*Operation, error)
RequestSignature produces a threshold signature over messageHash with a registered custody key and stages it for the next block.
func (*VM) Response ¶
func (vm *VM) Response(ctx context.Context, nodeID ids.NodeID, requestID uint32, response []byte) error
Response implements the common.VM interface
func (*VM) RunKeygen ¶ added in v1.7.10
func (vm *VM) RunKeygen(ctx context.Context, keyID string, policy quorum.Policy, requestingChain string) (*Operation, error)
RunKeygen generates a custody key across the committee and stages its registration for the next block.
The ceremony is: distributed key generation (no dealer — no party ever holds the whole secret), then a threshold signature by the fresh group key over its own registration digest. That second step is the proof of possession: it demonstrates the committee really can sign with the key it is registering, so a key that would be dead on arrival never reaches the registry, and a proposer cannot register a public key it does not control.
Every participant runs this and stages an identical operation. Non-blocking on the caller's behalf is the caller's business; this returns when the ceremony is done.
func (*VM) RunSign ¶ added in v1.7.10
func (vm *VM) RunSign(ctx context.Context, keyID string, digest []byte, requestingChain string) (*Operation, error)
RunSign produces a threshold signature over digest with a registered custody key and stages it for the next block.
digest must be the exact 32 bytes to sign. M-Chain does not hash on the caller's behalf: the caller knows its own signing domain (an Ethereum tx hash, a bridge release digest), and a chain that re-hashes would produce signatures over a preimage the caller never authorised.
func (*VM) SetPreference ¶
SetPreference implements the chain.ChainVM interface
func (*VM) Shutdown ¶
Shutdown implements the common.VM interface.
Nothing is flushed here. Every durable fact — registered keys, recorded ceremonies, key shares, the accepted tip — is written at the moment it becomes true, not at shutdown. A VM that persists its registry only on a clean shutdown loses it to any crash, kill or power cut, which for a custody chain means losing the record of who holds the funds.
func (*VM) StartKeygen ¶
StartKeygen generates a custody key using the chain's default policy.
func (*VM) StartKeygenWithPolicy ¶ added in v1.7.10
func (vm *VM) StartKeygenWithPolicy(ctx context.Context, keyID string, policy quorum.Policy, requestedBy string) (*Operation, error)
StartKeygenWithPolicy generates a custody key under an explicit k-of-n policy.
The policy is a quorum.Policy, not a pair of ints, so a caller cannot express the quorum ambiguously: "3-of-5" is the only spelling, and the polynomial degree is derived from it inside RunKeygen.
func (*VM) StateRoot ¶ added in v1.7.10
StateRoot returns the current state root — the value two validators compare to know whether they agree about custody.
func (*VM) VerifyAttestation ¶
func (vm *VM) VerifyAttestation(a *QuantumAttestation) error
VerifyAttestation checks an attestation against this node's registry: the domain is one M-Chain issues, the quorum satisfies the key's policy, and the signature verifies under the registered group key over the recomputed payload.
It uses the same verifyGroupSignature that block.go uses to admit a ceremony to state, so an attestation cannot pass here under a rule that a block would have rejected.
func (*VM) WaitForEvent ¶
WaitForEvent blocks until this VM has work for the engine.
M-Chain is demand-driven: it builds a block only when a ceremony has completed and staged an operation. Returning eagerly would spin the engine (the flood loop in chains/manager.go); blocking forever would mean a completed ceremony never reaches a block unless some other chain happened to wake the builder.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cert provides the QuasarCertLane registration and certificate-subject binding logic shared by M-Chain and F-Chain.
|
Package cert provides the QuasarCertLane registration and certificate-subject binding logic shared by M-Chain and F-Chain. |
|
cmd
|
|
|
plugin
command
|
|
|
Package fhe provides GPU-accelerated FHE operations for ThresholdVM.
|
Package fhe provides GPU-accelerated FHE operations for ThresholdVM. |
|
protocol
|
|
|
cggmp21
Package cggmp21 declares the M-Chain CGGMP21 protocol surface.
|
Package cggmp21 declares the M-Chain CGGMP21 protocol surface. |
|
corona_general
Package corona_general declares the M-Chain general-purpose Corona (Module-LWE) threshold protocol surface.
|
Package corona_general declares the M-Chain general-purpose Corona (Module-LWE) threshold protocol surface. |
|
frost
Package frost declares the M-Chain FROST protocol surface.
|
Package frost declares the M-Chain FROST protocol surface. |
|
tfhe_keygen
Package tfhe_keygen declares the cross-chain TFHE bootstrap-key generation surface.
|
Package tfhe_keygen declares the cross-chain TFHE bootstrap-key generation surface. |
|
Package runtime defines the adapter contracts the host chains (M-Chain and F-Chain) implement to plug into the ThresholdVM substrate.
|
Package runtime defines the adapter contracts the host chains (M-Chain and F-Chain) implement to plug into the ThresholdVM substrate. |
|
Package types defines the data types of the ThresholdVM substrate.
|
Package types defines the data types of the ThresholdVM substrate. |