// initializes the private variables (throws CryptographicException) private void Initialize(BigInteger p, BigInteger g, BigInteger x, int secretLen, bool checkInput) { if (!p.IsProbablePrime() || g <= 0 || g >= p || (x != null && (x <= 0 || x > p - 2))) throw new CryptographicException(); // default is to generate a number as large as the prime this // is usually overkill, but it's the most secure thing we can // do if the user doesn't specify a desired secret length ... if (secretLen == 0) secretLen = p.BitCount(); m_P = p; m_G = g; if (x == null) { BigInteger pm1 = m_P - 1; for(m_X = BigInteger.GenerateRandom(secretLen); m_X >= pm1 || m_X == 0; m_X = BigInteger.GenerateRandom(secretLen)) {} } else { m_X = x; } }
private void ExpectPrime (BigInteger bi) { Assertion.AssertEquals (true, bi.IsProbablePrime ()); }
private void GenerateParams (int keyLength) { byte[] seed = new byte[20]; byte[] part1 = new byte[20]; byte[] part2 = new byte[20]; byte[] u = new byte[20]; // TODO: a prime generator should be made for this SHA1 sha = SHA1.Create (); int n = (keyLength - 1) / 160; byte[] w = new byte [keyLength / 8]; bool primesFound = false; while (!primesFound) { do { Random.GetBytes (seed); part1 = sha.ComputeHash (seed); Array.Copy(seed, 0, part2, 0, seed.Length); add (part2, seed, 1); part2 = sha.ComputeHash (part2); for (int i = 0; i != u.Length; i++) u [i] = (byte)(part1 [i] ^ part2 [i]); // first bit must be set (to respect key length) u[0] |= (byte)0x80; // last bit must be set (prime are all odds - except 2) u[19] |= (byte)0x01; q = new BigInteger (u); } while (!q.IsProbablePrime ()); counter = 0; int offset = 2; while (counter < 4096) { for (int k = 0; k < n; k++) { add(part1, seed, offset + k); part1 = sha.ComputeHash (part1); Array.Copy (part1, 0, w, w.Length - (k + 1) * part1.Length, part1.Length); } add(part1, seed, offset + n); part1 = sha.ComputeHash (part1); Array.Copy (part1, part1.Length - ((w.Length - (n) * part1.Length)), w, 0, w.Length - n * part1.Length); w[0] |= (byte)0x80; BigInteger x = new BigInteger (w); BigInteger c = x % (q * 2); p = x - (c - 1); if (p.TestBit ((uint)(keyLength - 1))) { if (p.IsProbablePrime ()) { primesFound = true; break; } } counter += 1; offset += n + 1; } } // calculate the generator g BigInteger pMinusOneOverQ = (p - 1) / q; for (;;) { BigInteger h = BigInteger.GenerateRandom (keyLength); if ((h <= 1) || (h >= (p - 1))) continue; g = h.ModPow (pMinusOneOverQ, p); if (g <= 1) continue; break; } this.seed = new BigInteger (seed); j = (p - 1) / q; }
private void ExpectComposite (BigInteger bi) { Assertion.AssertEquals (false, bi.IsProbablePrime ()); }
private void ExpectPrime (BigInteger bi) { Assert.AreEqual (true, bi.IsProbablePrime ()); }