Files
go-synapse-backupper/pkg/domain/crypto/registry.go
T

85 lines
1.6 KiB
Go

package crypto
import (
"errors"
"fmt"
"sync"
)
// Sentinel errors for registry operations.
var (
ErrUnknownScheme = errors.New("unknown KEM scheme")
ErrDuplicateScheme = errors.New("duplicate KEM scheme registration")
)
// KEMFactory is a constructor function that returns a fresh KEM instance.
type KEMFactory func() KEM
// Registry is a concurrent-safe map of KEM scheme IDs to their factories.
type Registry interface {
Register(
schemeID uint16,
factory KEMFactory,
) error
Lookup(
schemeID uint16,
) (
KEMFactory,
error,
)
}
// registry is the private implementation of Registry.
type registry struct {
mutex sync.RWMutex
factories map[uint16]KEMFactory
}
// NewRegistry creates a new empty Registry.
func NewRegistry() Registry {
return &registry{
factories: make(map[uint16]KEMFactory),
}
}
// Register adds a KEMFactory for the given schemeID.
// Returns ErrDuplicateScheme if the schemeID is already registered.
func (r *registry) Register(schemeID uint16, factory KEMFactory) error {
r.mutex.Lock()
defer r.mutex.Unlock()
if _, exists := r.factories[schemeID]; exists {
return fmt.Errorf(
"scheme 0x%04x: %w",
schemeID,
ErrDuplicateScheme,
)
}
r.factories[schemeID] = factory
return nil
}
// Lookup retrieves the KEMFactory for the given schemeID.
// Returns ErrUnknownScheme if the schemeID is not registered.
func (r *registry) Lookup(
schemeID uint16,
) (
KEMFactory,
error,
) {
r.mutex.RLock()
defer r.mutex.RUnlock()
factory, exists := r.factories[schemeID]
if !exists {
return nil, fmt.Errorf(
"scheme 0x%04x: %w",
schemeID,
ErrUnknownScheme,
)
}
return factory, nil
}