golang/go · error
invalid P256 point encoding
Error message
invalid P256 point encoding
What it means
Concrete P-256 instance of the generated point-encoding error (generate.go:239 expanded into p256.go:112). Thrown when SetBytes on a P-256 point falls through all recognized cases: 0x04 uncompressed of length 65, 0x02/0x03 compressed of length 33, or 0x00 infinity. Any other leading byte or length is rejected.
Source
Thrown at src/crypto/internal/fips140/nistec/p256.go:112
y := p256Polynomial(new(fiat.P256Element), x)
if !p256Sqrt(y, y) {
return nil, errors.New("invalid P256 compressed point encoding")
}
// Select the positive or negative root, as indicated by the least
// significant bit, based on the encoding type byte.
otherRoot := new(fiat.P256Element)
otherRoot.Sub(otherRoot, y)
cond := y.Bytes()[p256ElementLength-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 P256 point encoding")
}
}
var _p256B *fiat.P256Element
var _p256BOnce sync.Once
func p256B() *fiat.P256Element {
_p256BOnce.Do(func() {
_p256B, _ = new(fiat.P256Element).SetBytes([]byte{0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x6, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b})
})
return _p256B
}
// p256Polynomial sets y2 to x³ - 3x + b, and returns y2.
func p256Polynomial(y2, x *fiat.P256Element) *fiat.P256Element {
y2.Square(x)
y2.Mul(y2, x)
View on GitHub (pinned to b6b368adc5)
Solutions
- Wrap raw (x,y) as 0x04 || x || y (65 bytes for P-256) before SetBytes.
- Decode hex/base64 to raw bytes first.
- Convert hybrid (0x06/0x07) to uncompressed 0x04 if the source emits it.
- Strip any length prefix or envelope the P-256 parser does not expect.
Example fix
// before p, err := nistec.NewP256Point().SetBytes(rawXY) // missing 0x04 // after buf := make([]byte, 65) buf[0] = 4 copy(buf[1:33], x); copy(buf[33:], y) p, err := nistec.NewP256Point().SetBytes(buf)
Defensive patterns
Strategy: validation
Validate before calling
// Wrap raw P-256 coordinates as 0x04 || x || y. buf := make([]byte, 65) buf[0] = 4 copy(buf[1:33], x) copy(buf[33:], y)
Type guard
func isSEC1P256(b []byte) bool {
switch {
case len(b) == 1 && b[0] == 0: return true
case len(b) == 65 && b[0] == 4: return true
case len(b) == 33 && (b[0] == 2 || b[0] == 3): return true
}
return false
} Try / catch
p, err := nistec.NewP256Point().SetBytes(b)
if err != nil {
return fmt.Errorf("unrecognized P-256 encoding (prefix=0x%x, len=%d): %w", b[0], len(b), err)
} Prevention
- Always prefix raw P-256 coordinates with 0x04 and use a 65-byte buffer.
- Convert hybrid (0x06/0x07) to uncompressed 0x04 if encountered.
- Decode hex/base64 to raw bytes before parsing.
When it happens
Trigger: Input with an unrecognized prefix (0x06/0x07 hybrid, 0x01), wrong-length buffer, raw x||y without the 0x04 prefix, or an un-decoded hex/base64 string.
Common situations: Hybrid SEC1 (unsupported), dropped length prefix, JWK/COSE coordinate arrays mistaken for SEC1, or a byte slice that included extra framing.
Related errors
- invalid P256 compressed point encoding
- invalid {{.P}} compressed point encoding
- invalid {{.P}} point encoding
- P256 point not on curve
- invalid {{ .Element }} encoding
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/63bf18863306cd79.
Report an issue: GitHub.