public static byte[] CreateSignature(byte[] p_data, ElGamalKeyStruct p_key_struct) { BigInteger x_pminusone = p_key_struct.P - 1; BigInteger K; do { K = new BigInteger(); K.genRandomBits(p_key_struct.P.bitCount() - 1, new Random()); } while (K.gcd(x_pminusone) != 1); BigInteger A = p_key_struct.G.modPow(K, p_key_struct.P); BigInteger B = mod(mod(K.modInverse(x_pminusone) * (new BigInteger(p_data) - (p_key_struct.X * (A))), (x_pminusone)), (x_pminusone)); byte[] x_a_bytes = A.getBytes(); byte[] x_b_bytes = B.getBytes(); int x_result_size = (((p_key_struct.P.bitCount() + 7) / 8) * 2); byte[] x_result = new byte[x_result_size]; Array.Copy(x_a_bytes, 0, x_result, x_result_size / 2 - x_a_bytes.Length, x_a_bytes.Length); Array.Copy(x_b_bytes, 0, x_result, x_result_size - x_b_bytes.Length, x_b_bytes.Length); return(x_result); }
public static byte[] CreateSignature(byte[] p_data, ElGamalKeyStruct p_key_struct) { BigInteger x_pminusone = p_key_struct.P - 1; // create K, which is the random number BigInteger K; do { K = new BigInteger(); K.genRandomBits(p_key_struct.P.bitCount() - 1, new Random()); } while (K.gcd(x_pminusone) != 1); BigInteger A = p_key_struct.G.modPow(K, p_key_struct.P); BigInteger B = mod(mod(K.modInverse(x_pminusone) * (new BigInteger(p_data) - (p_key_struct.X * (A))), (x_pminusone)), (x_pminusone)); byte[] x_a_bytes = A.getBytes(); byte[] x_b_bytes = B.getBytes(); // define the result size int x_result_size = (((p_key_struct.P.bitCount() + 7) / 8) * 2); // create an array to contain the ciphertext byte[] x_result = new byte[x_result_size]; // populate the arrays Array.Copy(x_a_bytes, 0, x_result, x_result_size / 2 - x_a_bytes.Length, x_a_bytes.Length); Array.Copy(x_b_bytes, 0, x_result, x_result_size - x_b_bytes.Length, x_b_bytes.Length); // return the result array .. return(x_result); }
protected override byte[] ProcessDataBlock(byte[] p_block) { // the random number, K BigInteger K; // create K, which is the random number do { K = new BigInteger(); K.genRandomBits(o_key_struct.P.bitCount() - 1, o_random); } while (K.gcd(o_key_struct.P - 1) != 1); // compute the values A and B BigInteger A = o_key_struct.G.modPow(K, o_key_struct.P); BigInteger B = (o_key_struct.Y.modPow(K, o_key_struct.P) * new BigInteger(p_block)) % (o_key_struct.P); // create an array to contain the ciphertext byte[] x_result = new byte[o_ciphertext_blocksize]; // copy the bytes from A and B into the result array byte[] x_a_bytes = A.getBytes(); Array.Copy(x_a_bytes, 0, x_result, o_ciphertext_blocksize / 2 - x_a_bytes.Length, x_a_bytes.Length); byte[] x_b_bytes = B.getBytes(); Array.Copy(x_b_bytes, 0, x_result, o_ciphertext_blocksize - x_b_bytes.Length, x_b_bytes.Length); // return the result array return(x_result); }
/// <summary> /// Probabilistic prime test based on Rabin-Miller's test /// </summary> /// <param name="bi" type="BigInteger.BigInteger"> /// <para> /// The number to test. /// </para> /// </param> /// <param name="confidence" type="int"> /// <para> /// The number of chosen bases. The test has at least a /// 1/4^confidence chance of falsely returning True. /// </para> /// </param> /// <returns> /// <para> /// True if "this" is a strong pseudoprime to randomly chosen bases. /// </para> /// <para> /// False if "this" is definitely NOT prime. /// </para> /// </returns> public static bool RabinMillerTest(BigInteger bi, ConfidenceFactor confidence) { int Rounds = GetSPPRounds(bi, confidence); // calculate values of s and t BigInteger p_sub1 = bi - 1; int s = p_sub1.LowestSetBit(); BigInteger t = p_sub1 >> s; int bits = bi.bitCount(); BigInteger a = null; RandomNumberGenerator rng = RandomNumberGenerator.Create(); var mr = new BigInteger.ModulusRing(bi); for (int round = 0; round < Rounds; round++) { while (true) { // generate a < n a = BigInteger.genRandom(bits, rng); // make sure "a" is not 0 if (a > 1 && a < bi) { break; } } if (a.gcd(bi) != 1) { return(false); } BigInteger b = mr.Pow(a, t); if (b == 1) { continue; // a^t mod p = 1 } bool result = false; for (int j = 0; j < s; j++) { if (b == p_sub1) { // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 result = true; break; } b = (b * b) % bi; } if (result == false) { return(false); } } return(true); }
protected override byte[] ProcessDataBlock(byte[] p_block) { BigInteger K; do { K = new BigInteger(); K.genRandomBits(o_key_struct.P.bitCount() - 1, o_random); } while (K.gcd(o_key_struct.P - 1) != 1); BigInteger A = o_key_struct.G.modPow(K, o_key_struct.P); BigInteger B = (o_key_struct.Y.modPow(K, o_key_struct.P) * new BigInteger(p_block)) % (o_key_struct.P); byte[] x_result = new byte[o_ciphertext_blocksize]; byte[] x_a_bytes = A.getBytes(); Array.Copy(x_a_bytes, 0, x_result, o_ciphertext_blocksize / 2 - x_a_bytes.Length, x_a_bytes.Length); byte[] x_b_bytes = B.getBytes(); Array.Copy(x_b_bytes, 0, x_result, o_ciphertext_blocksize - x_b_bytes.Length, x_b_bytes.Length); return(x_result); }
public void TestGenCoPrime() { { // Test small values var bi = new BigInteger(); var rng = new RNGCryptoServiceProvider(); bi.genRandomBits(100, rng); var coprime = bi.genCoPrime(10, rng); Assert.Equal(1, (bi.gcd(coprime)).getBytes()[0]); } // Test arbitrary values for (int i = 0; i < 99; i++) { var bi = new BigInteger(); var rng = new RNGCryptoServiceProvider(); var rand = new Random(); bi.genRandomBits(rand.Next(1, 32 * 69 + 1), rng); var coprime = bi.genCoPrime(rand.Next(1, 2241), rng); Assert.Equal(1, (bi.gcd(coprime)).getBytes()[0]); } }
//PROCESS_DATA_METHOD protected override byte[] ProcessDataBlock(byte[] plaintext_data_block) { // the random number, K BigInteger K; // create K, which is the random number do { K = new BigInteger(); K.genRandomBits(current_key.P.bitCount() - 1, random_number); }while (K.gcd(current_key.P - 1) != 1); // compute the values A = G exp K mod P // and B = ((Y exp K mod P) * plain_data_block) / P //Y is Alice's encrypted result (public key) BigInteger A = current_key.G.modPow(K, current_key.P); BigInteger B = (current_key.Y.modPow(K, current_key.P) * new BigInteger(plaintext_data_block)) % (current_key.P); // ciphertext byte[] cipher_result = new byte[ciphertext_blocksize]; // copy the bytes from A and B into the result array which is cipher_result byte[] a_bytes = A.getBytes(); Array.Copy(a_bytes, 0, cipher_result, ciphertext_blocksize / 2 - a_bytes.Length, a_bytes.Length); //96bit byte[] b_bytes = B.getBytes(); Array.Copy(b_bytes, 0, cipher_result, ciphertext_blocksize - b_bytes.Length, b_bytes.Length); //96bit // return the result array after merging A and B return(cipher_result); }
public void TestGenCoPrime() { { // Test small values var bi = new BigInteger(); var rng = new RNGCryptoServiceProvider(); bi.genRandomBits(100, rng); var coprime = bi.genCoPrime(10, rng); Assert.IsTrue((bi.gcd(coprime)).getBytes()[0] == 1); } { // Test arbitrary values var bi = new BigInteger(); var rng = new RNGCryptoServiceProvider(); var rand = new Random(); bi.genRandomBits(rand.Next(2241), rng); var coprime = bi.genCoPrime(rand.Next(2241), rng); Assert.IsTrue((bi.gcd(coprime)).getBytes()[0] == 1); } }
private static bool runMillerRabin(BigInteger number, SecureRandom random ) { if (number.compareTo(BigInteger.valueOf(3)) <= 0) { return(number.compareTo(BigInteger.ONE) != 0); } // Ensures that temp > 1 and temp < n. BigInteger temp = BigInteger.ZERO; do { temp = new BigInteger(number.bitLength() - 1, random); }while (temp.compareTo(BigInteger.ONE) <= 0); // Screen out n if our random number happens to share a factor with n. if (!number.gcd(temp).Equals(BigInteger.ONE)) { return(false); } // For debugging, prints out the integer to test with. //System.out.println("Testing with " + temp); BigInteger d = number.subtract(BigInteger.ONE); // Figure s and d Values int s = 0; while ((d.mod(TWO)).Equals(BigInteger.ZERO)) { d = d.divide(TWO); s++; } BigInteger curValue = temp.modPow(d, number); // If this works out, it's a prime if (curValue.Equals(BigInteger.ONE)) { return(true); } // Otherwise, we will check to see if this value successively // squared ever yields -1. for (int r = 0; r < s; r++) { // We need to really check n-1 which is equivalent to -1. if (curValue.Equals(number.subtract(BigInteger.ONE))) { return(true); } else { // Square this previous number - here I am just doubling the // exponent. A more efficient implementation would store the // value of the exponentiation and square it mod n. curValue = curValue.modPow(TWO, number); } } // If none of our tests pass, we return false. The number is // definitively composite if we ever get here. return(false); }
private void CheckX() { x = BigInteger.genPseudoPrime(128, 100, new Random()); while (N.gcd(x) != 1) { x = BigInteger.genPseudoPrime(128, 100, new Random()); } }
public void GeneratePair(int b, BigInteger e) { this.e = e; int qs = b >> 1; while (true) { while (true) { P = BigInteger.genPseudoPrime(b - qs, 1, new Random()); if ((P - 1).gcd(this.e) == 1 && P.isProbablePrime(10)) { break; } } while (true) { Q = BigInteger.genPseudoPrime(qs, 1, new Random()); if ((Q - 1).gcd(this.e) == 1 && P.isProbablePrime(10)) { break; } } if (P < Q) { BigInteger t = P; P = Q; Q = t; } BigInteger phi = (P - 1) * (Q - 1); if (phi.gcd(this.e) == 1) { N = P * Q; D = this.e.modInverse(phi); Dmp1 = D % (P - 1); Dmq1 = D % (Q - 1); Coeff = Q.modInverse(P); break; } } CanEncrypt = N != 0 && this.e != 0; CanDecrypt = CanEncrypt && D != 0; Console.WriteLine(N.ToString(16)); Console.WriteLine(D.ToString(16)); }
public void GeneratePair(int b, BigInteger e) { this.e = e; int qs = b >> 1; while (true) { while (true) { this.P = BigInteger.genPseudoPrime(b - qs, 1, new Random()); if ((this.P - 1).gcd(this.e) == 1 && this.P.isProbablePrime(10)) { break; } } while (true) { this.Q = BigInteger.genPseudoPrime(qs, 1, new Random()); if ((this.Q - 1).gcd(this.e) == 1 && this.P.isProbablePrime(10)) { break; } } if (this.P < this.Q) { BigInteger t = this.P; this.P = this.Q; this.Q = t; } BigInteger phi = (this.P - 1) * (this.Q - 1); if (phi.gcd(this.e) == 1) { this.N = this.P * this.Q; this.D = this.e.modInverse(phi); this.Dmp1 = this.D % (this.P - 1); this.Dmq1 = this.D % (this.Q - 1); this.Coeff = this.Q.modInverse(this.P); break; } } this.CanEncrypt = this.N != 0 && this.e != 0; this.CanDecrypt = this.CanEncrypt && this.D != 0; Console.WriteLine(N.ToString(16)); Console.WriteLine(D.ToString(16)); }
public void GeneratePair(int B, BigInteger _E) { E = _E; int Qs = B >> 1; while (true) { while (true) { P = BigInteger.genPseudoPrime(B - Qs, 1, new Random()); if ((P - 1).gcd(E) == 1 && P.isProbablePrime(10)) { break; } } while (true) { Q = BigInteger.genPseudoPrime(Qs, 1, new Random()); if ((Q - 1).gcd(E) == 1 && P.isProbablePrime(10)) { break; } } if (P < Q) { BigInteger t = P; P = Q; Q = t; } BigInteger phi = (P - 1) * (Q - 1); if (phi.gcd(E) == 1) { N = P * Q; D = E.modInverse(phi); Dmp1 = D % (P - 1); Dmq1 = D % (Q - 1); Coeff = Q.modInverse(P); break; } } CanEncrypt = N != 0 && E != 0; CanDecrypt = CanEncrypt && D != 0; Console.WriteLine(N.ToString(16)); Console.WriteLine(D.ToString(16)); }
public RSA(int b, BigInteger e) { this.e = e; int qs = b >> 1; while (true) { while (true) { this.p = BigInteger.genPseudoPrime(b - qs, 1, new Random()); if ((this.p - 1).gcd(this.e) == 1 && this.p.isProbablePrime(10)) { break; } } while (true) { this.q = BigInteger.genPseudoPrime(qs, 1, new Random()); if ((this.q - 1).gcd(this.e) == 1 && this.p.isProbablePrime(10)) { break; } } if (this.p < this.q) { BigInteger t = this.p; this.p = this.q; this.q = t; } BigInteger phi = (this.p - 1) * (this.q - 1); if (phi.gcd(this.e) == 1) { this.n = this.p * this.q; this.d = this.e.modInverse(phi); this.dmp1 = this.d % (this.p - 1); this.dmq1 = this.d % (this.q - 1); this.coeff = this.q.modInverse(this.p); break; } } this.canEncrypt = this.n != 0 && this.e != 0; this.canDecrypt = this.canEncrypt && this.d != 0; }
public RSA(int b, BigInteger e) { this.e = e; int qs = b >> 1; while (true) { while (true) { p = BigInteger.genPseudoPrime(b - qs, 1, new Random()); if ((p - 1).gcd(this.e) == 1 && p.isProbablePrime(10)) { break; } } while (true) { q = BigInteger.genPseudoPrime(qs, 1, new Random()); if ((q - 1).gcd(this.e) == 1 && p.isProbablePrime(10)) { break; } } if (p < q) { BigInteger t = p; p = q; q = t; } BigInteger phi = (p - 1) * (q - 1); if (phi.gcd(this.e) == 1) { n = p * q; d = this.e.modInverse(phi); dmp1 = d % (p - 1); dmq1 = d % (q - 1); coeff = q.modInverse(p); break; } } canEncrypt = n != 0 && this.e != 0; canDecrypt = canEncrypt && d != 0; }
public void TestGCD() { BigInteger bi1, bi2; int val1, val2; Random rand = new Random(); for (int i = 0; i < 100; i++) { val1 = rand.Next(); val2 = rand.Next(); bi1 = new BigInteger(val1); bi2 = new BigInteger(val2); Assert.AreEqual(GCD(val1, val2), bi1.gcd(bi2)); Assert.AreEqual(bi1.gcd(bi2), bi2.gcd(bi1)); } bi1 = new BigInteger("23479237493274982374983729847392847928347982374983795749598459895479485945984598949799486346632864782376823768236482364862624623864", 10); Assert.AreEqual(bi1, bi1.gcd(0)); Assert.AreEqual(1, bi1.gcd(1)); Assert.AreEqual(1, bi1.gcd(-1)); bi2 = new BigInteger("3294823794872398749835984985798575794759834759347593475983475983475949530439", 10); Assert.AreEqual(1, bi2.gcd(bi1)); bi2 = new BigInteger(2839392890293); Assert.AreEqual(1, bi1.gcd(bi2)); bi1 = new BigInteger("4951870740493721842141443925495861658429914087387823242795626852731793395869583123486587097315594003541474986183101777497261582259131154425", 10); bi2 = new BigInteger(25208378845650); Assert.AreEqual(12604189422825, bi2.gcd(bi1)); Assert.AreEqual(bi1.gcd(bi2), bi2.gcd(bi1)); bi2 = -bi2; Assert.AreEqual(12604189422825, bi2.gcd(bi1)); Assert.AreEqual(bi1.gcd(bi2), bi2.gcd(bi1)); }
public static bool RabinMillerTest(BigInteger bi, ConfidenceFactor confidence) { int sPPRounds = GetSPPRounds(bi, confidence); BigInteger bigInteger = bi - 1; int num = bigInteger.LowestSetBit(); BigInteger exp = bigInteger >> num; int bits = bi.bitCount(); BigInteger bigInteger2 = null; RandomNumberGenerator rng = RandomNumberGenerator.Create(); BigInteger.ModulusRing modulusRing = new BigInteger.ModulusRing(bi); for (int i = 0; i < sPPRounds; i++) { do { bigInteger2 = BigInteger.genRandom(bits, rng); }while (!(bigInteger2 > 1) || !(bigInteger2 < bi)); if (bigInteger2.gcd(bi) != 1u) { return(false); } BigInteger bigInteger3 = modulusRing.Pow(bigInteger2, exp); if (bigInteger3 == 1u) { continue; } bool flag = false; for (int j = 0; j < num; j++) { if (bigInteger3 == bigInteger) { flag = true; break; } bigInteger3 = bigInteger3 * bigInteger3 % bi; } if (!flag) { return(false); } } return(true); }
private static void Process(int C, TextReader reader, TextWriter writer) { string[] s = reader.ReadLine().Split(' '); int N = int.Parse(s[0]); BigInteger[] t = new BigInteger[N]; for (int i = 0; i < N; i++) { t[i] = new BigInteger(s[i + 1]); } Array.Sort(t, new comparer()); BigInteger[] delta = new BigInteger[N - 1]; for (int i = 1; i < N; i++) { delta[i - 1] = t[i].subtract(t[i - 1]); } BigInteger m = delta[0]; for (int i = 1; i < N - 1; i++) { m = m.gcd(delta[i]); } BigInteger[] d = t[0].divideAndRemainder(m); //BigInteger zero = new BigInteger("0"); if (m.subtract(d[1]) == m) { Console.WriteLine("Case #{0}: {1}", C, 0); writer.WriteLine("Case #{0}: {1}", C, 0); } else { Console.WriteLine("Case #{0}: {1}", C, m.subtract(d[1])); writer.WriteLine("Case #{0}: {1}", C, m.subtract(d[1])); } }
public RSA(BigInteger e, BigInteger p, BigInteger q) { this.e = e; this.p = p; this.q = q; BigInteger phi = (this.p - 1) * (this.q - 1); if (phi.gcd(this.e) == 1) { this.n = this.p * this.q; this.d = this.e.modInverse(phi); this.dmp1 = this.d % (this.p - 1); this.dmq1 = this.d % (this.q - 1); this.coeff = this.q.modInverse(this.p); } this.canEncrypt = this.n != 0 && this.e != 0; this.canDecrypt = this.canEncrypt && this.d != 0; }
public RSA(BigInteger e, BigInteger p, BigInteger q) { this.e = e; this.p = p; this.q = q; BigInteger phi = (this.p - 1) * (this.q - 1); if (phi.gcd(this.e) == 1) { n = this.p * this.q; d = this.e.modInverse(phi); dmp1 = d % (this.p - 1); dmq1 = d % (this.q - 1); coeff = this.q.modInverse(this.p); } canEncrypt = n != 0 && this.e != 0; canDecrypt = canEncrypt && d != 0; }
public rsa() { Random rn = new Random(); p = BigInteger.genPseudoPrime(521, 100, rn); q = BigInteger.genPseudoPrime(521, 100, rn); n = new BigInteger(p * q); BigInteger o = new BigInteger((p - 1) * (q - 1)); int eb=0; do { //eb = rn.Next(2, o.bitCount()); //e = BigInteger.genPseudoPrime(eb, 100, rn); e = new BigInteger(65537); } while (e > o || e.gcd(o) != new BigInteger(1)); d = new BigInteger(e.modInverse(o)); }
public rsa() { Random rn = new Random(); p = BigInteger.genPseudoPrime(520, 100, rn); q = BigInteger.genPseudoPrime(520, 100, rn); n = new BigInteger(p * q); BigInteger o = new BigInteger((p - 1) * (q - 1)); int eb = 0; do { //eb = rn.Next(2, o.bitCount()); //e = BigInteger.genPseudoPrime(eb, 100, rn); e = new BigInteger(65537); }while (e > o || e.gcd(o) != new BigInteger(1)); d = new BigInteger(e.modInverse(o)); }
//*********************************************************************** // Probabilistic prime test based on Solovay-Strassen (Euler Criterion) // // p is probably prime if for any a < p (a is not multiple of p), // a^((p-1)/2) mod p = J(a, p) // // where J is the Jacobi symbol. // // Otherwise, p is composite. // // Returns // ------- // True if "this" is a Euler pseudoprime to randomly chosen // bases. The number of chosen bases is given by the "confidence" // parameter. // // False if "this" is definitely NOT prime. // //*********************************************************************** public bool SolovayStrassenTest(int confidence) { BigInteger thisVal; if((this.data[maxLength-1] & 0x80000000) != 0) // negative thisVal = -this; else thisVal = this; if(thisVal.dataLength == 1) { // test small numbers if(thisVal.data[0] == 0 || thisVal.data[0] == 1) return false; else if(thisVal.data[0] == 2 || thisVal.data[0] == 3) return true; } if((thisVal.data[0] & 0x1) == 0) // even numbers return false; int bits = thisVal.bitCount(); BigInteger a = new BigInteger(); BigInteger p_sub1 = thisVal - 1; BigInteger p_sub1_shift = p_sub1 >> 1; Random rand = new Random(); for(int round = 0; round < confidence; round++) { bool done = false; while(!done) // generate a < n { int testBits = 0; // make sure "a" has at least 2 bits while(testBits < 2) testBits = (int)(rand.NextDouble() * bits); a.genRandomBits(testBits, rand); int byteLen = a.dataLength; // make sure "a" is not 0 if(byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) done = true; } // check whether a factor exists (fix for version 1.03) BigInteger gcdTest = a.gcd(thisVal); if(gcdTest.dataLength == 1 && gcdTest.data[0] != 1) return false; // calculate a^((p-1)/2) mod p BigInteger expResult = a.modPow(p_sub1_shift, thisVal); if(expResult == p_sub1) expResult = -1; // calculate Jacobi symbol BigInteger jacob = Jacobi(a, thisVal); //Console.WriteLine("a = " + a.ToString(10) + " b = " + thisVal.ToString(10)); //Console.WriteLine("expResult = " + expResult.ToString(10) + " Jacob = " + jacob.ToString(10)); // if they are different then it is not prime if(expResult != jacob) return false; } return true; }
//*********************************************************************** // Probabilistic prime test based on Rabin-Miller's // // for any p > 0 with p - 1 = 2^s * t // // p is probably prime (strong pseudoprime) if for any a < p, // 1) a^t mod p = 1 or // 2) a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 // // Otherwise, p is composite. // // Returns // ------- // True if "this" is a strong pseudoprime to randomly chosen // bases. The number of chosen bases is given by the "confidence" // parameter. // // False if "this" is definitely NOT prime. // //*********************************************************************** public bool RabinMillerTest(int confidence) { BigInteger thisVal; if((this.data[maxLength-1] & 0x80000000) != 0) // negative thisVal = -this; else thisVal = this; if(thisVal.dataLength == 1) { // test small numbers if(thisVal.data[0] == 0 || thisVal.data[0] == 1) return false; else if(thisVal.data[0] == 2 || thisVal.data[0] == 3) return true; } if((thisVal.data[0] & 0x1) == 0) // even numbers return false; // calculate values of s and t BigInteger p_sub1 = thisVal - (new BigInteger(1)); int s = 0; for(int index = 0; index < p_sub1.dataLength; index++) { uint mask = 0x01; for(int i = 0; i < 32; i++) { if((p_sub1.data[index] & mask) != 0) { index = p_sub1.dataLength; // to break the outer loop break; } mask <<= 1; s++; } } BigInteger t = p_sub1 >> s; int bits = thisVal.bitCount(); BigInteger a = new BigInteger(); Random rand = new Random(); for(int round = 0; round < confidence; round++) { bool done = false; while(!done) // generate a < n { int testBits = 0; // make sure "a" has at least 2 bits while(testBits < 2) testBits = (int)(rand.NextDouble() * bits); a.genRandomBits(testBits, rand); int byteLen = a.dataLength; // make sure "a" is not 0 if(byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) done = true; } // check whether a factor exists (fix for version 1.03) BigInteger gcdTest = a.gcd(thisVal); if(gcdTest.dataLength == 1 && gcdTest.data[0] != 1) return false; BigInteger b = a.modPow(t, thisVal); /* Console.WriteLine("a = " + a.ToString(10)); Console.WriteLine("b = " + b.ToString(10)); Console.WriteLine("t = " + t.ToString(10)); Console.WriteLine("s = " + s); */ bool result = false; if(b.dataLength == 1 && b.data[0] == 1) // a^t mod p = 1 result = true; for(int j = 0; result == false && j < s; j++) { if(b == p_sub1) // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 { result = true; break; } b = (b * b) % thisVal; } if(result == false) return false; } return true; }
//*********************************************************************** // Probabilistic prime test based on Fermat's little theorem // // for any a < p (p does not divide a) if // a^(p-1) mod p != 1 then p is not prime. // // Otherwise, p is probably prime (pseudoprime to the chosen base). // // Returns // ------- // True if "this" is a pseudoprime to randomly chosen // bases. The number of chosen bases is given by the "confidence" // parameter. // // False if "this" is definitely NOT prime. // // Note - this method is fast but fails for Carmichael numbers except // when the randomly chosen base is a factor of the number. // //*********************************************************************** public bool FermatLittleTest(int confidence) { BigInteger thisVal; if((this.data[maxLength-1] & 0x80000000) != 0) // negative thisVal = -this; else thisVal = this; if(thisVal.dataLength == 1) { // test small numbers if(thisVal.data[0] == 0 || thisVal.data[0] == 1) return false; else if(thisVal.data[0] == 2 || thisVal.data[0] == 3) return true; } if((thisVal.data[0] & 0x1) == 0) // even numbers return false; int bits = thisVal.bitCount(); BigInteger a = new BigInteger(); BigInteger p_sub1 = thisVal - (new BigInteger(1)); Random rand = new Random(); for(int round = 0; round < confidence; round++) { bool done = false; while(!done) // generate a < n { int testBits = 0; // make sure "a" has at least 2 bits while(testBits < 2) testBits = (int)(rand.NextDouble() * bits); a.genRandomBits(testBits, rand); int byteLen = a.dataLength; // make sure "a" is not 0 if(byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) done = true; } // check whether a factor exists (fix for version 1.03) BigInteger gcdTest = a.gcd(thisVal); if(gcdTest.dataLength == 1 && gcdTest.data[0] != 1) return false; // calculate a^(p-1) mod p BigInteger expResult = a.modPow(p_sub1, thisVal); int resultLen = expResult.dataLength; // is NOT prime is a^(p-1) mod p != 1 if(resultLen > 1 || (resultLen == 1 && expResult.data[0] != 1)) { //Console.WriteLine("a = " + a.ToString()); return false; } } return true; }
public bool RabinMillerTest(int confidence) { BigInteger thisVal; if ((this.data[maxLength - 1] & 0x80000000) != 0) // negative { thisVal = -this; } else { thisVal = this; } if (thisVal.dataLength == 1) { // test small numbers if (thisVal.data[0] == 0 || thisVal.data[0] == 1) { return(false); } else if (thisVal.data[0] == 2 || thisVal.data[0] == 3) { return(true); } } if ((thisVal.data[0] & 0x1) == 0) // even numbers { return(false); } // calculate values of s and t BigInteger p_sub1 = thisVal - (new BigInteger(1)); int s = 0; for (int index = 0; index < p_sub1.dataLength; index++) { uint mask = 0x01; for (int i = 0; i < 32; i++) { if ((p_sub1.data[index] & mask) != 0) { index = p_sub1.dataLength; // to break the outer loop break; } mask <<= 1; s++; } } BigInteger t = p_sub1 >> s; int bits = thisVal.bitCount(); BigInteger a = new BigInteger(); Random rand = new Random(); for (int round = 0; round < confidence; round++) { bool done = false; while (!done) // generate a < n { int testBits = 0; // make sure "a" has at least 2 bits while (testBits < 2) { testBits = (int)(rand.NextDouble() * bits); } a.genRandomBits(testBits, rand); int byteLen = a.dataLength; // make sure "a" is not 0 if (byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) { done = true; } } // check whether a factor exists (fix for version 1.03) BigInteger gcdTest = a.gcd(thisVal); if (gcdTest.dataLength == 1 && gcdTest.data[0] != 1) { return(false); } BigInteger b = a.modPow(t, thisVal); bool result = false; if (b.dataLength == 1 && b.data[0] == 1) // a^t mod p = 1 { result = true; } for (int j = 0; result == false && j < s; j++) { if (b == p_sub1) // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 { result = true; break; } b = (b * b) % thisVal; } if (result == false) { return(false); } } return(true); }
private BigInteger lsm(BigInteger x, BigInteger y) { return(x.multiply(y).divide(x.gcd(y))); }
// Generate an RSA keypair // Popular exponents are 3, 17 and 65537; the bigger it is, the slower encryption becomes public void GenerateKeyPair(int exponent) { for ( ; ;) { BigInteger E = exponent; Random rand = new Random(); int nbits = this.keylen * 8 / 2; // so that P * Q < N // Find primes P and Q with Q < P so that: // GCD (E, (P - 1) * (Q - 1)) == 1 BigInteger P = null; BigInteger Q = null; BigInteger Pmin1 = null; BigInteger Qmin1 = null; BigInteger H = null; BigInteger GCD = null; do { P = BigInteger.genPseudoPrime(nbits, 20, rand); Q = BigInteger.genPseudoPrime(nbits, 20, rand); if (P == Q) { continue; } if (P < Q) { BigInteger swap = P; P = Q; Q = swap; } Pmin1 = P - 1; Qmin1 = Q - 1; H = Pmin1 * Qmin1; GCD = H.gcd(E); }while (GCD != 1); // N = P * Q // D = E^-1 mod ((P - 1) * (Q - 1)) // DP = D mod (P - 1) // DQ = D mod (Q - 1) // QP = Q^-1 mod P this.N = P * Q; this.E = E; this.P = P; this.Q = Q; this.D = E.modInverse(H); this.DP = D.modPow(1, Pmin1); this.DQ = D.modPow(1, Qmin1); this.QP = Q.modInverse(P); // Check that this key actually works! // BigInteger.genPseudoPrime (rarely) returns a non-prime byte [] encrypt_me = new byte [this.keylen - 1]; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); rng.GetBytes(encrypt_me); encrypt_me = pad_bytes(encrypt_me, this.keylen); // ensure msg < modulus byte [] encrypted = DoPublic(encrypt_me); byte [] decrypted = DoPrivate(encrypted); if (compare_bytes(encrypt_me, 0, decrypted, 0, this.keylen)) { return; } } }
private void BuildKeys() { //Make a call to Generate_Primes. BigInteger P = new BigInteger(m_RSAParams.P); BigInteger Q = new BigInteger(m_RSAParams.Q); //Exponent. This needs to be a number such that the //GCD of the Exponent and Phi is 1. The larger the exp. //the more secure, but it increases encryption time. BigInteger E = new BigInteger(m_RSAParams.E); BigInteger N = new BigInteger(0); //Public and Private Key Part (Modulus) BigInteger D = new BigInteger(0); //Private Key Part BigInteger DP = new BigInteger(0); BigInteger DQ = new BigInteger(0); BigInteger IQ = new BigInteger(0); BigInteger Phi = new BigInteger(0); //Phi //Make sure P is greater than Q, swap if less. if (P < Q) { BigInteger biTmp = P; P = Q; Q = biTmp; biTmp = null; m_RSAParams.P = P.getBytesRaw(); m_RSAParams.Q = Q.getBytesRaw(); } //Calculate the modulus N = P * Q; m_RSAParams.N = N.getBytesRaw(); //Calculate Phi Phi = (P - 1) * (Q - 1); m_RSAParams.Phi = Phi.getBytesRaw(); //Make sure our Exponent will work, or choose a larger one. while (Phi.gcd(E) > 1) { //If the GCD is greater than 1 iterate the Exponent E = E + 2; //Also make sure the Exponent is prime. while (!E.isProbablePrime()) { E = E + 2; } } //Make sure the params contain the updated E value m_RSAParams.E = E.getBytesRaw(); //Calculate the private exponent D. D = E.modInverse(Phi); m_RSAParams.D = D.getBytesRaw(); //Calculate DP DP = E.modInverse(P - 1); m_RSAParams.DP = DP.getBytesRaw(); //Calculate DQ DQ = E.modInverse(Q - 1); m_RSAParams.DQ = DQ.getBytesRaw(); //Calculate InverseQ IQ = Q.modInverse(P); m_RSAParams.IQ = IQ.getBytesRaw(); m_KeyLoaded = true; m_isBusy = false; OnKeysGenerated(this); }
private bool LucasStrongTestHelper(BigInteger thisVal) { // Do the test (selects D based on Selfridge) // Let D be the first element of the sequence // 5, -7, 9, -11, 13, ... for which J(D,n) = -1 // Let P = 1, Q = (1-D) / 4 long D = 5, sign = -1, dCount = 0; bool done = false; while(!done) { int Jresult = BigInteger.Jacobi(D, thisVal); if(Jresult == -1) done = true; // J(D, this) = 1 else { if(Jresult == 0 && Math.Abs(D) < thisVal) // divisor found return false; if(dCount == 20) { // check for square BigInteger root = thisVal.sqrt(); if(root * root == thisVal) return false; } //Console.WriteLine(D); D = (Math.Abs(D) + 2) * sign; sign = -sign; } dCount++; } long Q = (1 - D) >> 2; /* Console.WriteLine("D = " + D); Console.WriteLine("Q = " + Q); Console.WriteLine("(n,D) = " + thisVal.gcd(D)); Console.WriteLine("(n,Q) = " + thisVal.gcd(Q)); Console.WriteLine("J(D|n) = " + BigInteger.Jacobi(D, thisVal)); */ BigInteger p_add1 = thisVal + 1; int s = 0; for(int index = 0; index < p_add1.dataLength; index++) { uint mask = 0x01; for(int i = 0; i < 32; i++) { if((p_add1.data[index] & mask) != 0) { index = p_add1.dataLength; // to break the outer loop break; } mask <<= 1; s++; } } BigInteger t = p_add1 >> s; // calculate constant = b^(2k) / m // for Barrett Reduction BigInteger constant = new BigInteger(); int nLen = thisVal.dataLength << 1; constant.data[nLen] = 0x00000001; constant.dataLength = nLen + 1; constant = constant / thisVal; BigInteger[] lucas = LucasSequenceHelper(1, Q, t, thisVal, constant, 0); bool isPrime = false; if((lucas[0].dataLength == 1 && lucas[0].data[0] == 0) || (lucas[1].dataLength == 1 && lucas[1].data[0] == 0)) { // u(t) = 0 or V(t) = 0 isPrime = true; } for(int i = 1; i < s; i++) { if(!isPrime) { // doubling of index lucas[1] = thisVal.BarrettReduction(lucas[1] * lucas[1], thisVal, constant); lucas[1] = (lucas[1] - (lucas[2] << 1)) % thisVal; //lucas[1] = ((lucas[1] * lucas[1]) - (lucas[2] << 1)) % thisVal; if((lucas[1].dataLength == 1 && lucas[1].data[0] == 0)) isPrime = true; } lucas[2] = thisVal.BarrettReduction(lucas[2] * lucas[2], thisVal, constant); //Q^k } if(isPrime) // additional checks for composite numbers { // If n is prime and gcd(n, Q) == 1, then // Q^((n+1)/2) = Q * Q^((n-1)/2) is congruent to (Q * J(Q, n)) mod n BigInteger g = thisVal.gcd(Q); if(g.dataLength == 1 && g.data[0] == 1) // gcd(this, Q) == 1 { if((lucas[2].data[maxLength-1] & 0x80000000) != 0) lucas[2] += thisVal; BigInteger temp = (Q * BigInteger.Jacobi(Q, thisVal)) % thisVal; if((temp.data[maxLength-1] & 0x80000000) != 0) temp += thisVal; if(lucas[2] != temp) isPrime = false; } } return isPrime; }
/// <summary> /// Creates a new RSA secret key and returns it as a /// 2 dimensional array of biginteger. return[0] holds /// the public values of the key and return[1] all the /// secret values. /// </summary> /// <remarks> /// Creates a new RSA secret key and returns it as a /// 2 dimensional array of biginteger. return[0] holds /// the public values of the key and return[1] all the /// secret values.<br></br> /// The order of the public components is n, e. /// The order of the secret components is d, p, /// q and u. /// </remarks> /// <param name="nbits">The size of the key in bits.</param> /// <returns>A new RSA secret key as a /// 2 dimensional array of biginteger. return[0] holds /// the public values of the key and return[1] all the /// secret values.<br></br> /// The order of the public components is n, e. /// The order of the secret components is d, p, /// q and u.</returns> /// <exception cref="System.ArgumentException">Throws an /// Argumentexception if the keysize is not between 768 /// and 4096 bits.</exception> public override BigInteger[][] Generate(int nbits) { BigInteger p, q; /* the two primes */ BigInteger d; /* the private key */ BigInteger u; BigInteger t1, t2; BigInteger n = new BigInteger(); /* the public key */ BigInteger e; /* the exponent */ BigInteger phi; /* helper: (p-1)(q-1) */ BigInteger g; BigInteger f; Random rand = new Random(); if ((nbits < 768) || (nbits > 4096)) { throw new ArgumentException("Only keysizes betwen 768 and 4096 bit are allowed!"); } /* make sure that nbits is even so that we generate p, q of equal size */ if ((nbits & 1) == 1) { nbits++; } do { /* select two (very secret) primes */ p = new BigInteger(); q = new BigInteger(); p = BigInteger.genPseudoPrime(nbits / 2); q = BigInteger.genPseudoPrime(nbits / 2); /* p shall be smaller than q (for calc of u)*/ if (q > p) { BigInteger tmp = p; p = q; q = tmp; } /* calculate the modulus */ n = p * q; } while (n.bitCount() != nbits); /* calculate Euler totient: phi = (p-1)(q-1) */ t1 = p - new BigInteger(1); t2 = q - new BigInteger(1); phi = t1 * t2; g = t1.gcd(t2); f = phi / g; /* find an public exponent. * We use 41 as this is quite fast and more secure than the * commonly used 17. */ e = new BigInteger(41); t1 = e.gcd(phi); if (t1 != new BigInteger(1)) { e = new BigInteger(257); t1 = e.gcd(phi); if (t1 != new BigInteger(1)) { e = new BigInteger(65537); t1 = e.gcd(phi); /* (while gcd is not 1) */ while (t1 != new BigInteger(1)) { e += 2; t1 = e.gcd(phi); } } } /* calculate the secret key d = e^1 mod phi */ d = e.modInverse(f); /* calculate the inverse of p and q (used for chinese remainder theorem)*/ u = p.modInverse(q); RSA_Secret_Key sk = new RSA_Secret_Key(); sk.n = n; sk.e = e; sk.p = p; sk.q = q; sk.d = d; sk.u = u; this.biGeneratedKey = ParseSecretKey(sk); return(this.biGeneratedKey); /* now we can test our keys (this should never fail!) */ // test_keys( sk, nbits - 64 ); }
public void GcdPP() { Expect(A.gcd(B), aGcdB); }
//*********************************************************************** // Generates a random number with the specified number of bits such // that gcd(number, this) = 1 //*********************************************************************** public BigInteger genCoPrime(int bits, Random rand) { bool done = false; BigInteger result = new BigInteger(); while(!done) { result.genRandomBits(bits, rand); //Console.WriteLine(result.ToString(16)); // gcd test BigInteger g = result.gcd(this); if(g.dataLength == 1 && g.data[0] == 1) done = true; } return result; }
public static RSAKeyPair GenerateNew(int bits, Random rnd) { BigInteger one = new BigInteger(1); BigInteger p = null; BigInteger q = null; BigInteger t = null; BigInteger p_1 = null; BigInteger q_1 = null; BigInteger phi = null; BigInteger G = null; BigInteger F = null; BigInteger e = null; BigInteger d = null; BigInteger u = null; BigInteger n = null; bool finished = false; while (!finished) { p = BigInteger.genPseudoPrime(bits / 2, 64, rnd); q = BigInteger.genPseudoPrime(bits - (bits / 2), 64, rnd); if (p == 0) { continue; } else if (q < p) { t = q; q = p; p = t; } t = p.gcd(q); if (t != one) { continue; } p_1 = p - one; q_1 = q - one; phi = p_1 * q_1; G = p_1.gcd(q_1); F = phi / G; e = one << 5; e = e - one; do { e = e + (one + one); t = e.gcd(phi); } while(t != one); // !!! d = e.modInverse(F); d = e.modInverse(phi); n = p * q; u = p.modInverse(q); finished = true; } return(new RSAKeyPair(e, d, n, u, p, q)); }
public static bool RabinMillerTest(this BigInteger thisVal, int confidence) { byte[] bytes = thisVal.ToUnsignedByteArray(); if (bytes.Length == 1) { // test small numbers if (bytes[0] == 0 || bytes[0] == 1) { return(false); } else if (bytes[0] == 2 || bytes[0] == 3) { return(true); } } if ((bytes[0] & 0x1) == 0) // even numbers { return(false); } // calculate values of s and t BigInteger p_sub1 = thisVal - (new BigInteger(1)); byte[] p_sub1Bytes = p_sub1.ToUnsignedByteArray(); int s = 0; for (int index = 0; index < p_sub1Bytes.Length; index++) { uint mask = 0x01; for (int i = 0; i < 32; i++) { if ((p_sub1Bytes[index] & mask) != 0) { index = p_sub1Bytes.Length; // to break the outer loop break; } mask <<= 1; s++; } } BigInteger t = p_sub1 >> s; int bits = thisVal.BitCount(); BigInteger a = new BigInteger(); Random rand = new Random(); for (int round = 0; round < confidence; round++) { bool done = false; while (!done) // generate a < n { int testBits = 0; // make sure "a" has at least 2 bits while (testBits < 2) { testBits = (int)(rand.NextDouble() * bits); } a = Create(testBits, rand); byte[] aBytes = a.ToUnsignedByteArray(); // make sure "a" is not 0 if (aBytes.Length > 1 || (aBytes.Length == 1 && aBytes[0] != 1)) { done = true; } } // check whether a factor exists (fix for version 1.03) BigInteger gcdTest = a.gcd(thisVal); byte[] gcdBytes = gcdTest.ToUnsignedByteArray(); if (gcdBytes.Length == 1 && gcdBytes[0] != 1) { return(false); } BigInteger b = a.modPow(t, thisVal); byte[] bBytes = b.ToUnsignedByteArray(); bool result = false; if (bBytes.Length == 1 && bBytes[0] == 1) // a^t mod p = 1 { result = true; } for (int j = 0; result == false && j < s; j++) { if (b == p_sub1) // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 { result = true; break; } b = (b * b) % thisVal; } if (result == false) { return(false); } } return(true); }
public static RSAPrivateCrtKey generateKey(int bits, BigInteger e, RandomNumberGenerator secRand) { BigInteger p = null; BigInteger q = null; BigInteger t = null; BigInteger phi = null; BigInteger d = null; BigInteger u = null; BigInteger n = null; bool finished = false; int pbits = (bits + 1) / 2; int qbits = bits - pbits; while (!finished) { p = new BigInteger(pbits, 25, secRand); q = new BigInteger(qbits, 25, secRand); if (p == q) { continue; } else if (p == q) { t = q; q = p; p = t; } if (!p.isProbablePrime(25)) { continue; } if (!q.isProbablePrime(25)) { continue; } t = p.gcd(q); if (t.compareTo(BigInteger.ONE) != 0) { continue; } n = p.multiply(q); if (n.bitLength() != bits) { continue; } phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE)); d = e.modInverse(phi); u = q.modInverse(p); finished = true; } return(new RSAPrivateCrtKey(n, e, d, p, q, RSA.getPrimeExponent(d, p), RSA.getPrimeExponent(d, q), u)); }