golang/go · error

invalid P256 point encoding

Error message

invalid P256 point encoding

What it means

The default case of P256Point.SetBytes: the input byte slice does not match any recognized P-256 point encoding. Valid formats are: 1-byte infinity (0x00), 65-byte uncompressed (prefix 0x04), or 33-byte compressed (prefix 0x02 or 0x03). Any other combination of length and prefix byte falls through to this error.

Source

Thrown at src/crypto/internal/fips140/nistec/p256_asm.go:133

		// y² = x³ - 3x + b
		p256Polynomial(&r.y, &r.x)
		if !p256Sqrt(&r.y, &r.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.
		yy := new(p256Element)
		p256FromMont(yy, &r.y)
		cond := int(yy[0]&1) ^ int(b[0]&1)
		p256NegCond(&r.y, cond)

		r.z = p256One
		return p.Set(&r), nil

	default:
		return nil, errors.New("invalid P256 point encoding")
	}
}

// p256Polynomial sets y2 to x³ - 3x + b, and returns y2.
func p256Polynomial(y2, x *p256Element) *p256Element {
	x3 := new(p256Element)
	p256Sqr(x3, x, 1)
	p256Mul(x3, x3, x)

	threeX := new(p256Element)
	p256Add(threeX, x, x)
	p256Add(threeX, threeX, x)
	p256NegCond(threeX, 1)

	p256B := &p256Element{0xd89cdf6229c4bddf, 0xacf005cd78843090,
		0xe5a220abf7212ed6, 0xdc30061d04874834}

	p256Add(x3, x3, threeX)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Ensure the input matches one of: [0x00] (infinity), 0x04 + 32-byte x + 32-byte y (uncompressed), or 0x02/0x03 + 32-byte x (compressed)
  2. If working with raw x,y coordinates, prepend the 0x04 prefix yourself
  3. Use crypto/x509.ParsePKIXPublicKey or ecdsa.Unmarshal for correct parsing of higher-level formats

Example fix

// before
point, err := nistec.NewP256Point().SetBytes(rawXY) // raw 64-byte x||y, no prefix

// after
enc := make([]byte, 1, 65)
enc[0] = 0x04
enc = append(enc, rawXY...) // now 65 bytes: 0x04 || x || y
point, err := nistec.NewP256Point().SetBytes(enc)
Defensive patterns

Strategy: validation

Validate before calling

func classifyP256Encoding(b []byte) error {
    switch {
    case len(b) == 1 && b[0] == 0:
        return nil // infinity
    case len(b) == 65 && b[0] == 0x04:
        return nil // uncompressed
    case len(b) == 33 && (b[0] == 0x02 || b[0] == 0x03):
        return nil // compressed
    default:
        return fmt.Errorf("unrecognized P-256 encoding: len=%d prefix=0x%02x", len(b), b[0])
    }
}

if err := classifyP256Encoding(b); err != nil { return err }
_, err := point.SetBytes(b)

Try / catch

_, err := point.SetBytes(b)
if err != nil {
    return fmt.Errorf("not a valid P-256 point encoding: %w", err)
}

Prevention

When it happens

Trigger: Calling SetBytes with an empty slice, a slice of the wrong length, a slice with an unrecognized prefix byte, or a slice whose length matches a valid format but whose prefix byte is wrong (e.g., 65 bytes starting with 0x02).

Common situations: Passing raw 64-byte x||y coordinates without the 0x04 prefix; passing a DER-encoded SubjectPublicKeyInfo instead of raw point bytes; truncated network data; using uncompressed coordinates with a compressed-point prefix by mistake.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/562d03377c556dd5. Report an issue: GitHub.