golang/go · error
negative coordinate
Error message
negative coordinate
What it means
Thrown by nistCurve.pointFromAffine (nistec.go:143) when either X or Y of a point passed to the nistec backend is negative. This is the elliptic-layer sibling of ecdsa error 241: it guards the same fixed-width encoding, but at the elliptic.Curve abstraction level used by crypto/ecdsa, crypto/tls, and crypto/x509.
Source
Thrown at src/crypto/elliptic/nistec.go:143
func (curve *nistCurve[Point]) IsOnCurve(x, y *big.Int) bool {
// IsOnCurve is documented to reject (0, 0), the conventional point at
// infinity, which however is accepted by pointFromAffine.
if x.Sign() == 0 && y.Sign() == 0 {
return false
}
_, err := curve.pointFromAffine(x, y)
return err == nil
}
func (curve *nistCurve[Point]) pointFromAffine(x, y *big.Int) (p Point, err error) {
// (0, 0) is by convention the point at infinity, which can't be represented
// in affine coordinates. See Issue 37294.
if x.Sign() == 0 && y.Sign() == 0 {
return curve.newPoint(), nil
}
// Reject values that would not get correctly encoded.
if x.Sign() < 0 || y.Sign() < 0 {
return p, errors.New("negative coordinate")
}
if x.BitLen() > curve.params.BitSize || y.BitLen() > curve.params.BitSize {
return p, errors.New("overflowing coordinate")
}
// Encode the coordinates and let SetBytes reject invalid points.
byteLen := (curve.params.BitSize + 7) / 8
buf := make([]byte, 1+2*byteLen)
buf[0] = 4 // uncompressed point
x.FillBytes(buf[1 : 1+byteLen])
y.FillBytes(buf[1+byteLen : 1+2*byteLen])
return curve.newPoint().SetBytes(buf)
}
func (curve *nistCurve[Point]) pointToAffine(p Point) (x, y *big.Int) {
out := p.Bytes()
if len(out) == 1 && out[0] == 0 {
// This is the encoding of the point at infinity, which the affine
// coordinates API represents as (0, 0) by convention.View on GitHub (pinned to b6b368adc5)
Solutions
- Reduce coordinates modulo the field prime (x.Mod(x, P)) before any elliptic curve call.
- Parse points with elliptic.Unmarshal / standard ASN.1 rather than constructing them from raw big.Int.
- Validate x.Sign() >= 0 && y.Sign() >= 0 at the trust boundary.
Example fix
// before x := new(big.Int).Sub(a, b) // may be negative px, py := curve.ScalarMult(x, y, k) // -> error 253 // after P := curve.Params().P x.Mod(x, P) px, py := curve.ScalarMult(x, y, k)
Defensive patterns
Strategy: validation
Validate before calling
if x.Sign() < 0 || y.Sign() < 0 {
return errors.New("elliptic coordinates must be non-negative")
} Type guard
func nonNegativeEC(x, y *big.Int) bool {
return x != nil && y != nil && x.Sign() >= 0 && y.Sign() >= 0
} Prevention
- Reduce coordinates modulo the field prime before elliptic curve operations.
- Prefer elliptic.Unmarshal over constructing points from raw big.Int.
- Validate coordinates received from external sources.
When it happens
Trigger: Reached via elliptic curve operations (Unmarshal, Add, ScalarMult on a nistCurve) and indirectly through ecdsa. Triggered when x.Sign() < 0 || y.Sign() < 0 after excluding the (0,0) infinity convention. Happens with hand-built points or arithmetic that left a coordinate negative.
Common situations: Custom elliptic-curve code using big.Int subtraction without a final Mod into the field; importing points from formats that permit a sign; interop with a library producing signed field elements.
Related errors
- overflowing coordinate
- crypto/dsa: invalid public key
- crypto/dsa: invalid ParameterSizes
- crypto/dsa: parameters not set up before generating key
- crypto/ecdh: private key and public key curves do not match
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/b7126cd586cbdf17.
Report an issue: GitHub.