{"record":{"id":"450fa27811224965","repo":"golang/go","slug":"crypto-rsa-public-modulus-is-even","errorCode":null,"errorMessage":"crypto/rsa: public modulus is even","messagePattern":"crypto/rsa: public modulus is even","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/crypto/internal/fips140/rsa/rsa.go","lineNumber":332,"sourceCode":"\t//\n\t// See section 3 of https://crypto.stanford.edu/~dabo/papers/RSA-survey.pdf\n\t// for more details about attacks on small d values.\n\t//\n\t// Likewise, the leakage of the magnitude of d is not adaptive.\n\tif priv.d.BitLenVarTime() <= N.BitLen()/2 {\n\t\treturn errors.New(\"crypto/rsa: d too small\")\n\t}\n\n\treturn nil\n}\n\nfunc checkPublicKey(pub *PublicKey) (fipsApproved bool, err error) {\n\tfipsApproved = true\n\tif pub.N == nil {\n\t\treturn false, errors.New(\"crypto/rsa: missing public modulus\")\n\t}\n\tif pub.N.Nat().IsOdd() == 0 {\n\t\treturn false, errors.New(\"crypto/rsa: public modulus is even\")\n\t}\n\t// FIPS 186-5, Section 5.1: \"This standard specifies the use of a modulus\n\t// whose bit length is an even integer and greater than or equal to 2048\n\t// bits.\"\n\tif pub.N.BitLen() < 2048 {\n\t\tfipsApproved = false\n\t}\n\tif pub.N.BitLen()%2 == 1 {\n\t\tfipsApproved = false\n\t}\n\tif pub.E < 2 {\n\t\treturn false, errors.New(\"crypto/rsa: public exponent too small or negative\")\n\t}\n\t// e needs to be coprime with p-1 and q-1, since it must be invertible\n\t// modulo λ(pq). Since p and q are prime, this means e needs to be odd.\n\tif pub.E&1 == 0 {\n\t\treturn false, errors.New(\"crypto/rsa: public exponent is even\")\n\t}","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/rsa/rsa.go#L314-L350","documentation":"Thrown by checkPublicKey when N is even (N.Nat().IsOdd() == 0). RSA modulus N = p*q where p,q are odd primes, so N is always odd; an even N is either 2-smooth (trivially factorable) or corrupted, and cannot be a valid RSA modulus.","triggerScenarios":"checkPublicKey tests N.Nat().IsOdd() == 0 during any RSA operation that validates the public key. Fires when the low bit of N is 0.","commonSituations":"N constructed as an even number in a test/fixture. A byte-corrupted N whose low bit flipped to 0. A custom key builder that multiplied 2 into N. Mis-parsed big-endian bytes dropping the leading odd byte.","solutions":["Use keys produced by rsa.GenerateKey, which always yields odd N.","On import, reject N whose least-significant bit is 0.","Re-serialize and re-parse to rule out byte-order corruption."],"exampleFix":"// before\n// N built or parsed such that it is even\n\n// after\nif n.Bit(0) == 0 {\n    return errors.New(\"RSA modulus must be odd\")\n}\npub := &rsa.PublicKey{N: n, E: 65537}","handlingStrategy":"validation","validationCode":"if n.Bit(0) == 0 {\n    return errors.New(\"RSA modulus must be odd\")\n}","typeGuard":"func modulusOdd(n *big.Int) bool { return n.Bit(0) == 1 }","tryCatchPattern":"err := op(pub)\nif err != nil && strings.Contains(err.Error(), \"public modulus is even\") {\n    return err // regenerate; N is corrupt or invalid\n}","preventionTips":["Use keys from rsa.GenerateKey, which always yields odd N.","Reject even N on import.","Re-serialize/re-parse to rule out byte corruption."],"tags":["crypto","rsa","public-key","input-validation","security","go"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}