private synchronized BigInteger[] generateParameters() {
      // N    A large safe prime (N = 2q+1, where q is prime)
      // g    A generator modulo N
      BigInteger q, p, g;
      byte[] qBytes = new byte[l / 8];
      do {
         do {
            nextRandomBytes(qBytes);
            q = new BigInteger(1, qBytes);
            q = q.setBit(0).setBit(l-2).clearBit(l-1);
         } while (!Prime.isProbablePrime(q));
         p = q.multiply(TWO).add(ONE);
      } while (p.bitLength() != l || !Prime.isProbablePrime(p));

      // compute g. from FIPS-186, Appendix 4: e == 2
      BigInteger p_minus_1 = p.subtract(ONE);
      g = TWO;
      // Set h = any integer, where 1 < h < p - 1 and
      // h differs from any value previously tried
      for (BigInteger h = TWO; h.compareTo(p_minus_1) < 0; h = h.add(ONE)) {
         // Set g = h**2 mod p
         g = h.modPow(TWO, p);
         // If g = 1, go to step 3
         if (!g.equals(ONE)) {
            break;
         }
      }

      return new BigInteger[] { q, p, g };
   }