public static BigInteger FIPS_186_3_AnnexA_2_3(BigInteger p, BigInteger q, byte[] domain_parameter_seed, byte index, Formatter formater, out int count)
        {
            string hashAlg = null;

            if (q.BitLength >= 512)
            {
                hashAlg = "SHA-512";
            }
            else if (q.BitLength >= 256)
            {
                hashAlg = "SHA-256";
            }
            else if (q.BitLength >= 160)
            {
                hashAlg = "SHA1";
            }
            else
            {
                throw new ArgumentException("q is too small");
            }
            HashAlgorithm hash = HashAlgorithm.Create(hashAlg);

            BigInteger e = p.Subtract(BigInteger.One).Divide(q);

            if (formater != null)
            {
                formater.PrintBigInteger("vr_e", "UCHAR", null, e);
            }
            count = 1;

            while (count != 0)
            {
                int    uIndex = 0;
                byte[] U      = new byte[domain_parameter_seed.Length + ggen.Length + 2];
                Array.Copy(domain_parameter_seed, 0, U, uIndex, domain_parameter_seed.Length);
                uIndex += domain_parameter_seed.Length;
                Array.Copy(ggen, 0, U, uIndex, ggen.Length);
                uIndex         += ggen.Length;
                U[U.Length - 2] = index;
                U[U.Length - 1] = (byte)count;

                BigInteger W = new BigInteger(1, hash.ComputeHash(U));
                BigInteger g = W.ModPow(e, p);
                if (g.CompareTo(BigInteger.Two) >= 0)
                {
                    if (formater != null)
                    {
                        formater.PrintHex("vr_U", "UCHAR", null, U);
                        formater.PrintBigInteger("vr_W", "UCHAR", null, W);
                    }
                    return(g);
                }

                count++;
            }

            throw new Exception("Can't generate generator; max count reached");
        }