golang/go · error
P521 point is the point at infinity
Error message
P521 point is the point at infinity
What it means
P521Point.BytesX() returns the SEC 1 x-coordinate encoding of a P-521 point and rejects the identity element (z == 0). The point at infinity has no affine representation, so extracting its x-coordinate is undefined. This is the P-521 counterpart of errors 400/409.
Source
Thrown at src/crypto/internal/fips140/nistec/p521.go:178
buf := append(out[:0], 4)
buf = append(buf, x.Bytes()...)
buf = append(buf, y.Bytes()...)
return buf
}
// BytesX returns the encoding of the x-coordinate of p, as specified in SEC 1,
// Version 2.0, Section 2.3.5, or an error if p is the point at infinity.
func (p *P521Point) BytesX() ([]byte, error) {
// This function is outlined to make the allocations inline in the caller
// rather than happen on the heap.
var out [p521ElementLength]byte
return p.bytesX(&out)
}
func (p *P521Point) bytesX(out *[p521ElementLength]byte) ([]byte, error) {
if p.z.IsZero() == 1 {
return nil, errors.New("P521 point is the point at infinity")
}
zinv := new(fiat.P521Element).Invert(p.z)
x := new(fiat.P521Element).Mul(p.x, zinv)
return append(out[:0], x.Bytes()...), nil
}
// BytesCompressed returns the compressed or infinity encoding of p, as
// specified in SEC 1, Version 2.0, Section 2.3.3. Note that the encoding of the
// point at infinity is shorter than all other encodings.
func (p *P521Point) BytesCompressed() []byte {
// This function is outlined to make the allocations inline in the caller
// rather than happen on the heap.
var out [1 + p521ElementLength]byte
return p.bytesCompressed(&out)
}
View on GitHub (pinned to b6b368adc5)
Solutions
- Check p.Bytes() for the 1-byte 0x00 infinity encoding before calling BytesX
- Validate scalar multiplication results before coordinate extraction
- Reject identity points from untrusted peers
Example fix
// before
x, err := p521Point.BytesX()
// after
if enc := p521Point.Bytes(); len(enc) == 1 && enc[0] == 0 {
return errors.New("P-521 identity point; no x-coordinate")
}
x, err := p521Point.BytesX() Defensive patterns
Strategy: validation
Validate before calling
func mustNotBeInfinityP521(p *nistec.P521Point) error {
enc := p.Bytes()
if len(enc) == 1 && enc[0] == 0 {
return errors.New("P-521 point is identity")
}
return nil
}
if err := mustNotBeInfinityP521(point); err != nil { return err }
x, err := point.BytesX() Try / catch
x, err := p521Point.BytesX()
if err != nil {
return fmt.Errorf("cannot extract P-521 x-coordinate: %w", err)
} Prevention
- Check for the identity point before extracting P-521 coordinates
- Validate the shared secret in P-521 ECDH is not infinity
- Ensure scalars are non-zero and properly bounded
When it happens
Trigger: Calling p.BytesX() on a P521Point whose z coordinate is zero — the result of ScalarMult with a zero scalar, an uninitialized point, or a point added to its inverse.
Common situations: P-521 ECDH with a malicious identity public key; ECDSA-P521 where the nonce yields infinity; uninitialized P521Point from NewP521Point().
Related errors
- {{.P}} point is the point at infinity
- P256 point is the point at infinity
- P256 point is the point at infinity
- P521 point not on curve
- invalid {{ .Element }} encoding
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/7f16684696f9e1fe.
Report an issue: GitHub.