OpenNHP/opennhp · error

unsupported hash type

Error message

unsupported hash type: %d

What it means

NewHash returns this error when passed a HashTypeEnum value that is not HASH_BLAKE2S (0), HASH_SM3 (1), or HASH_SHA256 (2). HashTypeEnum is an int-based enum, so any out-of-range or garbage integer (e.g. an unvalidated value read from config, wire data, or an uninitialized variable) falls into the default branch. It indicates an invalid algorithm selector reaching the crypto layer.

Solutions

  1. Only construct hash types via NewCipherSuite(scheme), which always returns a valid HashType (HASH_SM3 or HASH_BLAKE2S)
  2. Validate any externally-sourced integer against the known constants before casting to HashTypeEnum
  3. Log the offending numeric value (%d) and compare it against the HashTypeEnum constants 0/1/2
  4. If a new hash constant was added, add the corresponding case to NewHash's switch and rebuild

Example fix

// before
h, _ := core.NewHash(core.HashTypeEnum(cfg.HashCode))
// after
if cfg.HashCode < int(core.HASH_BLAKE2S) || cfg.HashCode > int(core.HASH_SHA256) {
    return fmt.Errorf("invalid hash code %d in config", cfg.HashCode)
}
h, err := core.NewHash(core.HashTypeEnum(cfg.HashCode))
if err != nil {
    return err
}
Defensive patterns

Strategy: validation

Validate before calling

func isValidHashType(t core.HashTypeEnum) bool {
    return t >= core.HASH_BLAKE2S && t <= core.HASH_SHA256
}

if !isValidHashType(t) {
    return fmt.Errorf("hash type %d out of range", int(t))
}

Type guard

func asHashType(v int) (core.HashTypeEnum, bool) {
    if v < int(core.HASH_BLAKE2S) || v > int(core.HASH_SHA256) {
        return 0, false
    }
    return core.HashTypeEnum(v), true
}

Try / catch

h, err := core.NewHash(t)
if err != nil {
    if strings.Contains(err.Error(), "unsupported hash type") {
        return fmt.Errorf("bad algorithm selector %d: %w", int(t), err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling NewHash(t) with t cast from an int outside 0-2: an uninitialized HashTypeEnum set to a sentinel like -1, a value decoded from a config file or network message, or an enum extended by another package without updating NewHash's switch.

Common situations: Hand-editing config.toml or code that maps a cipher-scheme number to a hash type incorrectly; deserializing a peer's algorithm identifier that doesn't match the local enum; adding a new hash algorithm to the enum but forgetting the switch case in crypto.go.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/7d2758e8a54cbd71. Report an issue: GitHub.

Appendix: source

Thrown at nhp/core/crypto.go:101

}

func NewHash(t HashTypeEnum) (hash.Hash, error) {
	switch t {
	case HASH_BLAKE2S:
		h, err := blake2s.New256(nil)
		if err != nil {
			return nil, fmt.Errorf("failed to create blake2s hash: %w", err)
		}
		return h, nil

	case HASH_SM3:
		return sm3.New(), nil

	case HASH_SHA256:
		return sha256.New(), nil

	default:
		return nil, fmt.Errorf("unsupported hash type: %d", t)
	}
}

type Ecdh interface {
	SetPrivateKey(prk []byte) error
	PrivateKey() []byte
	PublicKey() []byte
	SharedSecret(pbk []byte) []byte
	Name() string
	PrivateKeyBase64() string
	PublicKeyBase64() string
	Identity() []byte
	MidPublicKey() []byte
}

func ECDHFromKey(t EccTypeEnum, prk []byte) (e Ecdh) {
	switch t {
	case ECC_CURVE25519:

View on GitHub (pinned to 6e04ca5ff0)