{"record":{"id":"484202b115cfca3f","repo":"golang/go","slug":"ecdsa-invalid-public-key-encoding","errorCode":null,"errorMessage":"ecdsa: invalid public key encoding","messagePattern":"ecdsa: invalid public key encoding","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/ecdsa/ecdsa.go","lineNumber":190,"sourceCode":"\td, err := bigmod.NewNat().SetBytes(D, c.N)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif d.IsZero() == 1 {\n\t\treturn nil, errors.New(\"ecdsa: private key is zero\")\n\t}\n\tpriv := &PrivateKey{pub: *pub, d: d.Bytes(c.N)}\n\treturn priv, nil\n}\n\n// NewPublicKey creates a new ECDSA public key from the given Q byte slice.\n// Q must be the compressed or uncompressed encoding of the public point.\nfunc NewPublicKey[P Point[P]](c *Curve[P], Q []byte) (*PublicKey, error) {\n\t// SetBytes checks that Q is a valid point on the curve, and that its\n\t// coordinates are reduced modulo p, fulfilling the requirements of SP\n\t// 800-89, Section 5.3.2.\n\tif len(Q) < 1 || Q[0] == 0 {\n\t\treturn nil, errors.New(\"ecdsa: invalid public key encoding\")\n\t}\n\t_, err := c.newPoint().SetBytes(Q)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &PublicKey{curve: c.curve, q: Q}, nil\n}\n\n// GenerateKey generates a new ECDSA private key pair for the specified curve.\nfunc GenerateKey[P Point[P]](c *Curve[P], rand io.Reader) (*PrivateKey, error) {\n\tfips140.RecordApproved()\n\n\tk, Q, err := randomPoint(c, func(b []byte) error {\n\t\treturn drbg.ReadWithReader(rand, b)\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/ecdsa/ecdsa.go#L172-L208","documentation":"Thrown by fips140/ecdsa.NewPublicKey when len(Q) < 1 or Q[0] == 0. An empty point or one beginning with 0x00 (the point-at-infinity / malformed) is rejected up front; SetBytes afterward validates on-curve membership and coordinate ranges per SP 800-89 §5.3.2.","triggerScenarios":"Constructing an ECDSA public key from an empty slice, a 0x00-prefixed buffer, or any encoding whose first byte is zero.","commonSituations":"Parsing a corrupted/truncated certificate or JWK, an uninitialized buffer, or a mis-serialized point that lost its format prefix.","solutions":["Validate len(Q) >= 1 and Q[0] != 0 before calling NewPublicKey.","Re-serialize the point in SEC1 compressed (0x02/0x03) or uncompressed (0x04) form.","Check the upstream parser that produced Q for truncation."],"exampleFix":"// before\npub, err := ecdsa.NewPublicKey(curve, q) // q empty or q[0]==0x00\n\n// after: guard the encoding\nif len(q) == 0 || q[0] == 0 {\n    return errors.New(\"invalid public key encoding\")\n}\npub, err := ecdsa.NewPublicKey(curve, q)","handlingStrategy":"validation","validationCode":"if len(Q) < 1 || Q[0] == 0 {\n    return errors.New(\"ecdsa public key encoding is empty or starts with 0x00\")\n}\nreturn ecdsa.NewPublicKey(curve, Q)","typeGuard":"func validPubEnc(Q []byte) bool {\n    return len(Q) >= 1 && Q[0] != 0\n}","tryCatchPattern":null,"preventionTips":["Re-serialize points in SEC1 form before importing.","Check Q[0] is 0x02/0x03/0x04 at parse time.","Validate certificate/JWK parsing did not truncate the point."],"tags":["go","crypto","fips","ecdsa","key-validation","encoding"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}