{"record":{"id":"864d9da03faabee3","repo":"golang/go","slug":"ecdsa-sign-called-with-nil-random-and-nil-opts","errorCode":null,"errorMessage":"ecdsa: Sign called with nil random and nil opts","messagePattern":"ecdsa: Sign called with nil random and nil opts","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/ecdsa/ecdsa.go","lineNumber":441,"sourceCode":"\t\treturn nil, errors.New(\"crypto/ecdsa: only crypto/rand.Reader is allowed in FIPS 140-only mode\")\n\t}\n\tk, err := privateKeyToFIPS(c, priv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// Always using SHA-512 instead of the hash that computed hash is\n\t// technically a violation of draft-irtf-cfrg-det-sigs-with-noise-04 but in\n\t// our API we don't get to know what it was, and this has no security impact.\n\tsig, err := ecdsa.Sign(c, sha512.New, k, rand, hash)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn encodeSignature(sig.R, sig.S)\n}\n\nfunc signRFC6979(priv *PrivateKey, hash []byte, opts crypto.SignerOpts) ([]byte, error) {\n\tif opts == nil {\n\t\treturn nil, errors.New(\"ecdsa: Sign called with nil random and nil opts\")\n\t}\n\th := opts.HashFunc()\n\tswitch priv.Curve.Params() {\n\tcase elliptic.P224().Params():\n\t\treturn signFIPSDeterministic(ecdsa.P224(), h, priv, hash)\n\tcase elliptic.P256().Params():\n\t\treturn signFIPSDeterministic(ecdsa.P256(), h, priv, hash)\n\tcase elliptic.P384().Params():\n\t\treturn signFIPSDeterministic(ecdsa.P384(), h, priv, hash)\n\tcase elliptic.P521().Params():\n\t\treturn signFIPSDeterministic(ecdsa.P521(), h, priv, hash)\n\tdefault:\n\t\treturn nil, errors.New(\"ecdsa: curve not supported by deterministic signatures\")\n\t}\n}\n\nfunc signFIPSDeterministic[P ecdsa.Point[P]](c *ecdsa.Curve[P], hashFunc crypto.Hash, priv *PrivateKey, hash []byte) ([]byte, error) {\n\tk, err := privateKeyToFIPS(c, priv)","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/ecdsa/ecdsa.go#L423-L459","documentation":"Thrown by signRFC6979 when opts is nil. This path is reached from PrivateKey.Sign when the random parameter is nil (requesting deterministic RFC 6979 signing). Deterministic signing requires knowing which hash function produced the digest, which comes from opts.HashFunc(). With nil opts, the hash function is undefined, so signing cannot proceed.","triggerScenarios":"Calling priv.Sign(nil, digest, nil) — nil random triggers the deterministic RFC 6979 path, and nil opts means no hash function is specified. The Sign method only validates opts when it's non-nil, so nil opts passes through to signRFC6979 which then rejects it.","commonSituations":"Code that passes nil for both random and opts expecting some default behavior; misunderstanding the API where nil random means deterministic but forgetting that opts is still required to specify the hash; refactoring that accidentally nullifies opts.","solutions":["When requesting deterministic signing (random=nil), always provide a non-nil crypto.SignerOpts: priv.Sign(nil, digest, crypto.SHA256).","If you want randomized signing, pass a non-nil random reader (e.g., rand.Reader) — then nil opts is acceptable.","Understand the API contract: nil random = deterministic (requires opts), non-nil random = randomized (opts optional)."],"exampleFix":"// before\nsig, err := priv.Sign(nil, digest, nil) // both nil — error\n\n// after\nsig, err := priv.Sign(nil, digest, crypto.SHA256) // deterministic with SHA-256","handlingStrategy":"validation","validationCode":"func validateSignParams(random io.Reader, opts crypto.SignerOpts) error {\n    if random == nil && opts == nil {\n        return errors.New(\"deterministic signing requires non-nil opts with a hash\")\n    }\n    return nil\n}","typeGuard":"func canSignDeterministically(opts crypto.SignerOpts) bool {\n    return opts != nil && opts.HashFunc() != 0\n}","tryCatchPattern":"sig, err := priv.Sign(random, digest, opts)\nif err != nil && strings.Contains(err.Error(), \"nil random and nil opts\") {\n    // provide opts to enable deterministic signing\n    sig, err = priv.Sign(nil, digest, crypto.SHA256)\n}","preventionTips":["When random is nil (deterministic), always provide opts with a real hash function.","Pass crypto.Hash values directly as opts since crypto.Hash implements SignerOpts."],"tags":["crypto","ecdsa","signing","rfc6979","deterministic","api-misuse"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}