{"record":{"id":"80834e51ffd91d2d","repo":"golang/go","slug":"ecdsa-unsupported-curve-by-crypto-ecdh","errorCode":null,"errorMessage":"ecdsa: unsupported curve by crypto/ecdh","messagePattern":"ecdsa: unsupported curve by crypto/ecdh","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/ecdsa/ecdsa.go","lineNumber":66,"sourceCode":"\t// invalidate internal optimizations; moreover, [big.Int] methods are not\n\t// suitable for operating on cryptographic values. To encode and decode\n\t// PublicKey values, use [PublicKey.Bytes] and [ParseUncompressedPublicKey]\n\t// or [crypto/x509.MarshalPKIXPublicKey] and [crypto/x509.ParsePKIXPublicKey].\n\t// For ECDH, use [crypto/ecdh]. For lower-level elliptic curve operations,\n\t// use a third-party module like filippo.io/nistec.\n\tX, Y *big.Int\n}\n\n// Any methods implemented on PublicKey might need to also be implemented on\n// PrivateKey, as the latter embeds the former and will expose its methods.\n\n// ECDH returns k as a [ecdh.PublicKey]. It returns an error if the key is\n// invalid according to the definition of [ecdh.Curve.NewPublicKey], or if the\n// Curve is not supported by crypto/ecdh.\nfunc (pub *PublicKey) ECDH() (*ecdh.PublicKey, error) {\n\tc := curveToECDH(pub.Curve)\n\tif c == nil {\n\t\treturn nil, errors.New(\"ecdsa: unsupported curve by crypto/ecdh\")\n\t}\n\tk, err := pub.Bytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn c.NewPublicKey(k)\n}\n\n// Equal reports whether pub and x have the same value.\n//\n// Two keys are only considered to have the same value if they have the same Curve value.\n// Note that for example [elliptic.P256] and elliptic.P256().Params() are different\n// values, as the latter is a generic not constant time implementation.\nfunc (pub *PublicKey) Equal(x crypto.PublicKey) bool {\n\txx, ok := x.(*PublicKey)\n\tif !ok {\n\t\treturn false\n\t}","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/ecdsa/ecdsa.go#L48-L84","documentation":"Thrown by ecdsa.PublicKey.ECDH() when curveToECDH(pub.Curve) returns nil. The curveToECDH function only maps elliptic.P256, elliptic.P384, and elliptic.P521 to their ecdh equivalents — elliptic.P224 and any custom curve return nil, triggering this error. ECDSA keys on unsupported curves cannot be converted to ecdh.PublicKey for key agreement.","triggerScenarios":"Calling ECDH() on an ecdsa.PublicKey whose Curve is elliptic.P224() or a non-standard/custom elliptic.Curve. The method attempts to find a matching crypto/ecdh curve and fails because only P-256, P-384, and P-521 have ecdh.Curve counterparts.","commonSituations":"Loading a P-224 ECDSA certificate (used in some legacy systems or constrained environments) and trying to derive an ECDH shared secret from its public key; using a custom curve implementation; code that generically converts any ECDSA key to ECDH without checking the curve.","solutions":["Check pub.Curve against elliptic.P256(), elliptic.P384(), or elliptic.P521() before calling ECDH(); for P-224, use a separate ECDH key pair on a supported curve.","Generate a dedicated ecdh.PrivateKey with ecdh.P256().GenerateKey() (or P384/P521) for key agreement instead of reusing an ECDSA key.","If you need P-224 key agreement, use an alternative ECDH implementation since crypto/ecdh does not support it."],"exampleFix":"// before\necdhPub, err := ecdsaPub.ECDH()\n\n// after\nswitch ecdsaPub.Curve {\ncase elliptic.P256(), elliptic.P384(), elliptic.P521():\n    ecdhPub, err = ecdsaPub.ECDH()\ndefault:\n    return fmt.Errorf(\"curve %s not supported for ECDH\", ecdsaPub.Curve.Params().Name)\n}","handlingStrategy":"validation","validationCode":"func isECDSACurveECDHCompatible(c elliptic.Curve) bool {\n    switch c {\n    case elliptic.P256(), elliptic.P384(), elliptic.P521():\n        return true\n    }\n    return false\n}\n// call before: pub.ECDH()","typeGuard":"func supportsECDH(pub *ecdsa.PublicKey) bool {\n    switch pub.Curve {\n    case elliptic.P256(), elliptic.P384(), elliptic.P521():\n        return true\n    }\n    return false\n}","tryCatchPattern":"ecdhPub, err := pub.ECDH()\nif err != nil {\n    return fmt.Errorf(\"cannot use curve %s for ECDH: %w\", pub.Curve.Params().Name, err)\n}","preventionTips":["Remember P-224 ECDSA keys cannot be converted to ECDH — use P-256+ for dual-purpose keys.","Prefer generating dedicated ecdh.PrivateKey instances for key agreement rather than reusing ECDSA keys."],"tags":["crypto","ecdsa","ecdh","curve-mismatch","nist-curves"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}