{"record":{"id":"0ed5d9bdcbf5b764","repo":"TheAlgorithms/Go","slug":"panic-err","errorCode":null,"errorMessage":"panic(err)","messagePattern":"panic\\(err\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cipher/dsa/dsa.go","lineNumber":63,"sourceCode":"// 2. Choose a N-bit prime q\n// 3. Choose a L-bit prime p such that p-1 is a multiple of q\n// 4. Choose an integer h randomly from the range [2, p-2]\n// 5. Compute g = h^((p-1)/q) mod p\n// 6. Return (p, q, g)\nfunc (dsa *dsa) dsaParameterGeneration() {\n\tvar err error\n\tp, q, bigInt := new(big.Int), new(big.Int), new(big.Int)\n\tone, g, h := big.NewInt(1), big.NewInt(1), big.NewInt(2)\n\tpBytes := make([]byte, L/8)\n\n\t// GPLoop is a label for the loop\n\t// We use this loop to change the prime q if we don't find a prime p\nGPLoop:\n\tfor {\n\t\t// 2. Choose a N-bit prime q\n\t\tq, err = rand.Prime(rand.Reader, N)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tfor i := 0; i < 4*L; i++ {\n\t\t\t// 3. Choose a L-bit prime p such that p-1 is a multiple of q\n\t\t\t// In this case we generate a random number of L bits\n\t\t\tif _, err := io.ReadFull(rand.Reader, pBytes); err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\n\t\t\t// This are the minimum conditions for p being a possible prime\n\t\t\tpBytes[len(pBytes)-1] |= 1 // p is odd\n\t\t\tpBytes[0] |= 0x80          // p has the highest bit set\n\t\t\tp.SetBytes(pBytes)\n\n\t\t\t// Instead of using (p-1)%q == 0\n\t\t\t// We ensure that p-1 is a multiple of q and validates if p is prime\n\t\t\tbigInt.Mod(p, q)\n\t\t\tbigInt.Sub(bigInt, one)","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/TheAlgorithms/Go/blob/5ba447ec5ff3d1213de65b92e726ee74c5d5cc19/cipher/dsa/dsa.go#L45-L81","documentation":"In dsaParameterGeneration (cipher/dsa), choosing the N-bit prime q uses crypto/rand.Prime. If the cryptographic RNG fails, the code panics with panic(err) instead of returning an error. This is a hard crash: the library treats RNG failure as unrecoverable rather than propagating it to the caller.","triggerScenarios":"Calling any DSA key-generation entry point when crypto/rand.Reader cannot deliver bytes — e.g. a depleted or misconfigured entropy source, a sandboxed/containerized environment without proper /dev/urandom access, or a custom rand.Reader injected into the package that returns errors.","commonSituations":"Containers with restricted device access, stripped-down VMs or embedded systems low on entropy, tests that stub rand.Reader with a failing reader, or a broken/failed hardware RNG.","solutions":["Fix the underlying entropy source so crypto/rand works (restore /dev/urandom access, fix container/VM configuration).","Recover from the panic at the call boundary and translate it into a returned error.","Replace the library's panic with error propagation (fork or upstream patch): return err from dsaParameterGeneration."],"exampleFix":"// before\nq, err = rand.Prime(rand.Reader, N)\nif err != nil {\n    panic(err)\n}\n// after\nq, err = rand.Prime(rand.Reader, N)\nif err != nil {\n    return nil, fmt.Errorf(\"dsa: failed to generate prime q: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Go's crypto/rand cannot be pre-validated directly; verify entropy source availability\nif _, err := os.Stat(\"/dev/urandom\"); err != nil {\n    return fmt.Errorf(\"entropy source unavailable: %w\", err)\n}","typeGuard":"func recoverDSAError() (err error) {\n    if r := recover(); r != nil {\n        if e, ok := r.(error); ok {\n            err = fmt.Errorf(\"dsa parameter generation panicked: %w\", e)\n        } else {\n            err = fmt.Errorf(\"dsa parameter generation panicked: %v\", r)\n        }\n    }\n    return\n}","tryCatchPattern":"func generateParamsSafe(N, L int) (p *dsa.Params, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"dsa: rng failure during parameter generation: %v\", r)\n        }\n    }()\n    return dsa.GenerateParameters(N, L)\n}","preventionTips":["Ensure the runtime environment exposes a working entropy source (e.g. /dev/urandom) before crypto operations.","Wrap DSA key/parameter generation in a recover() boundary to convert panics into errors.","In tests, only substitute rand.Reader with readers that never fail, or skip crypto tests in restricted sandboxes."],"tags":["go","crypto","dsa","panic","random-generation"],"backgroundTag":"crypto-rand-failure-panic","analyzedSha":"5ba447ec5ff3d1213de65b92e726ee74c5d5cc19","analyzedAt":"2026-09-02T21:54:30.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}