in UProveParams/SubgroupRecommendedParameters.cs [292:348]
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");
}