threshold

package
v1.17.27 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 25, 2025 License: BSD-3-Clause Imports: 5 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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
	ErrInvalidKeyShare    = errors.New("threshold: invalid key share")
	ErrInvalidPublicKey   = errors.New("threshold: invalid public key")
	ErrKeyShareMismatch   = errors.New("threshold: key share does not match group key")
	ErrDuplicateKeyShare  = errors.New("threshold: duplicate key share index")
	ErrInsufficientShares = errors.New("threshold: insufficient shares for threshold")
	ErrKeyShareCorrupted  = errors.New("threshold: key share data corrupted")

	// Signature errors
	ErrInvalidSignatureShare       = errors.New("threshold: invalid signature share")
	ErrInvalidSignature            = errors.New("threshold: invalid signature")
	ErrSignatureShareMismatch      = errors.New("threshold: signature share does not match")
	ErrDuplicateSignatureShare     = errors.New("threshold: duplicate signature share index")
	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

func GetAbortingParty(err error) int

GetAbortingParty returns the party index from an identifiable abort error. Returns -1 if the error is not an identifiable abort.

func HasScheme

func HasScheme(id SchemeID) bool

HasScheme returns true if the scheme is registered.

func IsIdentifiableAbort

func IsIdentifiableAbort(err error) bool

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)

	// VerifyShare verifies a single signature share before aggregation.
	// 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.

func (DKGConfig) Validate

func (c DKGConfig) Validate() error

Validate checks if the DKG configuration is valid.

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 returns the party index for this share.
	Index() int

	// GroupKey returns the group public key.
	GroupKey() PublicKey

	// PublicShare returns this party's public key share.
	// This can be used for share verification.
	PublicShare() []byte

	// Threshold returns the signing threshold.
	Threshold() int

	// TotalParties returns the total number of parties.
	TotalParties() int

	// Bytes serializes the key share.
	Bytes() []byte

	// SchemeID returns the scheme this share belongs to.
	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

func NewQuickSign(schemeID SchemeID, groupKey PublicKey, threshold int) (*QuickSign, error)

NewQuickSign creates a new quick signing helper.

func (*QuickSign) GroupKey

func (q *QuickSign) GroupKey() PublicKey

GroupKey returns the group public key.

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.

func (*QuickSign) Threshold

func (q *QuickSign) Threshold() int

Threshold returns the signing threshold.

func (*QuickSign) Verify

func (q *QuickSign) Verify(message []byte, signature Signature) bool

Verify verifies a signature.

type Resharing

type Resharing interface {
	// GenerateReshareMessages creates messages for resharing to new parties.
	GenerateReshareMessages(ctx context.Context, newThreshold, newTotal int) ([]DKGMessage, error)

	// ProcessReshareMessages processes reshare messages to create a new share.
	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 returns the serialized size of a key share in bytes.
	KeyShareSize() int

	// SignatureShareSize returns the serialized size of a signature share in bytes.
	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 deserializes a key share from bytes.
	ParseKeyShare(data []byte) (KeyShare, error)

	// ParsePublicKey deserializes a group public key from bytes.
	ParsePublicKey(data []byte) (PublicKey, error)

	// ParseSignatureShare deserializes a signature share from bytes.
	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 GetScheme

func GetScheme(id SchemeID) (Scheme, error)

GetScheme returns a registered threshold scheme by ID.

func MustGetScheme

func MustGetScheme(id SchemeID) Scheme

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) Index

func (a *SchemeAdapter) Index() int

Index returns this party's index.

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 ListSchemes

func ListSchemes() []SchemeID

ListSchemes returns all registered scheme IDs.

func (SchemeID) IsPostQuantum

func (s SchemeID) IsPostQuantum() bool

IsPostQuantum returns true if the scheme provides post-quantum security.

func (SchemeID) String

func (s SchemeID) String() string

String returns the string representation of the scheme ID.

func (SchemeID) SupportsNonInteractive

func (s SchemeID) SupportsNonInteractive() bool

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
	KeyShareSize   int
	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 {
	Index int
	Err   error
}

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

type SignatureShare interface {
	// Index returns the party index that created this share.
	Index() int

	// Bytes serializes the signature share.
	Bytes() []byte

	// SchemeID returns the scheme this share belongs to.
	SchemeID() SchemeID
}

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 returns this party's public key share.
	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)

	// SignShare creates a signature share for the given message.
	// 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 returns the underlying key share.
	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

	// Shares stores signature shares from each participant.
	// Keyed by party index.
	Shares map[int]SignatureShare

	// PublicShares stores public key shares for verification.
	// 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 {
	// GenerateShares creates all key shares and the group public key.
	// 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.

Directories

Path Synopsis
Package bls implements BLS threshold signatures.
Package bls implements BLS threshold signatures.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL