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 ®istry{ 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 }