golang/go · error
crypto/rsa: public exponent is even
Error message
crypto/rsa: public exponent is even
What it means
Returned by checkPublicKey when the RSA public exponent E is even. RSA correctness requires e to be invertible modulo lambda(pq); since p and q are prime (odd), p-1 and q-1 are even, so e must be odd to be coprime. An even exponent has no inverse mod lambda(pq) and breaks encryption/decryption. The check pub.E&1 == 0 is a hard failure (returns false, err), unlike the FIPS-approval flags.
Source
Thrown at src/crypto/internal/fips140/rsa/rsa.go:349
if pub.N.Nat().IsOdd() == 0 {
return false, errors.New("crypto/rsa: public modulus is even")
}
// FIPS 186-5, Section 5.1: "This standard specifies the use of a modulus
// whose bit length is an even integer and greater than or equal to 2048
// bits."
if pub.N.BitLen() < 2048 {
fipsApproved = false
}
if pub.N.BitLen()%2 == 1 {
fipsApproved = false
}
if pub.E < 2 {
return false, errors.New("crypto/rsa: public exponent too small or negative")
}
// e needs to be coprime with p-1 and q-1, since it must be invertible
// modulo λ(pq). Since p and q are prime, this means e needs to be odd.
if pub.E&1 == 0 {
return false, errors.New("crypto/rsa: public exponent is even")
}
// FIPS 186-5, Section 5.5(e): "The exponent e shall be an odd, positive
// integer such that 2¹⁶ < e < 2²⁵⁶."
if pub.E <= 1<<16 {
fipsApproved = false
}
// We require pub.E to fit into a 32-bit integer so that we
// do not have different behavior depending on whether
// int is 32 or 64 bits. See also
// https://www.imperialviolet.org/2012/03/16/rsae.html.
if pub.E > 1<<31-1 {
return false, errors.New("crypto/rsa: public exponent too large")
}
return fipsApproved, nil
}
// Encrypt performs the RSA public key operation.
func Encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) {View on GitHub (pinned to b6b368adc5)
Solutions
- Set E to the de-facto standard 65537 (0x10001) on the PublicKey; this is odd and FIPS-approved.
- If you loaded the key from PEM/DER, re-decode it and inspect pub.E in hex; a wrong endianness or truncated field is the usual cause of an even E.
- If you must use a small exponent for research, use 3 or 17 (both odd) — but note small exponents are not FIPS-approved and are flagged separately.
- Add a unit assertion that pub.E&1 == 1 before passing the key into the crypto API.
Example fix
// before
pub := &rsa.PublicKey{N: n, E: 65536} // even -> error
// after
pub := &rsa.PublicKey{N: n, E: 65537} // 0x10001, odd Defensive patterns
Strategy: validation
Validate before calling
func validPublicExponent(e int) bool {
return e >= 2 && e&1 == 1 && e <= 1<<31-1
}
// before RSA ops:
if !validPublicExponent(pub.E) {
return fmt.Errorf("invalid RSA exponent E=%d", pub.E)
} Prevention
- Always construct RSA keys with E = 65537 (0x10001).
- After parsing a key from PEM/DER, assert pub.E is odd and small before using it.
- Treat any even or huge E as a parser bug, not as valid key material.
When it happens
Trigger: Constructing a rsa.PublicKey (or fips140/rsa.PublicKey) with an even E value (e.g. 2, 4, 6, 65536) and calling any API that runs checkPublicKey: Encrypt, encrypt, signature verification, key validation. Even one zero low bit triggers it.
Common situations: Hardcoded test fixtures with a non-standard exponent; key material imported from a malformed PEM/DER where E was decoded incorrectly; custom key generators that pick E=3 (odd, fine) but accidentally compute a wrong E; big-endian/little-endian swap of E turning 0x10001 into an even value.
Related errors
- crypto/rsa: public exponent too large
- crypto/rsa: missing public modulus
- crypto/rsa: invalid PSS salt length
- crypto/rsa: missing public modulus
- crypto/rsa: public modulus is even
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/3ba78f73d26eef72.
Report an issue: GitHub.