コード例 #1
0
        /// <summary>
        /// Creates a pair of two primes which, being multiplied one by another,
        /// produce a public key of desired length for the RSA algorithm.
        /// </summary>
        /// <typeparam name="B">An implementation of <c>IBase</c> interface which specifies the digit base of <c>LongInt&lt;<typeparamref name="B"/>&gt;</c> numbers.</typeparam>
        /// <param name="digits">The desired number of digits in the public key.</param>
        /// <param name="randomGenerator">A random generator for long integer numbers.</param>
        /// <param name="primalityTest"></param>
        /// <returns></returns>
        public static Point <LongInt <B> > GetKey <B>(int digits, IRandomBounded <LongInt <B> > randomGenerator = null, Func <LongInt <B>, bool> primalityTest = null) where B : IBase, new()
        {
            Contract.Requires <ArgumentOutOfRangeException>(digits > 1, "The amount of digits in the key should be more than 1.");

            /*
             * Contract.Ensures(
             *  (Contract.Result<Point<LongInt<B>>>().X * Contract.Result<Point<LongInt<B>>>().Y)
             *  .Length == digits);
             */

            long bits = (long)Math.Ceiling(Math.Log(LongInt <B> .BASE, 2));   // сколько бит занимает BASE

            if (randomGenerator == null)
            {
                randomGenerator = new RandomLongIntModular <B>(new RandomMersenneTwister());
            }

            if (primalityTest == null)
            {
                primalityTest = (x => __isPrimeOptimized(x));
            }

            LongInt <B>
            firstPrime,
                secondPrime;

            int half = digits / 2;

            // На текущий момент длина ключа может оказаться МЕНЬШЕ
            // запланированной. Сделать так, чтобы она всегда была одна.
            // Нижеуказанный генератор тоже снести.

            IRandomBoundedUnbounded <int> tmp = new RandomCryptographic();

            do
            {
                firstPrime = new LongInt <B>(half, tmp, false);
            }while (!primalityTest(firstPrime));

            do
            {
                secondPrime = new LongInt <B>(digits - half, tmp, false);
            }while (!primalityTest(secondPrime));

            return(new Point <LongInt <B> >(firstPrime, secondPrime));
        }
コード例 #2
0
        /// <summary>
        /// Hidden method - tries the first 100 primes to test divisibility.
        /// If not divisible - proceeds with Miller-Rabin.
        /// </summary>
        private static bool __isPrimeOptimized <B>(LongInt <B> number)
            where B : IBase, new()
        {
            RandomMersenneTwister    gen  = new RandomMersenneTwister();
            RandomLongIntModular <B> lgen = new RandomLongIntModular <B>(gen);

            foreach (int prime in firstPrimes)
            {
                if (number % prime == 0)
                {
                    return(false);
                }
            }

            if (PrimalityTests.IsPrime_MillerRabin(number, lgen, number.LengthInBinaryPlaces) < 1)
            {
                return(true);
            }

            return(false);
        }