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"); }