{"record":{"id":"f9df08eb22911c99","repo":"golang/go","slug":"invalid-p-point-encoding","errorCode":null,"errorMessage":"invalid {{.P}} point encoding","messagePattern":"invalid (.+?)\\} point encoding","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/nistec/generate.go","lineNumber":239,"sourceCode":"\t\ty := {{.p}}Polynomial(new({{.Element}}), x)\n\t\tif !{{.p}}Sqrt(y, y) {\n\t\t\treturn nil, errors.New(\"invalid {{.P}} 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({{.Element}})\n\t\totherRoot.Sub(otherRoot, y)\n\t\tcond := y.Bytes()[{{.p}}ElementLength-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 {{.P}} point encoding\")\n\t}\n}\n\n\nvar _{{.p}}B *{{.Element}}\nvar _{{.p}}BOnce sync.Once\n\nfunc {{.p}}B() *{{.Element}} {\n\t_{{.p}}BOnce.Do(func() {\n\t\t_{{.p}}B, _ = new({{.Element}}).SetBytes({{.B}})\n\t})\n\treturn _{{.p}}B\n}\n\n// {{.p}}Polynomial sets y2 to x³ - 3x + b, and returns y2.\nfunc {{.p}}Polynomial(y2, x *{{.Element}}) *{{.Element}} {\n\ty2.Square(x)\n\ty2.Mul(y2, x)","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/nistec/generate.go#L221-L257","documentation":"Generated from generate.go:239. Thrown when SetBytes on a NIST point falls through all recognized cases (uncompressed 0x04 of length 1+2*ElementLength, compressed 0x02/0x03, or infinity 0x00). Any other type byte or wrong length lands here.","triggerScenarios":"Input with an unrecognized leading byte (e.g. 0x06/0x07 hybrid, 0x01), a length that matches no recognized encoding, an un-decoded hex string, or a multi-buffer concatenation.","commonSituations":"Hybrid SEC1 encodings (deprecated, unsupported), wrong-length buffer after a slice mishap, raw coordinate pairs not wrapped in 0x04, or assuming the parser accepts COSE/JWK coordinate arrays.","solutions":["Wrap raw (x,y) coordinates in a 0x04-prefixed uncompressed SEC1 buffer of length 1+2*ElementLength.","Decode hex/base64 into raw bytes before calling SetBytes.","Strip any length prefix or framing the parser does not expect.","If the source emits hybrid (0x06/0x07) encoding, convert to 0x04 uncompressed first."],"exampleFix":"// before\np, err := nistec.NewP256Point().SetBytes(raw) // raw is x||y with no 0x04\n// after\nbuf := make([]byte, 1+2*p256ElementLength)\nbuf[0] = 4\ncopy(buf[1:], raw)\np, err := nistec.NewP256Point().SetBytes(buf)","handlingStrategy":"validation","validationCode":"// Wrap raw (x,y) in uncompressed SEC1 form before SetBytes.\nbuf := make([]byte, 1+2*elementLength)\nbuf[0] = 4\ncopy(buf[1:1+elementLength], x)\ncopy(buf[1+elementLength:], y)","typeGuard":"func isSEC1Point(b []byte, elLen int) bool {\n    switch {\n    case len(b) == 1 && b[0] == 0:\n        return true\n    case len(b) == 1+2*elLen && b[0] == 4:\n        return true\n    case len(b) == 1+elLen && (b[0] == 2 || b[0] == 3):\n        return true\n    }\n    return false\n}","tryCatchPattern":"p, err := curve.NewPoint().SetBytes(b)\nif err != nil {\n    return fmt.Errorf(\"unrecognized point encoding (prefix=0x%x, len=%d): %w\", b[0], len(b), err)\n}","preventionTips":["Always prefix raw coordinates with 0x04 and size the buffer to 1+2*ElementLen.","Convert hybrid (0x06/0x07) encodings to 0x04 before parsing.","Decode hex/base64 to raw bytes; never feed text to SetBytes."],"tags":["elliptic-curve","fips140","crypto","nistec","point-parsing","sec1","code-generation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}