golang/go · error
invalid {{.P}} compressed point encoding
Error message
invalid {{.P}} compressed point encoding What it means
Generated into each NIST curve from generate.go:223. Thrown when parsing a compressed SEC1 point (type byte 0x02/0x03, length 1+ElementLength) where the x-coordinate yields no valid y, i.e. x^3-3x+b is not a quadratic residue. The point is not on the curve.
Source
Thrown at src/crypto/internal/fips140/nistec/generate.go:223
if err := {{.p}}CheckOnCurve(x, y); err != nil {
return nil, err
}
p.x.Set(x)
p.y.Set(y)
p.z.One()
return p, nil
// Compressed form.
case len(b) == 1+{{.p}}ElementLength && (b[0] == 2 || b[0] == 3):
x, err := new({{.Element}}).SetBytes(b[1:])
if err != nil {
return nil, err
}
// y² = x³ - 3x + b
y := {{.p}}Polynomial(new({{.Element}}), x)
if !{{.p}}Sqrt(y, y) {
return nil, errors.New("invalid {{.P}} compressed point encoding")
}
// Select the positive or negative root, as indicated by the least
// significant bit, based on the encoding type byte.
otherRoot := new({{.Element}})
otherRoot.Sub(otherRoot, y)
cond := y.Bytes()[{{.p}}ElementLength-1]&1 ^ b[0]&1
y.Select(otherRoot, y, int(cond))
p.x.Set(x)
p.y.Set(y)
p.z.One()
return p, nil
default:
return nil, errors.New("invalid {{.P}} point encoding")
}
}View on GitHub (pinned to b6b368adc5)
Solutions
- Validate the source of the point; reject compressed points from untrusted peers with explicit error handling.
- Confirm the type byte (0x02/0x03) and length match the target curve (1+ElementLength).
- Use the curve-specific point parser rather than re-implementing decompression.
- Re-serialize the point via BytesCompressed from a known-good point and diff against the input.
Example fix
// before
p, err := nistec.NewP256Point().SetBytes(b) // b is a corrupted compressed point
// after
if !(len(b) == 1+p256ElementLength && (b[0] == 2 || b[0] == 3)) {
return errors.New("not a P-256 compressed point")
}
p, err := nistec.NewP256Point().SetBytes(b)
if err != nil { return fmt.Errorf("point off curve: %w", err) } Defensive patterns
Strategy: validation
Validate before calling
// Validate SEC1 compressed shape before decompression.
if len(b) != 1+elementLength || (b[0] != 2 && b[0] != 3) {
return errors.New("not a compressed point")
} Type guard
func isCompressedSEC1(b []byte, elLen int) bool {
return len(b) == 1+elLen && (b[0] == 2 || b[0] == 3)
} Try / catch
p, err := curve.NewPoint().SetBytes(b)
if err != nil {
return fmt.Errorf("point decompression failed (len=%d): %w", len(b), err)
} Prevention
- Reject compressed points from untrusted peers with explicit error handling.
- Match the curve before calling the curve-specific parser.
- Re-encode from a known-good point and diff if a point is suspect.
When it happens
Trigger: Compressed point with an x that is not on the curve, an x that was corrupted/truncated, or a compressed encoding from a different curve (e.g. P-384 point fed to a P-256 parser).
Common situations: Fuzzed/adversarial public keys, byte-swap or endian errors, cross-curve confusion, or a stale encoding from a draft curve parameter.
Related errors
- invalid {{.P}} point encoding
- invalid P256 compressed point encoding
- invalid P256 point encoding
- invalid {{ .Element }} encoding
- {{.P}} point not on curve
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/8d25e1f2217bd6ca.
Report an issue: GitHub.