public void When_GenerateParameters_Should_ReturnCorrectValues() { for (int i = 0; i < 3; i++) { DsaSystemParameters parameters = _generator.GenerateParameters(1024, 160, 160); _primalityTester.CheckPrimality(parameters.Q).Should().BeTrue(); _primalityTester.CheckPrimality(parameters.P).Should().BeTrue(); //p - 1 is a multiple of q ((parameters.P - 1) % parameters.Q).Should().BeEquivalentTo(BigInteger.Zero); //g^q is congruent to mod 1 BigInteger.ModPow(parameters.G, parameters.Q, parameters.P).Should().BeEquivalentTo(BigInteger.One); } }
public DsaSystemParameters GenerateParameters(int L, int N, int seedLen) { #region CONDITIONS //SHA-1 used //Bit length of the output block of choosen hash function, shall be equal to or greater than N int outlen = 160; // check combination support if (!CheckLengthCombinations(L, N)) { throw new ArgumentException($"Combination of lengths: L={L} and N={N} is not supported"); } if (outlen < N) { throw new ArgumentException("Outlen cannot be less than N"); } // insisted by FIPS standard if (seedLen < N) { throw new ArgumentException("Seedlen cannot be less then N"); } #endregion // calculate equation parameters L - 1 = n * 160(outlen) + b int n = (int)Math.Ceiling((double)L / outlen) - 1; int b = L - 1 - (n * outlen); // create container for seed int remainingBits = seedLen % 8; byte[] seed = new byte[(seedLen / 8) + (remainingBits == 0 ? 0 : 1)]; BigInteger outlenPow = BigInteger.Pow(2, seedLen); BigInteger p, q; bool outerLoop = true; do { q = GenerateQ(outlenPow, remainingBits, seed); bool innerLoop = true; int counter = 0, offset = 2; do { p = GenerateP(L, outlen, outlenPow, n, b, seed, q, ref offset); if (p < BigInteger.Pow(2, L - 1)) { UpdateControlVariables(n, ref outerLoop, ref innerLoop, ref counter, ref offset); } else { if (_primalityTester.CheckPrimality(p)) { outerLoop = false; innerLoop = false; } else { UpdateControlVariables(n, ref outerLoop, ref innerLoop, ref counter, ref offset); } } } while (innerLoop); } while (outerLoop || (p - 1) % q != 0); BigInteger g = GenerateG(p, q); return(new DsaSystemParameters(p, q, g)); }