Exemple #1
0
        /// <summary>
        ///     Probabilistic prime test based on Rabin-Miller's test
        /// </summary>
        /// <param name="n" 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 n, ConfidenceFactor confidence)
        {
            int bits = n.BitCount ();
            int t = GetSPPRounds (bits, confidence);

            // n - 1 == 2^s * r, r is odd
            BigInteger n_minus_1 = n - 1;
            int s = n_minus_1.LowestSetBit ();
            BigInteger r = n_minus_1 >> s;

            BigInteger.ModulusRing mr = new BigInteger.ModulusRing (n);

            // Applying optimization from HAC section 4.50 (base == 2)
            // not a really random base but an interesting (and speedy) one
            BigInteger y = null;
            // FIXME - optimization disable for small primes due to bug #81857
            if (n.BitCount () > 100)
                y = mr.Pow (2, r);

            // still here ? start at round 1 (round 0 was a == 2)
            for (int round = 0; round < t; round++) {

                if ((round > 0) || (y == null)) {
                    BigInteger a = null;

                    // check for 2 <= a <= n - 2
                    // ...but we already did a == 2 previously as an optimization
                    do {
                        a = BigInteger.GenerateRandom (bits);
                    } while ((a <= 2) && (a >= n_minus_1));

                    y = mr.Pow (a, r);
                }

                if (y == 1)
                    continue;

                for (int j = 0; ((j < s) && (y != n_minus_1)); j++) {

                    y = mr.Pow (y, 2);
                    if (y == 1)
                        return false;
                }

                if (y != n_minus_1)
                    return false;
            }
            return true;
        }
Exemple #2
0
		private static int GetSPPRounds(BigInteger bi, ConfidenceFactor confidence)
		{
			int bc = bi.BitCount();

			int Rounds;

			// Data from HAC, 4.49
			if (bc <= 100) Rounds = 27;
			else if (bc <= 150) Rounds = 18;
			else if (bc <= 200) Rounds = 15;
			else if (bc <= 250) Rounds = 12;
			else if (bc <= 300) Rounds = 9;
			else if (bc <= 350) Rounds = 8;
			else if (bc <= 400) Rounds = 7;
			else if (bc <= 500) Rounds = 6;
			else if (bc <= 600) Rounds = 5;
			else if (bc <= 800) Rounds = 4;
			else if (bc <= 1250) Rounds = 3;
			else Rounds = 2;

			switch (confidence)
			{
				case ConfidenceFactor.ExtraLow:
					Rounds >>= 2;
					return Rounds != 0 ? Rounds : 1;
				case ConfidenceFactor.Low:
					Rounds >>= 1;
					return Rounds != 0 ? Rounds : 1;
				case ConfidenceFactor.Medium:
					return Rounds;
				case ConfidenceFactor.High:
					return Rounds << 1;
				case ConfidenceFactor.ExtraHigh:
					return Rounds << 2;
				case ConfidenceFactor.Provable:
					throw new Exception("The Rabin-Miller test can not be executed in a way such that its results are provable");
				default:
					throw new ArgumentOutOfRangeException("confidence");
			}
		}
		public static bool Test (BigInteger n, ConfidenceFactor confidence)
		{
			// Rabin-Miller fails with smaller primes (at least with our BigInteger code)
			if (n.BitCount () < 33)
				return SmallPrimeSppTest (n, confidence);
			else
				return RabinMillerTest (n, confidence);
		}
		/// <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;
			BigInteger.ModulusRing mr = new BigInteger.ModulusRing (bi);
			
			// Applying optimization from HAC section 4.50 (base == 2)
			// not a really random base but an interesting (and speedy) one
			BigInteger b = mr.Pow (2, t);
			if (b != 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)
					return false;
			}

			// still here ? start at round 1 (round 0 was a == 2)
			for (int round = 1; round < Rounds; round++) {
				while (true) {		           // generate a < n
					a = BigInteger.GenerateRandom (bits);

					// make sure "a" is not 0 (and not 2 as we have already tested that)
					if (a > 2 && a < bi)
						break;
				}

				if (a.GCD (bi) != 1)
					return false;

				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)
					return false;
			}
			return true;
		}
