Ejemplo n.º 1
0
//***************************************************************************************
//***************************************************************************************
        /// <summary>
        /// Генерирует положительный  BigInt32. С большой вероятностью простое.+
        /// </summary>
        public static BigInt32 GetPseudoPrime(int bits, int confidence, Random rand)
        {
            BigInt32 result = new BigInt32();
            bool     done   = false;

            while (!done)
            {
                result.GetRandomBits(bits, rand);
                result.data[0] = 0x01;                     // делает сгенерированное число нечетным

                done = result.RabinMillerTest(confidence); //проверяем на простоту
            }
            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Конструктор. Генерирует и проверяет ключи.
        /// </summary>
        public RSA()
        {
            Random uy = new Random();

            const int KeyOFLenght = 128; // Длина p и q
            BigInt32  p           = BigInt32.GetPseudoPrime(KeyOFLenght, 10, uy);
            BigInt32  q           = BigInt32.GetPseudoPrime(KeyOFLenght - 1, 10, uy);

            //Console.WriteLine("q = {0}, p = {1}", q, p);
            n = p * q;
            //Console.WriteLine("n= {0}", n);
            p--;
            q--;
            BigInt32 w = p * q;                   // функция Эйлера

            e = new BigInt32();                   // открытый ключ

            do
            {
                e.GetRandomBits(KeyOFLenght * 2, uy);
            }while (BigInt32.NOD(e, w) != 1 && (e > n));

            d = BigInt32.Inverse(e, w);           // d - закрытый ключ (обратный к е по модулю w)
        }                                         // d - существует <=> НОД(e,w) = 1
Ejemplo n.º 3
0
        /// <summary>
        /// Вероятностный тест на простоту основанный на алгоритме Милера-Рабина
        /// Для любого p > 0, при p - 1 = 2^s * t
        /// p вероятно простое для любого  a < p,
        /// 1) a^t mod p = 1 или
        /// 2) a^((2^j)*t) mod p = p-1 для некоторого 0 <= j <= s-1
        /// </summary>
        public bool RabinMillerTest(int confidence)
        {
            BigInt32 thisVal = this;

            if (thisVal.dataLength == 1)
            {
                // для малых значений
                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)     // четное число
            {
                return(false);
            }

            // Вычислим значение s и t
            BigInt32 p_sub1 = thisVal - (new BigInt32(1));   // р-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;      // разбить внутренний цикл
                        break;
                    }
                    mask <<= 1;
                    s++;
                }
            }

            BigInt32 t = p_sub1 >> s;

            int      bits = thisVal.bitCount();
            BigInt32 a    = new BigInt32();
            Random   rand = new Random();

            for (int round = 0; round < confidence; round++)
            {
                bool done = false;

                while (!done)           // генерирует a < n
                {
                    int testBits = 0;

                    while (testBits < 2)
                    {
                        testBits = (int)(rand.NextDouble() * bits);
                    }

                    a.GetRandomBits(testBits, rand);

                    int byteLen = a.dataLength;

                    if (byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) // убедиться, что а != 0
                    {
                        done = true;
                    }
                }

                // проверка является ли а свидетелем простоты
                BigInt32 gcdTest = a.gcd(thisVal);
                if (gcdTest.dataLength == 1 && gcdTest.data[0] != 1)
                {
                    return(false);
                }

                BigInt32 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 для 0 <= j <= s-1
                    {
                        result = true;
                        break;
                    }

                    b = (b * b) % thisVal;
                }

                if (result == false)
                {
                    return(false);
                }
            }
            return(true);
        }