{"record":{"id":"df8a32b3dc474296","repo":"golang/go","slug":"crypto-ed25519-only-crypto-rand-reader-is-allowed","errorCode":null,"errorMessage":"crypto/ed25519: only crypto/rand.Reader is allowed in FIPS 140-only mode","messagePattern":"crypto/ed25519: only crypto/rand\\.Reader is allowed in FIPS 140-only mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/ed25519/ed25519.go","lineNumber":164,"sourceCode":"// restored with GODEBUG=cryptocustomrand=1. This setting will be removed in a\n// future Go release. Instead, use [testing/cryptotest.SetGlobalRandom].)\n//\n// The output of this function is deterministic, and equivalent to reading\n// [SeedSize] bytes from random, and passing them to [NewKeyFromSeed].\nfunc GenerateKey(random io.Reader) (PublicKey, PrivateKey, error) {\n\tif random == nil {\n\t\tif cryptocustomrand.Value() == \"1\" {\n\t\t\trandom = cryptorand.Reader\n\t\t\tif !rand.IsDefaultReader(random) {\n\t\t\t\tcryptocustomrand.IncNonDefault()\n\t\t\t}\n\t\t} else {\n\t\t\trandom = rand.Reader\n\t\t}\n\t}\n\n\tif fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) {\n\t\treturn nil, nil, errors.New(\"crypto/ed25519: only crypto/rand.Reader is allowed in FIPS 140-only mode\")\n\t}\n\n\tif rand.IsDefaultReader(random) {\n\t\tprivateKey, err := ed25519.GenerateKey()\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tpublicKey := PublicKey(privateKey.PublicKey())\n\t\treturn publicKey, PrivateKey(privateKey.Bytes()), nil\n\t}\n\n\tseed := make([]byte, SeedSize)\n\tif _, err := io.ReadFull(random, seed); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tprivateKey := NewKeyFromSeed(seed)\n\tpublicKey := privateKey.Public().(PublicKey)","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/ed25519/ed25519.go#L146-L182","documentation":"Thrown by ed25519.GenerateKey (ed25519.go:164) when FIPS 140-only mode is active and the supplied random reader is not the approved crypto/rand.Reader (fips140only.ApprovedRandomReader returns false). FIPS 140 requires entropy from the approved DRBG/cryptorand.Reader; custom or testing readers are rejected.","triggerScenarios":"Calling ed25519.GenerateKey(rand.Reader, nonDefaultReader) — passing a deterministic test reader, math/rand, or a wrapped reader — while FIPS 140-only is enforced. fips140only.ApprovedRandomReader(random) must be true to proceed.","commonSituations":"Tests that inject a deterministic reader for reproducibility; code that wraps rand.Reader for logging/metering; enabling FIPS mode without auditing all GenerateKey call sites. GODEBUG=cryptocustomrand=1 also interacts here.","solutions":["Pass crypto/rand.Reader (or nil, which resolves to the default reader) for key generation under FIPS builds.","For deterministic test keys, use testing/cryptotest.SetGlobalRandom instead of injecting a custom reader, or gate the test reader behind !fips140only.Enforced().","Ensure no reader-wrapping layer sits between your code and crypto/rand.Reader in FIPS builds."],"exampleFix":"// before\nreader := mathrand.New(mathrand.NewSource(1)) // not approved\npub, priv, err := ed25519.GenerateKey(reader, reader) // FIPS-only -> error 250\n\n// after\npub, priv, err := ed25519.GenerateKey(nil, nil) // uses crypto/rand.Reader","handlingStrategy":"validation","validationCode":"if fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) {\n    return errors.New(\"only crypto/rand.Reader is allowed in FIPS 140-only mode\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass nil or crypto/rand.Reader to GenerateKey under FIPS builds.","Use testing/cryptotest.SetGlobalRandom for deterministic tests instead of a custom reader.","Ensure no reader-wrapping layer intercepts crypto/rand.Reader in FIPS builds."],"tags":["go","crypto","ed25519","fips","randomness"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}