Exemplo n.º 1
0
        /// <summary>
        /// Вырабатывает ЭЦП сообщения-Text
        /// </summary>
        /// <param name="Text">Сообщение</param>
        /// <returns>Подпись</returns>
        public static BigInt32 CreateSignature(byte[] Text, BigInt32 d, BigInt32 n)
        {
            byte[]   hash    = MD5hash(Text);
            BigInt32 BI_Text = new BigInt32(hash);

            return(BI_Text.modPow(d, n));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Проверка цифровой подписи Signature текста Text
        /// </summary>
        /// <param name="Text">Текст</param>
        /// <param name="Signature">Подпись</param>
        /// <param name="e">Открытый ключ</param>
        /// <param name="n">Модуль</param>
        /// <returns>true если подпись верна, false в обратном случае</returns>
        public static bool VerifySignature(byte[] Text, BigInt32 Signature, BigInt32 e, BigInt32 n)
        {
            BigInt32 R = new BigInt32(MD5hash(Text));
            //Console.WriteLine(R);
            BigInt32 S = new BigInt32(Signature.modPow(e, n));

            //Console.WriteLine(S);
            if (R == S)
            {
                return(true);
            }
            return(false);
        }
Exemplo 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);
        }