Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.12.2009, 21:17   #1
Alex_FF
Удален
Форумчанин
 
Регистрация: 02.12.2009
Сообщений: 309
Вопрос a в степени d по модулю n. Длинная арифметика.

Необходимо реализовать программу для шифрования и расшифрования сообщений криптосистемой RSA.
Что дано: Сообщение; ключ.

Проблема: как вычислить a^d (mod n), если a, d и n - длинные числа (около 500 десятичных цифр). Нужен алгоритм, который вычисляет это за приемлемое время. При этом никакими библиотеками для работы с длинными числами пользоваться нельзя.

Я писал раньше программу для работы с длинными числами, и вот что у меня имеется: умножение длинного на короткое, умножение длинного на длинное, деление с остатком длинного на короткое, деление с остатком длинного на длинное, сложение/вычитание длинных чисел.

+ знаю алгоритм быстрого возведения в степень для чисел базовых типов (напр. Int32).
Alex_FF вне форума Ответить с цитированием
Старый 07.12.2009, 21:41   #2
LeBron
Форумчанин
 
Регистрация: 10.10.2009
Сообщений: 680
По умолчанию

Кто мешает реализовать быстрое возведение в степень с длинынми числами? Если брать кажый раз по модулю, то не будут получатся числа, больше n. Если 500 цифр, то двоичный логарифм d примерно 1500. Значит всего 1500 итераций. Если десятичных цифр 500, то можно хранить по 9 разрядов под 8байтовым типом - и получится менее 60 цифр. Даже если предположить очень кривую реализацию и 5 операций в каждой итерации (2 умножения, 2 модуля и 1 деление длинного на короткое), то имеем 15 тысяч условных операций в итерации. С учетом пооперанной реализации - примерно 50 тысяч. Если подумать над тем, будет ли польза при таких маленьких числах от Карацубы/Винограда/Штрассена/Фурье, то может даже еще быстрее получится (асимптотика там пониже, только весь выиграш константа перекроет).
В итоге - 75 миллионов операций. Надо быстрее? Что для Вас приемлимое время?
LeBron вне форума Ответить с цитированием
Старый 07.12.2009, 22:20   #3
Alex_FF
Удален
Форумчанин
 
Регистрация: 02.12.2009
Сообщений: 309
Вопрос

LeBron,
вот, к примеру, алгоритм для не длинных чисел:

Код:
long powmod(long a, long d, long n)
{
    long b = 1;

    while (d) 
    {
        if (d % 2 == 0) 
        {
             d /= 2;
             a = (a * a) % n;
        }
        else 
        {
             d--;
             b = (b * a) % n;
         }
     }
     return b;
}
Если у меня a, d, n - длинные числа, т. е. массив, то, чтобы только проверить условие в цикле [while(d)] на это уже нужно sizeof(d) операций + нужно постоянно делить это d на 2, брать то a, то b по модулю n... думаю это будет висеть сутки. Или не будет?
Alex_FF вне форума Ответить с цитированием
Старый 07.12.2009, 22:45   #4
LeBron
Форумчанин
 
Регистрация: 10.10.2009
Сообщений: 680
По умолчанию

Цитата:
Сообщение от Alex_FF Посмотреть сообщение
LeBron,
вот, к примеру, алгоритм для не длинных чисел:

Код:
long powmod(long a, long d, long n)
{
    long b = 1;

    while (d) 
    {
        if (d % 2 == 0) 
        {
             d /= 2;
             a = (a * a) % n;
        }
        else 
        {
             d--;
             b = (b * a) % n;
         }
     }
     return b;
}
Если у меня a, d, n - длинные числа, т. е. массив, то, чтобы только проверить условие в цикле [while(d)] на это уже нужно sizeof(d) операций + нужно постоянно делить это d на 2, брать то a, то b по модулю n... думаю это будет висеть сутки. Или не будет?
??? Это как надо проверять? Проверка "число больше 0" состоит из 2 условий - "количество цифр в числе больше 1" или "последняя цифра числа не 0". Делить на 2 и брать по модулю - я уже написал выше примерные рассчеты. Даже при весьма кривых руках и весьма убитом компе - минута. В идеале - подозреваю, что можно уложится в секунду (но это надо еще в теории покопаться). Примерно секунд 10 должно хватить с запасом.
LeBron вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
длинная арифметика Dimarik Общие вопросы C/C++ 1 16.09.2009 12:02
Длинная арифметика на C#(деление) Mr_Dark Общие вопросы .NET 1 21.06.2009 21:57
Длинная арифметика: деление Vadik(R) Помощь студентам 1 27.03.2009 12:08
Длинная арифметика DmT Помощь студентам 2 06.10.2007 22:43