реализация библиотеки bignum для шифрования rsa

Так что, конечно, я знаю, что есть простые решения для этого, такие как использование библиотеки GMP или множества других библиотек произвольной точности. Это для работы в классе, поэтому мне не разрешено пользоваться любым из этих маршрутов. После того, как мы создадим все наши операции, мы подойдем к тому, чтобы иметь возможность использовать схему шифрования RSA.

Я использую векторы для хранения n-битных чисел, представленных в двоичном виде. У меня есть преобразования в десятичные числа позже, но я должен работать с двоичными числами и преобразовывать только для отображения.

Я успешно реализовал сложение, вычитание и умножение. Я застрял на делении и модульных операциях... особенно на модульном возведении в степень. Я понимаю алгоритмы, по крайней мере, на базовом уровне, но не могу перевести их в код, который будет работать с числами произвольной длины. Кажется, я не могу найти примеры такой работы, выполненной на С++ без внешних библиотек.

Некоторые конкретные вопросы:

есть ли лучший способ выполнить модуль для n-битного числа, кроме простого вызова функции деления, которую я пишу, и использования возвращаемого остатка?

Мне бы очень хотелось увидеть несколько хороших примеров на С++, так как я вообще не могу хорошо следовать исходному коду GMP.

Будем очень благодарны за любые хорошие ресурсы для изучения или некоторую помощь. Спасибо


person Wildcat313    schedule 26.09.2012    source источник
comment
Knuth, Seminumerical Algorithms содержит краткое описание алгоритма деления.   -  person Pete Becker    schedule 26.09.2012


Ответы (1)


Вы можете подделать операции модуля с делением. Ваша операция модуля эквивалентна:

v = n - (n / m) * m

где n — делитель, m — модуль, а v — выходное значение (все произвольные числа точности)

Если вы застряли на делении, вы можете просто реализовать его, как если бы вы выполняли длинное деление вручную. (Вы должны были научиться делать это в средней школе с помощью умножения и вычитания. Достаточно легко перевести процесс в основание 2. Сделайте несколько на бумаге, если вы застряли. Если вам нужен более эффективный алгоритм, вы, вероятно, можете найдите его, выполнив поиск в Google по запросу «алгоритм деления произвольной точности»)

Когда у вас есть модуль, вы можете вычислить модульное возведение в степень с повторным возведением в квадрат. Наблюдайте, как мы вычисляем некоторое большое целое число X в степени 67 по модулю N:

v1  = X mod N         // X^1 mod N
v2  = v1  * v1  mod N // X^2 mod N
v4  = v2  * v2  mod N // X^4 mod N
v8  = v4  * v4  mod N
v16 = v8  * v8  mod N
v32 = v16 * v16 mod N
v64 = v32 * v32 mod N // X^64 mod N

v66 = v64 * v2  mod N // X^66 mod N
v67 = v66 * v1  mod N // X^67 mod N

Математически вы можете понять, почему это имеет смысл. Этот алгоритм является обычно выбираемым алгоритмом для вычисления модульных возведений в степень и работает во времени и пространстве логарифмически по размеру экспоненты и логарифмически по размеру основания (т.е. он быстр даже для огромных чисел)

P.S. Убедитесь, что вы сказали своему профессору, что он глуп из-за того, что не позволяет вам использовать внешние библиотеки. Одна из самых важных вещей, которую могут усвоить программисты, — это когда быть ленивым (т. е. когда найти и использовать библиотеку, чтобы что-то сделать, а не создавать собственное решение).

person Wug    schedule 26.09.2012
comment
Человек, который воняет. Это был отличный ответ до философского вощения. Есть разница между тем, что сделал кто-то другой, поэтому вам не нужно, и кем-то другим, поэтому вам не нужно учиться как в. Ньютон изучал Да'Винчи. Он не просто взял всю свою жизнь заметки и сказал «да». Меня не должно волновать, как это работает, этот умный парень уже сделал это. - person WhozCraig; 27.09.2012
comment
Знание того, когда нужно быть ленивым, является важным навыком, который улучшает вашу реальную производительность. Когда у вас есть работа, вы можете обратиться за помощью в Google, вы можете использовать библиотеки; все искусственные академические ограничения исчезли. Да, здорово знать, как что-то работает, но если вы действительно заинтересованы в большой целочисленной логике, загляните в существующую библиотеку; писать собственную наивную, неполную, глючную реализацию было бы пустой тратой времени. - person Wug; 28.09.2012
comment
Согласованный. Нет смысла изобретать велосипед, который уже сделал кто-то другой. Моя точка зрения заключалась в том, что когда это колесо ломается, а вы совершенно не знаете, как оно должно работать, вас обливают шлангом. Это не продукт; это ноу-хау. Использование чьей-то тяжелой работы без малейшего представления о том, что заставляет ее работать, отдает ваше будущее буквально в руки неизвестного. Вы можете управлять им, знакомясь, изучая, изучая. В этом была вся моя суть. И я имел в виду то, что сказал, мне действительно понравился ответ. Очень хорошо представлен. - person WhozCraig; 28.09.2012
comment
Спасибо. Я не знаю, как далеко вы продвинулись в своем образовании, но чем дальше я продвигаюсь в своем, тем больше я понимаю, что такие вещи, как правильный дизайн и намеренная лень, важны, и чем больше становится ваш проект, тем важнее экономить время теми способами. Для справки, я пытался написать библиотеку biginteger на C++, и это было непросто. Я не делал этого по какой-то конкретной причине, кроме как посмотреть, смогу ли я, и через некоторое время я отказался от этого. - person Wug; 28.09.2012