code:     public KeyPair generateKeyPair()
      {
          if (!initialised)
          {
              Integer paramStrength = Integers.valueOf(strength);
  
              if (params.containsKey(paramStrength))
              {
                  param = (DSAKeyGenerationParameters)params.get(paramStrength);
              }
              else
              {
                  synchronized (lock)
                  {
                      // we do the check again in case we were blocked by a generator for
                      // our key size.
                      if (params.containsKey(paramStrength))
                      {
                          param = (DSAKeyGenerationParameters)params.get(paramStrength);
                      }
                      else
                      {
                          DSAParametersGenerator pGen;
                          DSAParameterGenerationParameters dsaParams;
  
                          // Typical combination of keysize and size of q.
                          //     keysize = 1024, q's size = 160
                          //     keysize = 2048, q's size = 224
                          //     keysize = 2048, q's size = 256
                          //     keysize = 3072, q's size = 256
                          // For simplicity if keysize is greater than 1024 then we choose q's size to be 256.
                          // For legacy keysize that is less than 1024-bit, we just use the 186-2 style parameters
                          if (strength == 1024)
                          {
                              pGen = new DSAParametersGenerator();
                              if (Properties.isOverrideSet("org.bouncycastle.dsa.FIPS186-2for1024bits"))
                              {
                                  pGen.init(strength, certainty, random);
                              }
                              else
                              {
                                  dsaParams = new DSAParameterGenerationParameters(1024, 160, certainty, random);
                                  pGen.init(dsaParams);
                              }
                          }
                          else if (strength > 1024)
                          {
                              dsaParams = new DSAParameterGenerationParameters(strength, 256, certainty, random);
                              pGen = new DSAParametersGenerator(new SHA256Digest());
                              pGen.init(dsaParams);
                          }
                          else
                          {
                              pGen = new DSAParametersGenerator();
                              pGen.init(strength, certainty, random);
                          }
                          param = new DSAKeyGenerationParameters(random, pGen.generateParameters());
  
                          params.put(paramStrength, param);
                      }
                  }
              }
  
              engine.init(param);
              initialised = true;
          }
  
          AsymmetricCipherKeyPair pair = engine.generateKeyPair();
          DSAPublicKeyParameters pub = (DSAPublicKeyParameters)pair.getPublic();
          DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)pair.getPrivate();
  
          return new KeyPair(new BCDSAPublicKey(pub), new BCDSAPrivateKey(priv));
      }
  