golang/go · error
crypto/rsa: prime factor is <= 1
Error message
crypto/rsa: prime factor is <= 1
What it means
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.
Source
Thrown at src/crypto/rsa/rsa.go:648
var precomputed PrecomputedValues
k, err := rsa.NewPrivateKeyWithoutCRT(priv.N.Bytes(), priv.E, priv.D.Bytes())
if err != nil {
return precomputed, err
}
precomputed.fips = k
if len(priv.Primes) < 2 {
return precomputed, nil
}
// Ensure the Mod and ModInverse calls below don't panic.
for _, prime := range priv.Primes {
if prime == nil {
return precomputed, errors.New("crypto/rsa: prime factor is nil")
}
if prime.Cmp(bigOne) <= 0 {
return precomputed, errors.New("crypto/rsa: prime factor is <= 1")
}
}
precomputed.Dp = new(big.Int).Sub(priv.Primes[0], bigOne)
precomputed.Dp.Mod(priv.D, precomputed.Dp)
precomputed.Dq = new(big.Int).Sub(priv.Primes[1], bigOne)
precomputed.Dq.Mod(priv.D, precomputed.Dq)
precomputed.Qinv = new(big.Int).ModInverse(priv.Primes[1], priv.Primes[0])
if precomputed.Qinv == nil {
return precomputed, errors.New("crypto/rsa: prime factors are not relatively prime")
}
r := new(big.Int).Mul(priv.Primes[0], priv.Primes[1])
precomputed.CRTValues = make([]CRTValue, len(priv.Primes)-2)
for i := 2; i < len(priv.Primes); i++ {
prime := priv.Primes[i]View on GitHub (pinned to b6b368adc5)
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.
Example fix
// before
priv.Primes = []*big.Int{big.NewInt(1), big.NewInt(1)}
err := priv.Validate() // -> prime factor is <= 1
// after
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
func checkPrimesPositive(priv *rsa.PrivateKey) error {
one := big.NewInt(1)
for i, p := range priv.Primes {
if p == nil || p.Cmp(one) <= 0 {
return fmt.Errorf("rsa: prime[%d] invalid (<=1)", i)
}
}
return priv.Validate()
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- crypto/rsa: invalid prime
- crypto/rsa: p * q != n
- crypto/rsa: invalid CRT exponent
- crypto/rsa: invalid CRT coefficient
- crypto/rsa: d does not match dP
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/87fe8728048e5855.
Report an issue: GitHub.