{"record":{"id":"f04ad311266dad36","repo":"golang/go","slug":"ecdsa-invalid-private-key-length","errorCode":null,"errorMessage":"ecdsa: invalid private key length","messagePattern":"ecdsa: invalid private key length","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/ecdsa/ecdsa.go","lineNumber":170,"sourceCode":"\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,\n\t0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b,\n\t0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09, 0xa5, 0xd0,\n\t0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,\n\t0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09}\n\n// NewPrivateKey creates a new ECDSA private key from the given D and Q byte\n// slices. D must be the fixed-length big-endian encoding of the private scalar,\n// and Q must be the compressed or uncompressed encoding of the public point.\nfunc NewPrivateKey[P Point[P]](c *Curve[P], D, Q []byte) (*PrivateKey, error) {\n\tfips140.RecordApproved()\n\tpub, err := NewPublicKey(c, Q)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(D) != c.N.Size() {\n\t\treturn nil, errors.New(\"ecdsa: invalid private key length\")\n\t}\n\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.","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/ecdsa/ecdsa.go#L152-L188","documentation":"Thrown by fips140/ecdsa.NewPrivateKey when len(D) != c.N.Size(). D must be the fixed-length big-endian encoding of the private scalar with exactly the byte-width of the curve order (e.g. 32 for P-256, 48 for P-384, 66 for P-521). After this length check the scalar is parsed with SetBytes and additionally rejected if zero.","triggerScenarios":"Constructing an ECDSA private key whose D slice is shorter or longer than the curve order byte size, including a value with a stripped or extra leading byte.","commonSituations":"Importing a scalar encoded with a variable-length big.Int that dropped leading zeros or added a sign byte; cross-curve key reuse; truncated key material.","solutions":["Left-pad (or trim) D to exactly c.N.Size() bytes in big-endian before calling NewPrivateKey.","If D came from math/big, use the fixed-size FillBytes(buf) with a buffer of length c.N.Size() rather than Bytes().","Verify the curve constant matches the key's intended curve."],"exampleFix":"// before\npriv, err := ecdsa.NewPrivateKey(curve, bigInt.Bytes()) // variable length\n\n// after: fixed-width big-endian\nbuf := make([]byte, curve.N.Size())\nbigInt.FillBytes(buf)\npriv, err := ecdsa.NewPrivateKey(curve, buf)","handlingStrategy":"validation","validationCode":"// Require exactly c.N.Size() bytes for the scalar.\nif len(D) != curveN.Size() {\n    return fmt.Errorf(\"private scalar must be %d bytes\", curveN.Size())\n}\nreturn ecdsa.NewPrivateKey(curve, D, Q)","typeGuard":"func validScalarLen(D []byte, order *bigmod.Modulus) bool {\n    return len(D) == order.Size()\n}","tryCatchPattern":null,"preventionTips":["Encode scalars with big.Int.FillBytes into a fixed-size buffer.","Validate byte length against the curve order size at import.","Do not strip leading zero bytes when serializing fixed-width fields."],"tags":["go","crypto","fips","ecdsa","key-validation","encoding"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}