{"record":{"id":"eda22c9e337c205a","repo":"golang/go","slug":"crypto-rsa-prime-p-is-nil","errorCode":null,"errorMessage":"crypto/rsa: prime P is nil","messagePattern":"crypto/rsa: prime P is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/rsa.go","lineNumber":594,"sourceCode":"}\n\n// precompute calculates the PrecomputedValues for priv and returns them.\n//\n// It does NOT modify priv and is safe for concurrent use.\nfunc (priv *PrivateKey) precompute() (PrecomputedValues, error) {\n\tvar precomputed PrecomputedValues\n\n\tif priv.N == nil {\n\t\treturn precomputed, errors.New(\"crypto/rsa: missing public modulus\")\n\t}\n\tif priv.D == nil {\n\t\treturn precomputed, errors.New(\"crypto/rsa: missing private exponent\")\n\t}\n\tif len(priv.Primes) != 2 {\n\t\treturn priv.precomputeLegacy()\n\t}\n\tif priv.Primes[0] == nil {\n\t\treturn precomputed, errors.New(\"crypto/rsa: prime P is nil\")\n\t}\n\tif priv.Primes[1] == nil {\n\t\treturn precomputed, errors.New(\"crypto/rsa: prime Q is nil\")\n\t}\n\n\t// If the CRT values are already set, use them.\n\tif priv.Precomputed.Dp != nil && priv.Precomputed.Dq != nil && priv.Precomputed.Qinv != nil {\n\t\tk, err := rsa.NewPrivateKeyWithPrecomputation(priv.N.Bytes(), priv.E, priv.D.Bytes(),\n\t\t\tpriv.Primes[0].Bytes(), priv.Primes[1].Bytes(),\n\t\t\tpriv.Precomputed.Dp.Bytes(), priv.Precomputed.Dq.Bytes(), priv.Precomputed.Qinv.Bytes())\n\t\tif err != nil {\n\t\t\treturn precomputed, err\n\t\t}\n\t\tprecomputed = priv.Precomputed\n\t\tprecomputed.fips = k\n\t\tprecomputed.CRTValues = make([]CRTValue, 0)\n\t\treturn precomputed, nil\n\t}","sourceCodeStart":576,"sourceCodeEnd":612,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/rsa.go#L576-L612","documentation":"Thrown by precompute() when priv.Primes[0] (prime P) is nil, reached only when len(priv.Primes)==2. P is required to compute the CRT values (Dp, Qinv); a nil P makes CRT signing impossible. The guard prevents a nil-pointer dereference in subsequent big.Int operations.","triggerScenarios":"Sign/Decrypt/Validate/Precompute on a 2-prime PrivateKey whose Primes slice has length 2 but Primes[0]==nil. Happens with hand-built keys, partially zero-value structs, or deserialization that allocated the slice but left entries nil.","commonSituations":"Constructing rsa.PrivateKey{Primes: make([]*big.Int, 2)} without filling it; JSON/encoding round-trips that omitted zero/big.Int fields; test fixtures that set N and D but forgot Primes.","solutions":["Use rsa.GenerateKey (or rsa.GenerateMultiPrimeKey) so Primes is always populated correctly.","After parsing, call priv.Validate() to catch missing primes before any private operation.","When constructing manually, set priv.Primes[0] and priv.Primes[1] to valid *big.Int primes.","Re-derive a key from a complete PKCS#1/PKCS#8 encoding rather than assembling fields by hand."],"exampleFix":"// before\npriv := &rsa.PrivateKey{\n    PublicKey: rsa.PublicKey{N: n, E: e},\n    D: d,\n    Primes: []*big.Int{nil, q}, // P missing\n}\nerr := priv.Validate() // -> prime P is nil\n\n// after\npriv, err := rsa.GenerateKey(rand.Reader, 2048)\nif err != nil { return err }\n// or: priv.Primes = []*big.Int{p, q} with both non-nil","handlingStrategy":"validation","validationCode":"func checkPrimesFilled(priv *rsa.PrivateKey) error {\n    if len(priv.Primes) != 2 {\n        return fmt.Errorf(\"rsa: expected 2 primes, got %d\", len(priv.Primes))\n    }\n    if priv.Primes[0] == nil || priv.Primes[1] == nil {\n        return errors.New(\"rsa: prime P or Q is nil\")\n    }\n    return priv.Validate()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never construct *rsa.PrivateKey by hand with a pre-allocated Primes slice left nil.","Prefer rsa.GenerateKey; only assemble manually if you also set every prime.","Run priv.Validate() after deserialization to detect nil primes before Sign/Decrypt.","Encode keys via PKCS#1/PKCS#8 and re-parse rather than field-level marshaling."],"tags":["crypto","rsa","key-validation","go"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}