Exemple #5
0
        public override byte[] DecryptValue(byte[] rgb)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException("private key");
            }

            // decrypt operation is used for signature
            if (!keypairGenerated)
            {
                GenerateKeyPair();
            }

            BigInteger input = new BigInteger(rgb);
            BigInteger r     = null;

            // we use key blinding (by default) against timing attacks
            if (keyBlinding)
            {
                // x = (r^e * g) mod n
                // *new* random number (so it's timing is also random)
                r     = BigInteger.GenerateRandom(n.BitCount());
                input = r.ModPow(e, n) * input % n;
            }

            BigInteger output;

            // decrypt (which uses the private key) can be
            // optimized by using CRT (Chinese Remainder Theorem)
            if (isCRTpossible)
            {
                // m1 = c^dp mod p
                BigInteger m1 = input.ModPow(dp, p);
                // m2 = c^dq mod q
                BigInteger m2 = input.ModPow(dq, q);
                BigInteger h;
                if (m2 > m1)
                {
                    // thanks to benm!
                    h      = p - ((m2 - m1) * qInv % p);
                    output = m2 + q * h;
                }
                else
                {
                    // h = (m1 - m2) * qInv mod p
                    h = (m1 - m2) * qInv % p;
                    // m = m2 + q * h;
                    output = m2 + q * h;
                }
            }
            else
            {
                // m = c^d mod n
                output = input.ModPow(d, n);
            }

            if (keyBlinding)
            {
                // Complete blinding
                // x^e / r mod n
                output = output * r.ModInverse(n) % n;
                r.Clear();
            }

            byte[] result = output.GetBytes();
            // zeroize values
            input.Clear();
            output.Clear();
            return(result);
        }
Exemple #6
0
        void setStatusBar()
        {
            // create status line string
            string s     = textOutputPresentation.textBox.Text;
            string label = "";

            if (Input is string)
            {
                var value = Input as string;
                if (Regex.IsMatch(value, @"^-?\d+$"))
                {
                    try
                    {
                        input = BigInteger.Parse(value);
                    }
                    catch (Exception)
                    {
                        //wtf ?
                    }
                }
            }

            if (Input is Int16)
            {
                input = (BigInteger)(int)(Int16)Input;
            }
            else if (Input is Int32)
            {
                input = (BigInteger)(int)(Int32)Input;
            }

            if (Input is BigInteger)
            {
                int digits = 0;
                int bits;
                try
                {
                    BigInteger number = (BigInteger)input;
                    bits   = number.BitCount();
                    digits = BigInteger.Abs(number).ToString().Length;
                }
                catch (Exception)
                {
                    digits = 0;
                    bits   = 0;
                }
                string digitText = (digits == 1) ? Properties.Resources.Digit : Properties.Resources.Digits;
                string bitText   = (bits == 1) ? Properties.Resources.Bit : Properties.Resources.Bits;
                label = string.Format(" {0:#,0} {1}, {2} {3}", digits, digitText, bits, bitText);
                textOutputPresentation.labelBytes.Content = label;
                return;
            }

            if (settings.ShowChars)
            {
                int chars = (s == null) ? 0 : s.Length;
                //int bytes = Encoding.UTF8.GetBytes(textOutputPresentation.textBox.Text).Length;
                string entity = (chars == 1) ? Properties.Resources.Char : Properties.Resources.Chars;
                label += string.Format(" {0:#,0} " + entity, chars);
            }

            if (settings.ShowLines)
            {
                int lines = 0;
                if (s != null && s.Length > 0)
                {
                    lines = new Regex("\n", RegexOptions.Multiline).Matches(s).Count;
                    if (s[s.Length - 1] != '\n')
                    {
                        lines++;
                    }
                }
                string entity = (lines == 1) ? Properties.Resources.Line : Properties.Resources.Lines;
                if (label != "")
                {
                    label += ", ";
                }
                label += string.Format(" {0:#,0} " + entity, lines);
            }

            textOutputPresentation.labelBytes.Content = label;
        }
        private static int GetSPPRounds(BigInteger bi, ConfidenceFactor confidence)
        {
            int bc = bi.BitCount();

            int Rounds;

            // Data from HAC, 4.49
            if (bc <= 100)
            {
                Rounds = 27;
            }
            else if (bc <= 150)
            {
                Rounds = 18;
            }
            else if (bc <= 200)
            {
                Rounds = 15;
            }
            else if (bc <= 250)
            {
                Rounds = 12;
            }
            else if (bc <= 300)
            {
                Rounds = 9;
            }
            else if (bc <= 350)
            {
                Rounds = 8;
            }
            else if (bc <= 400)
            {
                Rounds = 7;
            }
            else if (bc <= 500)
            {
                Rounds = 6;
            }
            else if (bc <= 600)
            {
                Rounds = 5;
            }
            else if (bc <= 800)
            {
                Rounds = 4;
            }
            else if (bc <= 1250)
            {
                Rounds = 3;
            }
            else
            {
                Rounds = 2;
            }

            switch (confidence)
            {
            case ConfidenceFactor.ExtraLow:
                Rounds >>= 2;
                return(Rounds != 0 ? Rounds : 1);

            case ConfidenceFactor.Low:
                Rounds >>= 1;
                return(Rounds != 0 ? Rounds : 1);

            case ConfidenceFactor.Medium:
                return(Rounds);

            case ConfidenceFactor.High:
                return(Rounds << 1);

            case ConfidenceFactor.ExtraHigh:
                return(Rounds << 2);

            case ConfidenceFactor.Provable:
                throw new Exception("The Rabin-Miller test can not be executed in a way such that its results are provable");

            default:
                throw new ArgumentOutOfRangeException("confidence");
            }
        }
