golang/go · error
P256 point is the point at infinity
Error message
P256 point is the point at infinity
What it means
The same error as 400 but from the assembly-optimized P256Point implementation (p256_asm.go). BytesX() returns the SEC 1 x-coordinate encoding and rejects the identity point (detected via isInfinity() == 1). The asm path uses p256Inverse/p256Sqr/p256Mul/p256FromMont internally instead of fiat inversion, but the precondition is identical: the point must not be at infinity.
Source
Thrown at src/crypto/internal/fips140/nistec/p256_asm.go:523
p256Mul(x, &p.x, x)
p256Mul(y, &p.y, y)
p256FromMont(x, x)
p256FromMont(y, y)
}
// 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 *P256Point) BytesX() ([]byte, error) {
// This function is outlined to make the allocations inline in the caller
// rather than happen on the heap.
var out [p256ElementLength]byte
return p.bytesX(&out)
}
func (p *P256Point) bytesX(out *[p256ElementLength]byte) ([]byte, error) {
if p.isInfinity() == 1 {
return nil, errors.New("P256 point is the point at infinity")
}
x := new(p256Element)
p256Inverse(x, &p.z)
p256Sqr(x, x, 1)
p256Mul(x, &p.x, x)
p256FromMont(x, x)
p256LittleToBig((*[32]byte)(out[:]), x)
return out[:], 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 *P256Point) BytesCompressed() []byte {
// This function is outlined to make the allocations inline in the caller
// rather than happen on the heap.View on GitHub (pinned to b6b368adc5)
Solutions
- Check p.Bytes() for the 1-byte 0x00 infinity encoding before calling BytesX
- Validate ScalarMult results before coordinate extraction
- Reject identity points at the protocol/peer-validation layer
Example fix
// before
x, err := point.BytesX()
// after
if enc := point.Bytes(); len(enc) == 1 && enc[0] == 0 {
return errors.New("identity point has no x-coordinate")
}
x, err := point.BytesX() Defensive patterns
Strategy: validation
Validate before calling
func mustNotBeInfinity(p *nistec.P256Point) error {
enc := p.Bytes()
if len(enc) == 1 && enc[0] == 0 {
return errors.New("point is identity")
}
return nil
}
if err := mustNotBeInfinity(point); err != nil { return err }
x, err := point.BytesX() Try / catch
x, err := point.BytesX()
if err != nil {
return fmt.Errorf("cannot extract x-coordinate: %w", err)
} Prevention
- Check for the identity point before extracting any affine coordinate
- In ECDH, validate the shared secret point is not infinity before using it
- Ensure scalars are non-zero before scalar multiplication
When it happens
Trigger: Calling p.BytesX() on an asm-path P256Point that is the identity element (z is zero). Occurs after ScalarMult with a zero-reducing scalar, or on an uninitialized point.
Common situations: ECDH with an identity public key; ECDSA where the per-message nonce produces an infinity result; this is the same root cause as error 400 — only the internal implementation differs.
Related errors
- P256 point is the point at infinity
- {{.P}} point is the point at infinity
- invalid P256 compressed point encoding
- invalid P256 point encoding
- P256 point not on curve
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/64365d07296bb697.
Report an issue: GitHub.