{"record":{"id":"63bf18863306cd79","repo":"golang/go","slug":"invalid-p256-point-encoding","errorCode":null,"errorMessage":"invalid P256 point encoding","messagePattern":"invalid P256 point encoding","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/nistec/p256.go","lineNumber":112,"sourceCode":"\t\ty := p256Polynomial(new(fiat.P256Element), x)\n\t\tif !p256Sqrt(y, y) {\n\t\t\treturn nil, errors.New(\"invalid P256 compressed point encoding\")\n\t\t}\n\n\t\t// Select the positive or negative root, as indicated by the least\n\t\t// significant bit, based on the encoding type byte.\n\t\totherRoot := new(fiat.P256Element)\n\t\totherRoot.Sub(otherRoot, y)\n\t\tcond := y.Bytes()[p256ElementLength-1]&1 ^ b[0]&1\n\t\ty.Select(otherRoot, y, int(cond))\n\n\t\tp.x.Set(x)\n\t\tp.y.Set(y)\n\t\tp.z.One()\n\t\treturn p, nil\n\n\tdefault:\n\t\treturn nil, errors.New(\"invalid P256 point encoding\")\n\t}\n}\n\nvar _p256B *fiat.P256Element\nvar _p256BOnce sync.Once\n\nfunc p256B() *fiat.P256Element {\n\t_p256BOnce.Do(func() {\n\t\t_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})\n\t})\n\treturn _p256B\n}\n\n// p256Polynomial sets y2 to x³ - 3x + b, and returns y2.\nfunc p256Polynomial(y2, x *fiat.P256Element) *fiat.P256Element {\n\ty2.Square(x)\n\ty2.Mul(y2, x)\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/nistec/p256.go#L94-L130","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hybrid SEC1 (unsupported), dropped length prefix, JWK/COSE coordinate arrays mistaken for SEC1, or a byte slice that included extra framing.","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."],"exampleFix":"// before\np, err := nistec.NewP256Point().SetBytes(rawXY) // missing 0x04\n// after\nbuf := make([]byte, 65)\nbuf[0] = 4\ncopy(buf[1:33], x); copy(buf[33:], y)\np, err := nistec.NewP256Point().SetBytes(buf)","handlingStrategy":"validation","validationCode":"// Wrap raw P-256 coordinates as 0x04 || x || y.\nbuf := make([]byte, 65)\nbuf[0] = 4\ncopy(buf[1:33], x)\ncopy(buf[33:], y)","typeGuard":"func isSEC1P256(b []byte) bool {\n    switch {\n    case len(b) == 1 && b[0] == 0: return true\n    case len(b) == 65 && b[0] == 4: return true\n    case len(b) == 33 && (b[0] == 2 || b[0] == 3): return true\n    }\n    return false\n}","tryCatchPattern":"p, err := nistec.NewP256Point().SetBytes(b)\nif err != nil {\n    return fmt.Errorf(\"unrecognized P-256 encoding (prefix=0x%x, len=%d): %w\", b[0], len(b), err)\n}","preventionTips":["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."],"tags":["elliptic-curve","fips140","crypto","nistec","p256","point-parsing","sec1"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}