OpenNHP/opennhp · error
extractInitiatorStaticPubKey: chain hash
Error message
extractInitiatorStaticPubKey: chain hash: %w
What it means
extractInitiatorStaticPubKey builds a throwaway chain hash (InitialHash || serverPubKey || ephemeral) to recover the initiator's static public key during checkHMAC. This error wraps a NewHash failure for the cipher suite's hash type, meaning the responder cannot even begin verifying the message.
Solutions
- Align the responder's cipher scheme configuration with the initiator's (both CURVE or both GMSM)
- Validate ciphers.HashType is set from a supported scheme constant
- Call NewHash(hashType) in an init check to fail fast at startup
- Rebuild with complete crypto backends if hash algorithms were trimmed
Example fix
// before
responder, _ := nhpcore.NewDevice(nhpcore.NHP_SERVER)
responder.SetCiphers(&nhpcore.CipherSuites{}) // empty suite
// after
responder.SetCiphers(nhpcore.NewCipherSuites(nhpcore.CIPHER_SCHEME_CURVE)) Defensive patterns
Strategy: validation
Validate before calling
if _, err := nhpcore.NewHash(ciphers.HashType); err != nil {
return fmt.Errorf("responder hash type invalid: %w", err)
} Type guard
func hashReady(c *nhpcore.CipherSuites) bool {
h, err := nhpcore.NewHash(c.HashType)
return err == nil && h != nil
} Try / catch
ppd, err := responder.PacketToMsg(pkt)
if err != nil && strings.Contains(err.Error(), "chain hash") {
log.Errorf("cipher mismatch with initiator: %v", err)
return
} Prevention
- Keep responder and initiator cipher schemes in sync
- Fail fast at startup by instantiating the hash once
- Compile with all required crypto backends
When it happens
Trigger: checkHMAC (nhp/core/responder.go:140) invoked during packet verification with ciphers.HashType that NewHash cannot instantiate (unknown algorithm, zero value, or missing crypto backend).
Common situations: Responder configured with a different/unknown cipher scheme than the peer; uninitialized CipherSuites in a custom code path; builds lacking SM3 (GMSM) support.
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
- failed to create device
- failed to create device from new key
- keystore: generate otp
- failed to create blake2s hash
- failed to create AES-GCM
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/25a2ea66e4fb009f.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/responder.go:140
// instances; doing it here too costs one extra ECDH per RKN-under-
// overload packet, but keeps the noise-transcript machinery untouched
// (and untouchable from this helper, which only takes a *Device, the
// cipher suite, and the header).
func extractInitiatorStaticPubKey(device *Device, ciphers *CipherSuite, header Header) ([]byte, error) {
deviceEcdh := device.GetEcdhByCipherScheme(header.CipherScheme())
ess := deviceEcdh.SharedSecret(header.EphermeralBytes())
if ess == nil {
return nil, ErrDeviceECDHEphermalFailed
}
defer SetZero(ess[:])
// Local chain hash: InitialHash || serverPubKey || ephemeral
// (mirrors validatePeer's ChainHash0 → ChainHash1 evolution, but
// in a throwaway hash that never leaks back to ppd).
chainHash, err := NewHash(ciphers.HashType)
if err != nil {
return nil, fmt.Errorf("extractInitiatorStaticPubKey: chain hash: %w", err)
}
chainHash.Write([]byte(InitialHashString))
chainHash.Write(deviceEcdh.PublicKey())
chainHash.Write(header.EphermeralBytes())
// Local chain key: ChainKey0 = MixKey(InitialHash, InitialChainKey)
// then ChainKey0 → ChainKey1 via ess.
var noise NoiseFactory
noise.HashType = ciphers.HashType
var chainKey [SymmetricKeySize]byte
defer SetZero(chainKey[:])
// ChainKey0
initHash, err := NewHash(ciphers.HashType)
if err != nil {
return nil, fmt.Errorf("extractInitiatorStaticPubKey: init hash: %w", err)
}
initHash.Write([]byte(InitialHashString))
noise.MixKey(&chainKey, initHash.Sum(nil), []byte(InitialChainKeyString))View on GitHub (pinned to 6e04ca5ff0)