Exemple #8
0
 public void WriteBigIntWithBits(BigInteger bi)
 {
     WriteInt32(bi.BitCount());
     Write(bi.GetBytes());
 }
        // Modified from http://www.codeproject.com/Articles/2728/C-BigInteger-Class for use with the BigInteger
        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);
                }
                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 pSub1 = thisVal - (new BigInteger(1));

            byte[] pSub1Bytes = pSub1.ToUnsignedByteArray();
            int    s          = 0;

            for (var index = 0; index < pSub1Bytes.Length; index++)
            {
                uint mask = 0x01;

                for (var i = 0; i < 32; i++)
                {
                    if ((pSub1Bytes[index] & mask) != 0)
                    {
                        index = pSub1Bytes.Length;      // to break the outer loop
                        break;
                    }
                    mask <<= 1;
                    s++;
                }
            }

            BigInteger t = pSub1 >> s;

            int        bits = thisVal.BitCount();
            BigInteger a    = new BigInteger().MakePositive();
            var        rand = new Random();

            for (var round = 0; round < confidence; round++)
            {
                var 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 = CreateBigInteger(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();

                var result = bBytes.Length == 1 && bBytes[0] == 1;

                for (var j = 0; result == false && j < s; j++)
                {
                    if (b == pSub1)         // 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);
        }
Exemple #10
0
        protected void GenerateKeyPair()
        {
            // p and q values should have a length of half the strength in bits
            int        pbitlength = ((KeySize + 1) >> 1);
            int        qbitlength = (KeySize - pbitlength);
            const uint uint_e     = 65537; //duff before 17 now

            e = uint_e;                    // fixed

            // generate p, prime and (p-1) relatively prime to e
            for (;;)
            {
                p = BigInteger.GeneratePseudoPrime(pbitlength);
                if (p % uint_e != 1)
                {
                    break;
                }
            }
            // generate a modulus of the required length
            for (;;)
            {
                // generate q, prime and (q-1) relatively prime to e,
                // and not equal to p
                for (;;)
                {
                    q = BigInteger.GeneratePseudoPrime(qbitlength);
                    if ((q % uint_e != 1) && (p != q))
                    {
                        break;
                    }
                }

                // calculate the modulus
                n = p * q;
                if (n.BitCount() == KeySize)
                {
                    break;
                }

                // if we get here our primes aren't big enough, make the largest
                // of the two p and try again
                if (p < q)
                {
                    p = q;
                }
            }

            BigInteger pSub1 = (p - 1);
            BigInteger qSub1 = (q - 1);
            BigInteger phi   = pSub1 * qSub1;

            // calculate the private exponent
            d = e.ModInverse(phi);

            // calculate the CRT factors
            dp   = d % pSub1;
            dq   = d % qSub1;
            qInv = q.ModInverse(p);

            //duff add
            qP = q.ModInverse(p);
            pQ = p.ModInverse(q);

            keypairGenerated = true;
            isCRTpossible    = true;

            if (KeyGenerated != null)
            {
                KeyGenerated(this, null);
            }
        }
        /// <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;

            BigInteger.ModulusRing mr = new BigInteger.ModulusRing(bi);

            // Applying optimization from HAC section 4.50 (base == 2)
            // not a really random base but an interesting (and speedy) one
            BigInteger b = mr.Pow(2, t);

            if (b != 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)
                {
                    return(false);
                }
            }

            // still here ? start at round 1 (round 0 was a == 2)
            for (int round = 1; round < Rounds; round++)
            {
                while (true)                                       // generate a < n
                {
                    a = BigInteger.GenerateRandom(bits);

                    // make sure "a" is not 0 (and not 2 as we have already tested that)
                    if (a > 2 && a < bi)
                    {
                        break;
                    }
                }

                if (a.GCD(bi) != 1)
                {
                    return(false);
                }

                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)
                {
                    return(false);
                }
            }
            return(true);
        }
