{"record":{"id":"6dc611445f675d2f","repo":"golang/go","slug":"negative-coordinate","errorCode":null,"errorMessage":"negative coordinate","messagePattern":"negative coordinate","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/ecdsa/ecdsa.go","lineNumber":625,"sourceCode":"\tif size > maxScalarSize {\n\t\treturn nil, errors.New(\"ecdsa: internal error: curve size too large\")\n\t}\n\tD := priv.D.FillBytes(make([]byte, size, maxScalarSize))\n\n\treturn privateKeyCache.Get(priv, func() (*ecdsa.PrivateKey, error) {\n\t\treturn ecdsa.NewPrivateKey(c, D, Q)\n\t}, func(k *ecdsa.PrivateKey) bool {\n\t\treturn subtle.ConstantTimeCompare(k.PublicKey().Bytes(), Q) == 1 &&\n\t\t\tsubtle.ConstantTimeCompare(k.Bytes(), D) == 1\n\t})\n}\n\n// pointFromAffine is used to convert the PublicKey to a nistec SetBytes input.\nfunc pointFromAffine(curve elliptic.Curve, x, y *big.Int) ([]byte, error) {\n\tbitSize := curve.Params().BitSize\n\t// Reject values that would not get correctly encoded.\n\tif x.Sign() < 0 || y.Sign() < 0 {\n\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\")","sourceCodeStart":607,"sourceCodeEnd":643,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/ecdsa/ecdsa.go#L607-L643","documentation":"Thrown by pointFromAffine (ecdsa.go:625) when either the X or Y coordinate of an ECDSA PublicKey has a negative sign. ECDSA point coordinates are field elements represented as non-negative big.Int values; a negative value indicates corruption or misuse of math/big (e.g. a subtraction that went negative, or an externally-constructed key with bogus coordinates).","triggerScenarios":"Reached via privateKeyToFIPS (line 592) and parsePublicKey (line 582) — any Sign/Verify path that converts a PublicKey to the FIPS nistec representation. Triggered when pub.X.Sign() < 0 || pub.Y.Sign() < 0, e.g. coordinates produced by ModInverse/Sub without a final Mod into the field, or hand-built keys with negative components.","commonSituations":"Custom curve arithmetic that uses big.Int subtraction without taking a positive modulus; importing coordinates from JSON/ASN.1 that allowed a leading sign bit; porting code from a library that permits signed coordinates.","solutions":["Always reduce coordinates with x.Mod(x, P) (where P is the field prime) before building the PublicKey so the sign is non-negative.","Load public keys only through x509.ParsePKIXPublicKey / cryptobyte ASN.1 parsing rather than constructing PublicKey{X,Y} directly.","Validate pub.X.Sign() >= 0 && pub.Y.Sign() >= 0 before invoking ecdsa.Verify*."],"exampleFix":"// before\nx := new(big.Int).Sub(a, b)        // may be negative\npub := ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}\nok := ecdsa.Verify(&pub, hash, r, s) // -> error 241 via pointFromAffine\n\n// after\nP := elliptic.P256().Params().P\nx := new(big.Int).Sub(a, b)\nx.Mod(x, P) // now in [0, P)\npub := ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}","handlingStrategy":"validation","validationCode":"if pub.X.Sign() < 0 || pub.Y.Sign() < 0 {\n    return errors.New(\"public key coordinates must be non-negative\")\n}","typeGuard":"func nonNegativeCoords(pub *ecdsa.PublicKey) bool {\n    return pub != nil && pub.X != nil && pub.Y != nil && pub.X.Sign() >= 0 && pub.Y.Sign() >= 0\n}","tryCatchPattern":null,"preventionTips":["Reduce all big.Int coordinates modulo the field prime before building a PublicKey.","Prefer standard parsing (x509/cryptobyte) over manual coordinate construction.","Validate coordinates at the trust boundary for keys received over the wire."],"tags":["go","crypto","ecdsa","validation","fips"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}