/// <summary> /// Generates a key pair using a portable BES approach. /// </summary> /// <param name="keyGen"></param> /// <param name="keySize"></param> /// <returns></returns> public AsymmetricCipherKeyPair GenerateKeyPair(IBasylKeyGenerator keyGen, int keySize) { gSize = keySize; gen = keyGen; Thread thread = new Thread(new ThreadStart(GenerateP)), thread2 = new Thread(new ThreadStart(GenerateQ)); thread.Start(); thread2.Start(); thread.Join(); thread2.Join(); var n = p * q; var e = 65537; var phi = (p - 1) * (q - 1); var d = (new Org.BouncyCastle.Math.BigInteger(e.ToString())).ModInverse(phi.Convert()); var dP = d.Remainder((p - 1).Convert()); var dQ = d.Remainder((q - 1).Convert()); var qInv = q.Convert().ModInverse(p.Convert()); return(new AsymmetricCipherKeyPair( new RsaKeyParameters(false, n.Convert(), new Org.BouncyCastle.Math.BigInteger(e.ToString())), new RsaPrivateCrtKeyParameters(n.Convert(), new Org.BouncyCastle.Math.BigInteger(e.ToString()), d, p.Convert(), q.Convert(), dP, dQ, qInv))); }
/// <summary> /// Generates a random large prime near the given bit size. /// </summary> /// <param name="generator"></param> /// <param name="size"></param> /// <returns></returns> private static BigInteger GetRandomLargePrime(IBasylKeyGenerator generator, int size) { //fills an array with random bytes. This is used for the prime search. byte[] vals = new byte[(int)Math.Ceiling(size / 8.0f)]; lock (generator) { for (int i = 0; i < 20; i++) { generator.FillBytes(vals); } for (int k = 0; k < 2; k++) { for (int i = 0; i < vals.Length; i++) { for (int n = 0; n < 3; n++) { generator.GetRandomByte(); } generator.EncryptByte(ref vals[i]); } } } //searches for the prime number, decreases until it finds one that tests to be prime. BigInteger gco = new BigInteger(vals); if (gco < 0) { gco *= -1; } if (gco.IsEven) { gco -= 1; } var bouncyCastleBig = gco.Convert(); var amt = new BigInteger(2).Convert(); while (!bouncyCastleBig.IsProbablePrime(1)) { bouncyCastleBig = bouncyCastleBig.Subtract(amt); gco -= 2; } //Bouncy castles isProbablePrime method is severely optimized compared to a naive approach. return(gco); }