Exemple #12
0
        public override byte[] DecryptValue(byte[] rgb)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException("private key");
            }

            // decrypt operation is used for signature
            if (!keypairGenerated)
            {
                GenerateKeyPair();
            }

            BigInteger input = new BigInteger(rgb);
            BigInteger r     = null;

            // we use key blinding (by default) against timing attacks
            if (keyBlinding)
            {
                // x = (r^e * g) mod n
                // *new* random number (so it's timing is also random)
                r     = BigInteger.GenerateRandom(n.BitCount());
                input = r.ModPow(e, n) * input % n;
            }

            BigInteger output;

            // decrypt (which uses the private key) can be
            // optimized by using CRT (Chinese Remainder Theorem)
            if (isCRTpossible)
            {
                // m1 = c^dp mod p
                BigInteger m1 = input.ModPow(dp, p);
                // m2 = c^dq mod q
                BigInteger m2 = input.ModPow(dq, q);
                BigInteger h;
                if (m2 > m1)
                {
                    // thanks to benm!
                    h      = p - ((m2 - m1) * qInv % p);
                    output = m2 + q * h;
                }
                else
                {
                    // h = (m1 - m2) * qInv mod p
                    h = (m1 - m2) * qInv % p;
                    // m = m2 + q * h;
                    output = m2 + q * h;
                }
            }
            else if (!PublicOnly)
            {
                // m = c^d mod n
                output = input.ModPow(d, n);
            }
            else
            {
                throw new CryptographicException(Locale.GetText("Missing private key to decrypt value."));
            }

            if (keyBlinding)
            {
                // Complete blinding
                // x^e / r mod n
                output = output * r.ModInverse(n) % n;
                r.Clear();
            }

            // it's sometimes possible for the results to be a byte short
            // and this can break some software (see #79502) so we 0x00 pad the result
            byte[] result = GetPaddedValue(output, (KeySize >> 3));
            // zeroize values
            input.Clear();
            output.Clear();
            return(result);
        }