golang/go · error
NewPublicKeyECDH: wrong key length
Error message
NewPublicKeyECDH: wrong key length
What it means
Raised by boring.NewPublicKeyECDH when the supplied bytes are not the expected length for an uncompressed ECDH public point on the given curve: 1 + 2*curveSize bytes (a 0x04 prefix plus X and Y). For P-256 that is 65 bytes, P-384 97, P-521 133.
Source
Thrown at src/crypto/internal/boring/ecdh.go:38
bytes []byte
}
func (k *PublicKeyECDH) finalize() {
C._goboringcrypto_EC_POINT_free(k.key)
}
type PrivateKeyECDH struct {
curve string
key *C.GO_EC_KEY
}
func (k *PrivateKeyECDH) finalize() {
C._goboringcrypto_EC_KEY_free(k.key)
}
func NewPublicKeyECDH(curve string, bytes []byte) (*PublicKeyECDH, error) {
if len(bytes) != 1+2*curveSize(curve) {
return nil, errors.New("NewPublicKeyECDH: wrong key length")
}
nid, err := curveNID(curve)
if err != nil {
return nil, err
}
group := C._goboringcrypto_EC_GROUP_new_by_curve_name(nid)
if group == nil {
return nil, fail("EC_GROUP_new_by_curve_name")
}
defer C._goboringcrypto_EC_GROUP_free(group)
key := C._goboringcrypto_EC_POINT_new(group)
if key == nil {
return nil, fail("EC_POINT_new")
}
ok := C._goboringcrypto_EC_POINT_oct2point(group, key, (*C.uint8_t)(unsafe.Pointer(&bytes[0])), C.size_t(len(bytes)), nil) != 0
if !ok {View on GitHub (pinned to b6b368adc5)
Solutions
- Provide the full uncompressed point (0x04 || X || Y) of the correct length for the curve.
- Generate the encoding via ecdh.PublicKey.Bytes() on the standard library side rather than hand-encoding.
- Match the curve string exactly to the key's actual curve.
Example fix
// before
pub, err := boring.NewPublicKeyECDH("P-256", compressed33Bytes) // 33 != 65
// after
pub, err := boring.NewPublicKeyECDH("P-256", uncompressed65Bytes) // 0x04||X||Y Defensive patterns
Strategy: validation
Validate before calling
func expectedEcdhPubLen(curve string) int {
switch curve {
case "P-256": return 65
case "P-384": return 97
case "P-521": return 133
}
return -1
}
func validateEcdhPub(curve string, b []byte) error {
if want := expectedEcdhPubLen(curve); want < 0 || len(b) != want {
return fmt.Errorf("expected %d bytes for %s public key, got %d", want, curve, len(b))
}
return nil
} Prevention
- Encode public points via ecdh.PublicKey.Bytes() (uncompressed 0x04||X||Y).
- Match the curve string to the key's actual curve.
- Reject compressed encodings before calling the boring API.
When it happens
Trigger: Calling NewPublicKeyECDH(curve, bytes) with len(bytes) != 1 + 2*curveSize(curve). Caused by passing a compressed point, a private key scalar, raw X-only bytes, or bytes encoded for a different curve.
Common situations: Feeding a compressed point (33/49 bytes) where uncompressed is required; passing the wrong curve's encoding; truncation; confusing private and public key material.
Related errors
- point not on curve
- NewPrivateKeyECDH: wrong key length
- boringcrypto: unknown elliptic curve
- crypto/ecdh: invalid private key
- crypto/aes: GCM tag and nonce sizes can't be non-standard at
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/6e76964be8f21a1e.
Report an issue: GitHub.