Documentation
¶
Overview ¶
Package threshold defines interfaces for threshold signature schemes.
This package provides a unified interface layer for multiple threshold signature implementations including:
- FROST (Flexible Round-Optimized Schnorr Threshold)
- CMP/CGGMP21 (Threshold ECDSA)
- BLS Threshold (Boneh-Lynn-Shacham)
- Ringtail (Lattice-based threshold, post-quantum)
The interfaces are designed to support both interactive (multi-round) and non-interactive threshold signing protocols.
Usage:
scheme, err := threshold.GetScheme(threshold.SchemeFROST)
if err != nil {
return err
}
// Distributed key generation
dkg := scheme.NewDKG(config)
keyShare, err := dkg.Generate(ctx, participants)
// Signing
signer := scheme.NewSigner(keyShare)
share, err := signer.SignShare(ctx, message)
// Aggregation
aggregator := scheme.NewAggregator(groupKey)
signature, err := aggregator.Aggregate(ctx, shares)
Index ¶
- Variables
- func GetAbortingParty(err error) int
- func HasScheme(id SchemeID) bool
- func IsIdentifiableAbort(err error) bool
- func RegisterScheme(scheme Scheme)
- type Aggregator
- type DKG
- type DKGConfig
- type DKGMessage
- type DealerConfig
- type IdentifiableAbortError
- type KeyRefresh
- type KeyShare
- type NonceCommitment
- type NonceState
- type PublicKey
- type QuickSign
- type Resharing
- type Scheme
- type SchemeAdapter
- func (a *SchemeAdapter) Aggregate(ctx context.Context, message []byte, shares []SignatureShare) (Signature, error)
- func (a *SchemeAdapter) GroupKey() PublicKey
- func (a *SchemeAdapter) Index() int
- func (a *SchemeAdapter) PublicShare() []byte
- func (a *SchemeAdapter) SchemeID() SchemeID
- func (a *SchemeAdapter) SignShare(ctx context.Context, message []byte, signers []int) (SignatureShare, error)
- func (a *SchemeAdapter) Threshold() int
- func (a *SchemeAdapter) Verify(message []byte, signature Signature) bool
- func (a *SchemeAdapter) VerifyBytes(message, signature []byte) bool
- func (a *SchemeAdapter) VerifyShare(message []byte, share SignatureShare, publicShare []byte) error
- type SchemeID
- type SchemeInfo
- type SessionManager
- func (m *SessionManager) CleanupExpired(ctx context.Context) int
- func (m *SessionManager) CreateSession(id string, scheme SchemeID, message []byte, groupKey PublicKey, threshold int, ...) (*SigningSession, error)
- func (m *SessionManager) DeleteSession(id string)
- func (m *SessionManager) GetSession(id string) (*SigningSession, error)
- func (m *SessionManager) ListSessions() []string
- type SessionState
- type ShareError
- type Signature
- type SignatureShare
- type Signer
- type SigningSession
- func (s *SigningSession) AddCommitment(index int, commitment NonceCommitment) error
- func (s *SigningSession) AddParticipant(index int, publicShare []byte) error
- func (s *SigningSession) AddShare(index int, share SignatureShare) error
- func (s *SigningSession) Complete(signature Signature)
- func (s *SigningSession) Fail(err error)
- func (s *SigningSession) GetCommitments() []NonceCommitment
- func (s *SigningSession) GetShares() []SignatureShare
- func (s *SigningSession) HasEnoughCommitments() bool
- func (s *SigningSession) HasEnoughShares() bool
- func (s *SigningSession) IsExpired() bool
- type TrustedDealer
- type Verifier
Constants ¶
This section is empty.
Variables ¶
var ( // Configuration errors ErrInvalidThreshold = errors.New("threshold: invalid threshold value") ErrInvalidPartyCount = errors.New("threshold: invalid party count") ErrThresholdTooHigh = errors.New("threshold: threshold must be less than total parties") ErrInvalidPartyIndex = errors.New("threshold: party index out of range") ErrInvalidConfig = errors.New("threshold: invalid configuration") // Scheme errors ErrSchemeNotFound = errors.New("threshold: scheme not registered") ErrSchemeNotSupported = errors.New("threshold: operation not supported by scheme") // Key errors ErrInvalidPublicKey = errors.New("threshold: invalid public key") // Signature errors ErrInvalidSignature = errors.New("threshold: invalid signature") ErrSignatureVerificationFailed = errors.New("threshold: signature verification failed") // Protocol errors ErrProtocolAborted = errors.New("threshold: protocol aborted") ErrInvalidRound = errors.New("threshold: invalid protocol round") ErrMissingMessage = errors.New("threshold: missing message from party") ErrInvalidMessage = errors.New("threshold: invalid protocol message") ErrMessageFromWrongParty = errors.New("threshold: message from unexpected party") ErrMessageFromSelf = errors.New("threshold: cannot process own message") // Nonce errors ErrNonceReused = errors.New("threshold: nonce already used") ErrNonceMissing = errors.New("threshold: nonce state required") ErrInvalidNonce = errors.New("threshold: invalid nonce") ErrNonceCommitmentMismatch = errors.New("threshold: nonce commitment mismatch") // State errors ErrNotInitialized = errors.New("threshold: not initialized") ErrAlreadyComplete = errors.New("threshold: operation already complete") ErrInvalidState = errors.New("threshold: invalid state for operation") // Serialization errors ErrInvalidEncoding = errors.New("threshold: invalid encoding") ErrDataTooShort = errors.New("threshold: data too short") ErrDataTooLong = errors.New("threshold: data too long") ErrVersionMismatch = errors.New("threshold: version mismatch") )
Sentinel errors for threshold signature operations.
Functions ¶
func GetAbortingParty ¶
GetAbortingParty returns the party index from an identifiable abort error. Returns -1 if the error is not an identifiable abort.
func IsIdentifiableAbort ¶
IsIdentifiableAbort returns true if the error is an identifiable abort.
func RegisterScheme ¶
func RegisterScheme(scheme Scheme)
RegisterScheme registers a threshold signature scheme. This should be called during init() by scheme implementations. Panics if the scheme ID is already registered.
Types ¶
type Aggregator ¶
type Aggregator interface {
// Aggregate combines signature shares into a final signature.
// For non-interactive schemes (BLS), this combines shares directly.
// For interactive schemes, commitments from all signers may be required.
Aggregate(ctx context.Context, message []byte, shares []SignatureShare, commitments []NonceCommitment) (Signature, error)
// Returns nil if the share is valid.
VerifyShare(message []byte, share SignatureShare, publicShare []byte) error
// GroupKey returns the group public key for this aggregator.
GroupKey() PublicKey
}
Aggregator combines signature shares into a final signature.
type DKG ¶
type DKG interface {
// Round1 generates the first round message to broadcast.
// Returns the message to send to all other parties.
Round1(ctx context.Context) (DKGMessage, error)
// Round2 processes Round1 messages and generates Round2 messages.
// The input map is keyed by party index.
Round2(ctx context.Context, round1Messages map[int]DKGMessage) (DKGMessage, error)
// Round3 processes Round2 messages and generates the final key share.
// Some schemes may not require Round3; they return the key share from Round2.
Round3(ctx context.Context, round2Messages map[int]DKGMessage) (KeyShare, error)
// NumRounds returns the number of rounds required for this DKG protocol.
NumRounds() int
// GroupKey returns the group public key after DKG completes.
// Returns nil if DKG has not completed.
GroupKey() PublicKey
}
DKG represents a distributed key generation protocol. The protocol proceeds in multiple rounds, with each round producing messages to broadcast and processing received messages.
type DKGConfig ¶
type DKGConfig struct {
// Threshold is the minimum number of parties required to sign (t).
// A valid signature requires at least Threshold+1 shares.
Threshold int
// TotalParties is the total number of parties (n).
TotalParties int
// PartyIndex is this party's index (0 to TotalParties-1).
PartyIndex int
// PartyID is an optional identifier for this party.
PartyID []byte
// Randomness source (defaults to crypto/rand if nil).
Rand io.Reader
}
DKGConfig contains configuration for distributed key generation.
type DKGMessage ¶
type DKGMessage interface {
// Round returns which round this message belongs to.
Round() int
// FromParty returns the index of the party that created this message.
FromParty() int
// Bytes serializes the message for transmission.
Bytes() []byte
}
DKGMessage represents a message in the DKG protocol.
type DealerConfig ¶
type DealerConfig struct {
// Threshold is the minimum number of parties required to sign.
Threshold int
// TotalParties is the total number of parties.
TotalParties int
// Randomness source (defaults to crypto/rand if nil).
Rand io.Reader
}
DealerConfig contains configuration for trusted dealer key generation.
func (DealerConfig) Validate ¶
func (c DealerConfig) Validate() error
Validate checks if the dealer configuration is valid.
type IdentifiableAbortError ¶
type IdentifiableAbortError struct {
// PartyIndex is the index of the misbehaving party.
PartyIndex int
// Round is the protocol round where misbehavior was detected.
Round int
// Reason describes the misbehavior.
Reason string
// Proof contains cryptographic proof of misbehavior (scheme-specific).
Proof []byte
}
IdentifiableAbortError contains information about a misbehaving party. Schemes with identifiable abort can return this error to identify which party caused the protocol to fail.
func (*IdentifiableAbortError) Error ¶
func (e *IdentifiableAbortError) Error() string
type KeyRefresh ¶
type KeyRefresh interface {
// Round1 generates the first round of key refresh messages.
Round1(ctx context.Context) (DKGMessage, error)
// Round2 processes Round1 messages and generates new shares.
Round2(ctx context.Context, round1Messages map[int]DKGMessage) (KeyShare, error)
}
KeyRefresh provides key share refresh functionality. This allows updating shares while keeping the same group key.
type KeyShare ¶
type KeyShare interface {
Index() int
GroupKey() PublicKey
// This can be used for share verification.
PublicShare() []byte
Threshold() int
TotalParties() int
Bytes() []byte
SchemeID() SchemeID
}
KeyShare represents a party's share of the threshold key.
type NonceCommitment ¶
type NonceCommitment interface {
// Bytes serializes the commitment.
Bytes() []byte
// FromParty returns the index of the party that created this commitment.
FromParty() int
}
NonceCommitment represents a commitment to a signing nonce. Used in schemes like FROST that require nonce pre-generation.
type NonceState ¶
type NonceState interface {
// Bytes serializes the nonce state (for secure storage).
Bytes() []byte
// FromParty returns the index of the party that owns this nonce.
FromParty() int
}
NonceState represents the secret nonce state for signing. This must be kept secret and used exactly once.
type PublicKey ¶
type PublicKey interface {
// Bytes serializes the public key.
Bytes() []byte
// Equal returns true if the public keys are identical.
Equal(other PublicKey) bool
// SchemeID returns the scheme this key belongs to.
SchemeID() SchemeID
}
PublicKey represents the threshold group public key.
type QuickSign ¶
type QuickSign struct {
// contains filtered or unexported fields
}
QuickSign provides a one-shot threshold signing helper. It collects shares, aggregates them, and returns the final signature.
func NewQuickSign ¶
NewQuickSign creates a new quick signing helper.
func (*QuickSign) SignAndAggregate ¶
func (q *QuickSign) SignAndAggregate(ctx context.Context, message []byte, signers []Signer) (Signature, error)
SignAndAggregate creates signature shares and aggregates them. This is a convenience method for when all signers are local.
type Resharing ¶
type Resharing interface {
GenerateReshareMessages(ctx context.Context, newThreshold, newTotal int) ([]DKGMessage, error)
ProcessReshareMessages(ctx context.Context, messages []DKGMessage) (KeyShare, error)
}
Resharing provides proactive share update with threshold change.
type Scheme ¶
type Scheme interface {
// ID returns the unique identifier for this scheme.
ID() SchemeID
// Name returns a human-readable name for the scheme.
Name() string
KeyShareSize() int
SignatureShareSize() int
// SignatureSize returns the serialized size of the final signature in bytes.
SignatureSize() int
// PublicKeySize returns the serialized size of the group public key in bytes.
PublicKeySize() int
// NewDKG creates a new distributed key generation instance.
NewDKG(config DKGConfig) (DKG, error)
// NewTrustedDealer creates a trusted dealer for centralized key generation.
// Returns an error if the scheme doesn't support trusted dealer setup.
NewTrustedDealer(config DealerConfig) (TrustedDealer, error)
// NewSigner creates a signer from a key share.
NewSigner(share KeyShare) (Signer, error)
// NewAggregator creates a signature aggregator for the given group key.
NewAggregator(groupKey PublicKey) (Aggregator, error)
// NewVerifier creates a signature verifier for the given group key.
NewVerifier(groupKey PublicKey) (Verifier, error)
ParseKeyShare(data []byte) (KeyShare, error)
// ParsePublicKey deserializes a group public key from bytes.
ParsePublicKey(data []byte) (PublicKey, error)
ParseSignatureShare(data []byte) (SignatureShare, error)
// ParseSignature deserializes a final signature from bytes.
ParseSignature(data []byte) (Signature, error)
}
Scheme represents a threshold signature scheme. It serves as the factory for creating DKG, Signer, and Aggregator instances.
func MustGetScheme ¶
MustGetScheme returns a registered scheme or panics.
type SchemeAdapter ¶
type SchemeAdapter struct {
// contains filtered or unexported fields
}
SchemeAdapter provides a simplified interface for using threshold schemes. It wraps the full scheme interfaces for common use cases.
func NewAdapter ¶
func NewAdapter(share KeyShare) (*SchemeAdapter, error)
NewAdapter creates a new scheme adapter from a key share.
func (*SchemeAdapter) Aggregate ¶
func (a *SchemeAdapter) Aggregate(ctx context.Context, message []byte, shares []SignatureShare) (Signature, error)
Aggregate combines signature shares into a final signature.
func (*SchemeAdapter) GroupKey ¶
func (a *SchemeAdapter) GroupKey() PublicKey
GroupKey returns the group public key.
func (*SchemeAdapter) PublicShare ¶
func (a *SchemeAdapter) PublicShare() []byte
PublicShare returns this party's public key share.
func (*SchemeAdapter) SchemeID ¶
func (a *SchemeAdapter) SchemeID() SchemeID
SchemeID returns the scheme identifier.
func (*SchemeAdapter) SignShare ¶
func (a *SchemeAdapter) SignShare(ctx context.Context, message []byte, signers []int) (SignatureShare, error)
SignShare creates a signature share for the given message.
func (*SchemeAdapter) Threshold ¶
func (a *SchemeAdapter) Threshold() int
Threshold returns the signing threshold.
func (*SchemeAdapter) Verify ¶
func (a *SchemeAdapter) Verify(message []byte, signature Signature) bool
Verify verifies a final signature.
func (*SchemeAdapter) VerifyBytes ¶
func (a *SchemeAdapter) VerifyBytes(message, signature []byte) bool
VerifyBytes verifies a serialized signature.
func (*SchemeAdapter) VerifyShare ¶
func (a *SchemeAdapter) VerifyShare(message []byte, share SignatureShare, publicShare []byte) error
VerifyShare verifies a single signature share.
type SchemeID ¶
type SchemeID uint8
SchemeID identifies a threshold signature scheme.
const ( // SchemeUnknown represents an unknown or uninitialized scheme. SchemeUnknown SchemeID = iota // SchemeFROST is the Flexible Round-Optimized Schnorr Threshold scheme. // Produces Schnorr signatures compatible with Ed25519/EdDSA. SchemeFROST // SchemeCMP is the Canetti-Makriyannis-Pagourtzis threshold ECDSA scheme. // Also known as CGGMP21 in its updated form. SchemeCMP // SchemeBLS is the BLS threshold signature scheme. // Supports non-interactive aggregation. SchemeBLS // SchemeRingtail is the lattice-based threshold signature scheme. // Provides post-quantum security. SchemeRingtail )
func (SchemeID) IsPostQuantum ¶
IsPostQuantum returns true if the scheme provides post-quantum security.
func (SchemeID) SupportsNonInteractive ¶
SupportsNonInteractive returns true if shares can be aggregated without additional communication rounds.
type SchemeInfo ¶
type SchemeInfo struct {
ID SchemeID
Name string
Description string
PostQuantum bool
NonInteractive bool
SignatureSize int
DKGRounds int
SigningRounds int
}
SchemeInfo provides metadata about a threshold scheme.
func AllSchemeInfo ¶
func AllSchemeInfo() []*SchemeInfo
AllSchemeInfo returns information about all registered schemes.
func GetSchemeInfo ¶
func GetSchemeInfo(id SchemeID) (*SchemeInfo, error)
GetSchemeInfo returns information about a registered scheme.
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager manages multiple signing sessions.
func NewSessionManager ¶
func NewSessionManager() *SessionManager
NewSessionManager creates a new session manager.
func (*SessionManager) CleanupExpired ¶
func (m *SessionManager) CleanupExpired(ctx context.Context) int
CleanupExpired removes all expired sessions.
func (*SessionManager) CreateSession ¶
func (m *SessionManager) CreateSession(id string, scheme SchemeID, message []byte, groupKey PublicKey, threshold int, timeout time.Duration) (*SigningSession, error)
CreateSession creates a new signing session.
func (*SessionManager) DeleteSession ¶
func (m *SessionManager) DeleteSession(id string)
DeleteSession removes a session.
func (*SessionManager) GetSession ¶
func (m *SessionManager) GetSession(id string) (*SigningSession, error)
GetSession returns a session by ID.
func (*SessionManager) ListSessions ¶
func (m *SessionManager) ListSessions() []string
ListSessions returns all active session IDs.
type SessionState ¶
type SessionState uint8
SessionState represents the state of a threshold signing session.
const ( // SessionStateNew indicates a newly created session. SessionStateNew SessionState = iota // SessionStateNonceGeneration indicates nonce generation phase. SessionStateNonceGeneration // SessionStateSigning indicates signature share generation phase. SessionStateSigning // SessionStateAggregating indicates signature aggregation phase. SessionStateAggregating // SessionStateComplete indicates the session has completed successfully. SessionStateComplete // SessionStateFailed indicates the session has failed. SessionStateFailed )
func (SessionState) String ¶
func (s SessionState) String() string
String returns the string representation of the session state.
type ShareError ¶
type ShareError struct {
}
ShareError wraps an error with share index information.
func (*ShareError) Error ¶
func (e *ShareError) Error() string
func (*ShareError) Unwrap ¶
func (e *ShareError) Unwrap() error
type Signature ¶
type Signature interface {
// Bytes serializes the signature.
Bytes() []byte
// SchemeID returns the scheme that produced this signature.
SchemeID() SchemeID
}
Signature represents a complete threshold signature.
type SignatureShare ¶
SignatureShare represents a party's share of a threshold signature.
type Signer ¶
type Signer interface {
// Index returns the party index for this signer.
Index() int
PublicShare() []byte
// NonceGen generates a nonce commitment for signing.
// Returns a commitment to broadcast and nonce state to preserve.
// Not all schemes require this step.
NonceGen(ctx context.Context) (NonceCommitment, NonceState, error)
// For multi-round schemes, this may require nonce state from NonceGen.
// The signers parameter contains the indices of all participating signers.
SignShare(ctx context.Context, message []byte, signers []int, nonce NonceState) (SignatureShare, error)
KeyShare() KeyShare
}
Signer creates signature shares for a threshold signing protocol.
type SigningSession ¶
type SigningSession struct {
// ID is a unique identifier for this session.
ID string
// SchemeID identifies the threshold scheme being used.
SchemeID SchemeID
// Message is the message being signed.
Message []byte
// GroupKey is the threshold group public key.
GroupKey PublicKey
// Threshold is the minimum number of signers required.
Threshold int
// Participants contains the indices of parties participating in this session.
Participants []int
// Commitments stores nonce commitments from each participant.
// Keyed by party index.
Commitments map[int]NonceCommitment
// Keyed by party index.
Shares map[int]SignatureShare
// Keyed by party index.
PublicShares map[int][]byte
// State is the current session state.
State SessionState
// Result holds the final signature on success.
Result Signature
// Error holds the error if the session failed.
Error error
// CreatedAt is when the session was created.
CreatedAt time.Time
// UpdatedAt is when the session was last updated.
UpdatedAt time.Time
// Timeout is the session timeout duration.
Timeout time.Duration
// contains filtered or unexported fields
}
SigningSession manages a multi-party threshold signing session. It tracks participants, collected shares, and session state.
func NewSigningSession ¶
func NewSigningSession(id string, scheme SchemeID, message []byte, groupKey PublicKey, threshold int, timeout time.Duration) *SigningSession
NewSigningSession creates a new signing session.
func (*SigningSession) AddCommitment ¶
func (s *SigningSession) AddCommitment(index int, commitment NonceCommitment) error
AddCommitment adds a nonce commitment from a participant.
func (*SigningSession) AddParticipant ¶
func (s *SigningSession) AddParticipant(index int, publicShare []byte) error
AddParticipant adds a party to the session.
func (*SigningSession) AddShare ¶
func (s *SigningSession) AddShare(index int, share SignatureShare) error
AddShare adds a signature share from a participant.
func (*SigningSession) Complete ¶
func (s *SigningSession) Complete(signature Signature)
Complete marks the session as complete with the given signature.
func (*SigningSession) Fail ¶
func (s *SigningSession) Fail(err error)
Fail marks the session as failed with the given error.
func (*SigningSession) GetCommitments ¶
func (s *SigningSession) GetCommitments() []NonceCommitment
GetCommitments returns all collected nonce commitments.
func (*SigningSession) GetShares ¶
func (s *SigningSession) GetShares() []SignatureShare
GetShares returns all collected signature shares.
func (*SigningSession) HasEnoughCommitments ¶
func (s *SigningSession) HasEnoughCommitments() bool
HasEnoughCommitments returns true if enough commitments have been collected.
func (*SigningSession) HasEnoughShares ¶
func (s *SigningSession) HasEnoughShares() bool
HasEnoughShares returns true if enough shares have been collected.
func (*SigningSession) IsExpired ¶
func (s *SigningSession) IsExpired() bool
IsExpired returns true if the session has exceeded its timeout.
type TrustedDealer ¶
type TrustedDealer interface {
// Returns a slice of key shares (indexed 0 to n-1) and the group key.
GenerateShares(ctx context.Context) ([]KeyShare, PublicKey, error)
}
TrustedDealer generates key shares in a centralized manner. This is simpler than DKG but requires trusting the dealer.
type Verifier ¶
type Verifier interface {
// Verify checks if a signature is valid for the given message.
Verify(message []byte, signature Signature) bool
// VerifyBytes verifies a serialized signature.
VerifyBytes(message, signature []byte) bool
// GroupKey returns the group public key for this verifier.
GroupKey() PublicKey
}
Verifier verifies threshold signatures.