OpenNHP/opennhp · error
failed to create ChaCha20-Poly1305
Error message
failed to create ChaCha20-Poly1305: %w
What it means
AeadFromKey(GCM_CHACHA20POLY1305, key) wraps chacha20poly1305.New(key[:]) errors with this message. golang.org/x/crypto/chacha20poly1305.New fails only when the key is not exactly 32 bytes (chacha20poly1305.KeySize); OpenNHP passes the full 32-byte SymmetricKeySize array, so failure implies nil/mis-sized key material or dependency issues. The ChaCha20-Poly1305 suite is an alternative AEAD available in the GcmTypeEnum.
Solutions
- Ensure the 32-byte key array is fully derived (ECDH shared secret + KDF) before calling AeadFromKey
- Log the wrapped error — it will state the expected 32-byte key size
- Verify SymmetricKeySize equals 32 and chacha20poly1305.KeySize matches in your build
- Run go mod verify to ensure unmodified golang.org/x/crypto
- Test with go test ./nhp/core/... to reproduce against known-good keys
Example fix
// before
key := make([]byte, 16) // wrong length, cast into fixed array
aead, _ := core.AeadFromKey(core.GCM_CHACHA20POLY1305, (*[core.SymmetricKeySize]byte)(unsafe.Pointer(&key[0])))
// after
shared := ecdh.SharedSecret(peerPub)
if len(shared) != core.SymmetricKeySize {
return fmt.Errorf("derived key length %d, want %d", len(shared), core.SymmetricKeySize)
}
var key [core.SymmetricKeySize]byte
copy(key[:], shared)
aead, err := core.AeadFromKey(core.GCM_CHACHA20POLY1305, &key)
if err != nil {
return err
} Defensive patterns
Strategy: validation
Validate before calling
if key == nil {
return errors.New("ChaCha20-Poly1305 key not initialized")
}
if core.SymmetricKeySize != chacha20poly1305.KeySize {
return fmt.Errorf("SymmetricKeySize %d != required %d", core.SymmetricKeySize, chacha20poly1305.KeySize)
} Try / catch
aead, err := core.AeadFromKey(core.GCM_CHACHA20POLY1305, &key)
if err != nil {
return fmt.Errorf("ChaCha20-Poly1305 setup failed: %w", err)
} Prevention
- Derive the full 32-byte key before selecting the ChaCha20-Poly1305 GCM type
- Never cast arbitrary-length slices into the fixed-size key array
- Verify golang.org/x/crypto integrity with go mod verify
When it happens
Trigger: Calling AeadFromKey with GCM_CHACHA20POLY1305 and a nil *[SymmetricKeySize]byte, an array not fully populated by the KDF, or a x/crypto build where chacha20poly1305 constants differ.
Common situations: Custom code selecting the ChaCha20-Poly1305 GCM type before the ECDH key derivation completes; unsafe casting of shorter slices into the fixed-size array; dependency pinning problems.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Failed to decrypt ztdo file
- failed to create AES cipher
- unsupported GCM type
- failed to create AES cipher for CBC
- failed to create AES cipher for CBC decryption
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/dbf9f461d84d96ef.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/crypto.go:178
return nil, fmt.Errorf("failed to create AES-GCM: %w", err)
}
return aead, nil
case GCM_SM4:
sm4Block, err := sm4.NewCipher(key[:16])
if err != nil {
return nil, fmt.Errorf("failed to create SM4 cipher: %w", err)
}
aead, err := cipher.NewGCM(sm4Block)
if err != nil {
return nil, fmt.Errorf("failed to create SM4-GCM: %w", err)
}
return aead, nil
case GCM_CHACHA20POLY1305:
aead, err := chacha20poly1305.New(key[:])
if err != nil {
return nil, fmt.Errorf("failed to create ChaCha20-Poly1305: %w", err)
}
return aead, nil
default:
return nil, fmt.Errorf("unsupported GCM type: %d", t)
}
}
func CBCEncryption(t GcmTypeEnum, key *[SymmetricKeySize]byte, plaintext []byte, inPlace bool) ([]byte, error) {
var block cipher.Block
var iv []byte
var err error
switch t {
case GCM_AES256:
block, err = aes.NewCipher(key[:])
if err != nil {
return nil, fmt.Errorf("failed to create AES cipher for CBC: %w", err)
}View on GitHub (pinned to 6e04ca5ff0)