{"record":{"id":"f51747260bed4cf6","repo":"golang/go","slug":"ecdsa-public-key-point-is-the-infinity","errorCode":null,"errorMessage":"ecdsa: public key point is the infinity","messagePattern":"ecdsa: public key point is the infinity","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/ecdsa/ecdsa.go","lineNumber":643,"sourceCode":"\t\treturn nil, errors.New(\"negative coordinate\")\n\t}\n\tif x.BitLen() > bitSize || y.BitLen() > bitSize {\n\t\treturn nil, errors.New(\"overflowing coordinate\")\n\t}\n\t// Encode the coordinates and let [ecdsa.NewPublicKey] reject invalid points.\n\tbyteLen := (bitSize + 7) / 8\n\tbuf := make([]byte, 1+2*byteLen)\n\tbuf[0] = 4 // uncompressed point\n\tx.FillBytes(buf[1 : 1+byteLen])\n\ty.FillBytes(buf[1+byteLen : 1+2*byteLen])\n\treturn buf, nil\n}\n\n// pointToAffine is used to convert a nistec Bytes encoding to a PublicKey.\nfunc pointToAffine(curve elliptic.Curve, p []byte) (x, y *big.Int, err error) {\n\tif len(p) == 1 && p[0] == 0 {\n\t\t// This is the encoding of the point at infinity.\n\t\treturn nil, nil, errors.New(\"ecdsa: public key point is the infinity\")\n\t}\n\tbyteLen := (curve.Params().BitSize + 7) / 8\n\tx = new(big.Int).SetBytes(p[1 : 1+byteLen])\n\ty = new(big.Int).SetBytes(p[1+byteLen:])\n\treturn x, y, nil\n}\n","sourceCodeStart":625,"sourceCodeEnd":650,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/ecdsa/ecdsa.go#L625-L650","documentation":"Thrown by pointToAffine (ecdsa.go:643) when the nistec point encodes to a single 0x00 byte — the standard encoding of the point at infinity (identity element). An ECDSA public key must never be the identity; such a key is invalid and cannot be used for verification, since the identity has no discrete-log.","triggerScenarios":"Reached when converting a FIPS nistec point back to affine coordinates (line 566 in parsePublicKey / verification paths). Happens when the underlying point object is the zero/identity point — e.g. a malformed public key whose decoded coordinates happen to satisfy y^2 = x^3 + ax + b at the identity, or arithmetic that produced the identity (adding a point to its inverse).","commonSituations":"Parsing a public key that was set to all-zero bytes, importing a key from a peer that sent a degenerate point, or test vectors that accidentally encode the identity.","solutions":["Reject all-zero or single-0x00 point encodings before constructing the PublicKey.","Use ecdsa.NewPublicKey / standard ASN.1 parsing which validates points; never build PublicKey{X:0,Y:0} by hand.","Verify the peer's public key is on the curve and is not the identity as part of key validation at the trust boundary."],"exampleFix":"// before\npub := ecdsa.PublicKey{Curve: elliptic.P256(), X: big.NewInt(0), Y: big.NewInt(0)}\nok := ecdsa.Verify(&pub, hash, r, s) // -> error 243\n\n// after\nparsed, err := x509.ParsePKIXPublicKey(derBytes) // validates point\nif err != nil { return err }\npub := parsed.(*ecdsa.PublicKey)","handlingStrategy":"validation","validationCode":"// reject identity / all-zero point before constructing a PublicKey\nisZero := func(z *big.Int) bool { return z == nil || z.Sign() == 0 }\nif isZero(pub.X) && isZero(pub.Y) {\n    return errors.New(\"public key must not be the point at infinity\")\n}","typeGuard":"func isIdentityPoint(pub *ecdsa.PublicKey) bool {\n    return pub.X.Sign() == 0 && pub.Y.Sign() == 0\n}","tryCatchPattern":null,"preventionTips":["Validate received public keys are on the curve and not the identity (RFC 5480 / NIST SP800-186).","Use standard parsing that rejects the identity rather than constructing PublicKey by hand.","Reject all-zero point encodings at the trust boundary."],"tags":["go","crypto","ecdsa","validation","fips"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}