gcd() public method

public gcd ( BigInteger bi ) : BigInteger
bi BigInteger
return BigInteger
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #4
0
        /// <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);
        }
Beispiel #6
0
        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);
        }
Beispiel #8
0
        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);
            }
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        private void CheckX()
        {
            x = BigInteger.genPseudoPrime(128, 100, new Random());

            while (N.gcd(x) != 1)
            {
                x = BigInteger.genPseudoPrime(128, 100, new Random());
            }
        }
Beispiel #11
0
        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));
        }
Beispiel #12
0
        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));
        }
Beispiel #13
0
        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));
        }
Beispiel #14
0
        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;
        }
Beispiel #15
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;
        }
Beispiel #16
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));
        }
Beispiel #17
0
        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);
        }
Beispiel #18
0
        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]));
            }
        }
Beispiel #19
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)
            {
                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;
        }
Beispiel #20
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;
        }
Beispiel #21
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));
        }
Beispiel #22
0
        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);
    }
Beispiel #27
0
 private BigInteger lsm(BigInteger x, BigInteger y)
 {
     return(x.multiply(y).divide(x.gcd(y)));
 }
Beispiel #28
0
// 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;
        }
Beispiel #31
0
        /// <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 );
        }
Beispiel #32
0
 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;
        }
Beispiel #34
0
        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);
        }
Beispiel #36
0
        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));
        }