{"record":{"id":"87fe8728048e5855","repo":"golang/go","slug":"crypto-rsa-prime-factor-is-1","errorCode":null,"errorMessage":"crypto/rsa: prime factor is <= 1","messagePattern":"crypto/rsa: prime factor is <= 1","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/rsa.go","lineNumber":648,"sourceCode":"\tvar precomputed PrecomputedValues\n\n\tk, err := rsa.NewPrivateKeyWithoutCRT(priv.N.Bytes(), priv.E, priv.D.Bytes())\n\tif err != nil {\n\t\treturn precomputed, err\n\t}\n\tprecomputed.fips = k\n\n\tif len(priv.Primes) < 2 {\n\t\treturn precomputed, nil\n\t}\n\n\t// Ensure the Mod and ModInverse calls below don't panic.\n\tfor _, prime := range priv.Primes {\n\t\tif prime == nil {\n\t\t\treturn precomputed, errors.New(\"crypto/rsa: prime factor is nil\")\n\t\t}\n\t\tif prime.Cmp(bigOne) <= 0 {\n\t\t\treturn precomputed, errors.New(\"crypto/rsa: prime factor is <= 1\")\n\t\t}\n\t}\n\n\tprecomputed.Dp = new(big.Int).Sub(priv.Primes[0], bigOne)\n\tprecomputed.Dp.Mod(priv.D, precomputed.Dp)\n\n\tprecomputed.Dq = new(big.Int).Sub(priv.Primes[1], bigOne)\n\tprecomputed.Dq.Mod(priv.D, precomputed.Dq)\n\n\tprecomputed.Qinv = new(big.Int).ModInverse(priv.Primes[1], priv.Primes[0])\n\tif precomputed.Qinv == nil {\n\t\treturn precomputed, errors.New(\"crypto/rsa: prime factors are not relatively prime\")\n\t}\n\n\tr := new(big.Int).Mul(priv.Primes[0], priv.Primes[1])\n\tprecomputed.CRTValues = make([]CRTValue, len(priv.Primes)-2)\n\tfor i := 2; i < len(priv.Primes); i++ {\n\t\tprime := priv.Primes[i]","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/rsa.go#L630-L666","documentation":"Thrown in the legacy precompute loop when a prime compares <= 1 (i.e., 0, 1, or negative). A valid RSA prime must be an integer >= 2; values <= 1 would make Sub(prime, bigOne) zero or negative, breaking Mod and ModInverse. This guard rejects degenerate/corrupted primes.","triggerScenarios":"Sign/Decrypt/Validate on a key whose priv.Primes contains a value that is 0, 1, or negative. Usually a corrupted key, a test stub, or a deserialization that defaulted unset fields to big.NewInt(0).","commonSituations":"Test fixtures with Primes set to big.NewInt(1); JSON unmarshaling that left a prime as zero; tampered or adversarially crafted key material; accidental reuse of bigOne as a prime.","solutions":["Discard the key and generate a valid one with rsa.GenerateKey.","Run priv.Validate() on loaded keys; it performs deeper consistency checks than the prime guards.","If importing untrusted key material, validate primes are > 1 and reasonably sized before use.","Check the source of the key encoding for truncation or default-value substitution."],"exampleFix":"// before\npriv.Primes = []*big.Int{big.NewInt(1), big.NewInt(1)}\nerr := priv.Validate() // -> prime factor is <= 1\n\n// after\npriv, err := rsa.GenerateKey(rand.Reader, 2048)\nif err != nil { return err }","handlingStrategy":"validation","validationCode":"func checkPrimesPositive(priv *rsa.PrivateKey) error {\n    one := big.NewInt(1)\n    for i, p := range priv.Primes {\n        if p == nil || p.Cmp(one) <= 0 {\n            return fmt.Errorf(\"rsa: prime[%d] invalid (<=1)\", i)\n        }\n    }\n    return priv.Validate()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Discard keys with degenerate primes; regenerate with rsa.GenerateKey.","Never use big.NewInt(0) or big.NewInt(1) as test primes.","Validate untrusted key material before importing it.","Add a unit test that rejects a key with a prime of 1."],"tags":["crypto","rsa","key-validation","go"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}