{"record":{"id":"4883c3fb44ffe96c","repo":"golang/go","slug":"crypto-rsa-precomputed-values-are-inconsistent-wi","errorCode":null,"errorMessage":"crypto/rsa: precomputed values are inconsistent with the key","messagePattern":"crypto/rsa: precomputed values are inconsistent with the key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/rsa.go","lineNumber":252,"sourceCode":"\n// Validate performs basic sanity checks on the key.\n// It returns nil if the key is valid, or else an error describing a problem.\n//\n// It runs faster on valid keys if run after [PrivateKey.Precompute].\nfunc (priv *PrivateKey) Validate() error {\n\t// We can operate on keys based on d alone, but they can't be encoded with\n\t// [crypto/x509.MarshalPKCS1PrivateKey], which unfortunately doesn't return\n\t// an error, so we need to reject them here.\n\tif len(priv.Primes) < 2 {\n\t\treturn errors.New(\"crypto/rsa: missing primes\")\n\t}\n\t// If Precomputed.fips is set and consistent, then the key has been\n\t// validated by [rsa.NewPrivateKey] or [rsa.NewPrivateKeyWithoutCRT].\n\tif priv.precomputedIsConsistent() {\n\t\treturn nil\n\t}\n\tif priv.Precomputed.fips != nil {\n\t\treturn errors.New(\"crypto/rsa: precomputed values are inconsistent with the key\")\n\t}\n\t_, err := priv.precompute()\n\treturn err\n}\n\nfunc (priv *PrivateKey) precomputedIsConsistent() bool {\n\tif priv.Precomputed.fips == nil {\n\t\treturn false\n\t}\n\tN, e, d, P, Q, dP, dQ, qInv := priv.Precomputed.fips.Export()\n\tif !bigIntEqualToBytes(priv.N, N) || priv.E != e || !bigIntEqualToBytes(priv.D, d) {\n\t\treturn false\n\t}\n\tif len(priv.Primes) != 2 {\n\t\treturn P == nil && Q == nil && dP == nil && dQ == nil && qInv == nil\n\t}\n\treturn bigIntEqualToBytes(priv.Primes[0], P) &&\n\t\tbigIntEqualToBytes(priv.Primes[1], Q) &&","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/rsa.go#L234-L270","documentation":"Returned by PrivateKey.Validate when Precomputed.fips is non-nil but precomputedIsConsistent() returns false — i.e. the cached FIPS key handle was built for different N/E/D/p/q/dP/dQ/qInv than the key currently carries. This means somebody mutated the struct fields after Precompute (or after NewPrivateKey), invalidating the cached CRT values. The library treats this as a hard error rather than silently using stale CRT data.","triggerScenarios":"Mutate priv.N, priv.E, priv.D, priv.Primes[i], or priv.Precomputed.Dp/Dq/Qinv after Precompute()/NewPrivateKey(); unmarshal a key on top of an already-precomputed one without resetting Precomputed.","commonSituations":"Reusing a *rsa.PrivateKey variable across keys to avoid allocation; a deserializer that fills fields in two passes (first N/E, then primes) after the struct was already Precomputed; test fixtures that mutate keys in place.","solutions":["Treat *rsa.PrivateKey as immutable after construction — build a fresh struct for a new key.","If you must mutate, zero out priv.Precomputed (set Precomputed to PrecomputedValues{}) and call Precompute() again before Validate().","Re-construct the key via rsa.NewPrivateKey / x509.ParsePKCS1PrivateKey to get a clean Precomputed handle."],"exampleFix":"// before: mutate in place\npriv.N = newN\nerr := priv.Validate() // err: precomputed values are inconsistent\n\n// after: reset and recompute, or rebuild\npriv.Precomputed = rsa.PrecomputedValues{}\npriv.Precompute()\nerr := priv.Validate()","handlingStrategy":"validation","validationCode":"// Reset cached precomputation before mutating a key, then recompute.\nfunc safeMutate(priv *rsa.PrivateKey) {\n    priv.Precomputed = rsa.PrecomputedValues{}\n    // ... apply field changes ...\n    priv.Precompute()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat *rsa.PrivateKey as immutable after construction.","If you must reuse a variable, zero Precomputed before changing fields.","Re-obtain keys from the parser instead of mutating in place."],"tags":["rsa","key-validation","mutation","crypto"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}