golang/go · error
crypto/ecdh: invalid private key
Error message
crypto/ecdh: invalid private key
What it means
When BoringCrypto is enabled, NewPrivateKey delegates parsing to boring.NewPrivateKeyECDH(c.name, key). If that call fails, the key bytes are not a valid private scalar for the named NIST curve, so this generic 'invalid private key' error is returned. The second return path (bk.PublicKey()) is tracked separately at line 92.
Solutions
- Ensure the key bytes are the raw, fixed-length scalar for the exact curve used.
- Generate keys via curve.GenerateKey(rand.Reader) so encoding is always valid.
- Verify key length matches the curve's expected private-key size before calling NewPrivateKey.
Defensive patterns
Strategy: validation
Validate before calling
// Validate length/range for the NIST curve before NewPrivateKey.
// P-256 expects 32 bytes, P-384 48, P-521 66.
func loadPriv(curve ecdh.Curve, key []byte) (*ecdh.PrivateKey, error) {
if len(key) == 0 {
return nil, errors.New("empty private key")
}
return curve.NewPrivateKey(key)
} Try / catch
priv, err := curve.NewPrivateKey(key)
if err != nil {
// 'invalid private key' under BoringCrypto: reject and request a fresh key.
return err
} Prevention
- Obtain private keys from curve.GenerateKey(rand.Reader), not from external byte sources.
- When loading persisted keys, verify byte length matches the curve's scalar size.
- Discard keys that fail to construct; never try to patch the bytes.
When it happens
Trigger: Calling curve.NewPrivateKey(key) with malformed, out-of-range, or wrong-length scalar bytes while boring.Enabled is true.
Common situations: Loading a key with the wrong curve's encoding; truncated key bytes; a scalar that is zero or >= the curve order; key produced by a non-compatible library.
Related errors
- crypto/ecdh: invalid public key
- crypto/ecdh: private key and public key curves do not match
- crypto/dsa: invalid public key
- point not on curve
- boringcrypto: unknown elliptic curve
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/a40d6db320d7d466.
Report an issue: GitHub.
Appendix: source
Thrown at src/crypto/ecdh/nist.go:88
bk, err := boring.NewPrivateKeyECDH(c.name, k.privateKey)
if err != nil {
return nil, err
}
pub, err := bk.PublicKey()
if err != nil {
return nil, err
}
k.boring = bk
k.publicKey.boring = pub
}
return k, nil
}
func (c *nistCurve) NewPrivateKey(key []byte) (*PrivateKey, error) {
if boring.Enabled {
bk, err := boring.NewPrivateKeyECDH(c.name, key)
if err != nil {
return nil, errors.New("crypto/ecdh: invalid private key")
}
pub, err := bk.PublicKey()
if err != nil {
return nil, errors.New("crypto/ecdh: invalid private key")
}
k := &PrivateKey{
curve: c,
privateKey: bytes.Clone(key),
publicKey: &PublicKey{curve: c, publicKey: pub.Bytes(), boring: pub},
boring: bk,
}
return k, nil
}
fk, err := c.newPrivateKey(key)
if err != nil {
return nil, err
}View on GitHub (pinned to b6b368adc5)