Каскадное шифрование редуцированным алгоритмом RSA
Введение
Данная публикация была написана в результате применения общей идеи каскадирования, взятой из радиотехники, к широко известному теоретико-числовому алгоритму RSA, но, правда, в его облегченном (редуцированном) виде. Облегчение RSA компенсируется идеей каскадирования. Таким образом возник вариант методики улучшения криптостойкости RSA в противовес классическому удлинению ключа.
Для предварительных исследований использовались возможности встроенной Big Integer арифметики языка Python, а также функция factorint (.) библиотеки SymPy, позволяющая раскладывать числа на простые множители
from sympy import factorint as f
d = f(999_999_999)
factors = list(d)
print(factors)
[3, 37, 333667]
Целью данной публикации является ознакомление широкой публики с предлагаемой идеей.
Генерация ключей
Для ускорения процедуры генерации выбраны два небольших числа: и . Дополнительно, это позволяет уместиться в -битный регистр процессора. Дальнейшие параметры будут согласованы так, чтобы обрабатывать -битный вход. Процедура генерации ключей состоит в следующем:
Генерируем случайных чисел в диапазоне
Составляем произведение
Раскладываем произведение на простые множители
Повторяем пп. 1–3 несколько раз (на выбор):
Из найденных множителей формируем множество простых множителей .
Здесь и — небольшие числа, , подбираются экспериментально и обеспечивают некоторую «соль» и разнообразие получаемых множителей (влияет на скорость генерации).
Среди найденного множества в цикле отбираем случайных множителей
Определяем минимальную и максимальную битность множителей (то есть их ширину в битах)
Если min/max битности попадают в определенный интервал, например, больше и меньше бит (помним про -битный вход), то сохраняем множители — будущие ключи — и завершаем цикл.
Рекомендуется брать . В цикле можно установить максимальное количество итераций, например, . При превышении генерацию начинаем заново.
По отобранным множителям составляем произведение
которое гарантирует обратимость шифрования.
Найденное произведение раскладываем на множители — будущие модули
Если множителей мало (например, меньше ), то генерацию начинаем заново
Среди найденных множителей ищем множитель, битность которого попадает в заданный диапазон, например, от до бит (модуль должен быть большим относительно разрядности входа, которую мы выбрали бита)
Если «хороший» множитель (модуль) найден, то сгенерированные ключи и этот множитель сохраняем. В противном случае генерацию начинаем заново.
Можно отбирать два и более множителя и использовать любой из них, т.к. математически на результат шифрования они не влияют.
Сгенерированные ключей необходимо разделить на две примерно равновесные половины: первая используется для шифрования, , вторая — для дешифрования, .
Время поиска ключей при использовании описанных выше инструментов составляет единицы секунд. Пример найденных ключей и одного модуля
Процедура шифрования
Допустим, что шифруется некоторое число .
Последовательно умножаем на ключи шифрования
В качестве результата шифрования берем модуль , где — отобранный модуль.
Пример.
Пусть . Возьмем найденные выше ключи и первые будем использовать для шифрования:
Заметим, что после шифрования несколько повышается битность числа: примерно бита для рассмотренного примера.
Модуль рекомендуется брать на каждом шаге, как в примере, что позволит ограничить разрядность чисел. Если арифметика BigInt, то модуль можно взять один раз в конце.
Процедура дешифрования
Допустим, принимаем шифрованное число .
Последовательно умножаем на ключи дешифрования
В качестве результата дешифрования берем модуль .
Продолжение примера.
Ключи шифрования являются открытыми ключами, а ключи дешифрования — закрытыми, и, вообще, для предложенного метода шифрования существующие протоколы (вариации применения) алгоритма RSA остаются теми же самыми.
Каскадирование шифра
Если последовательно сгенерировать, допустим, разных наборов ключей и модулей, то описанную процедуру шифрования можно последовательно применить раз. В свою очередь процедура дешифрования должна быть последовательно применена раз.
Каскадирование позволяет увеличить криптостойкость — компенсировать небольшой диапазон используемых множителей, который был выбран для ускорения процедуры генерации ключей. Последняя основана на разложении относительно небольших чисел ( бита) на простые множители.
При каскадировании, чтобы согласовать требование разрядности входа, придется текущее шифрованное число делить на две части: -битный вход и остаток, причем последний передавать как есть. Либо возможен вариант с сортировкой сгенерированных наборов ключей по их модулям в порядке возрастания: набор ключей с наибольшим модулем применяется самым последним (при дешифровании он будет первым). В этом случае данные будут переданы и приняты без потерь.
Предложенный алгоритм является мультипликативным и, естественно, имеет недостаток в виде, например, обнуления шифрованного потока при нулевом входном потоке. Однако, данный недостаток можно нивелировать, например, соответствующим обратимым (линейным) псевдослучайным генератором, который по определению не допускает нулевого состояния: — шифровать состояние генератора (полученное после кратного применения функции next), а при дешифровании использовать обратную функцию (back) того же самого генератора: .
Выводы
Предложен упрощенный каскадный вариант алгоритма RSA с ускоренной генерацией ключей.
Каскадирование позволяет:
Регулировать криптостойкость алгоритма, не увеличивая длину фактических ключей, а увеличивая их количество
Ускорить генерацию ключей за счет отсутствия экстремально больших простых чисел.
Предложено мультипликативную природу алгоритмов типа RSA нивелировать обратимым (линейным) псевдослучайным генератором. Про последние можно прочитать в моих статьях на Хабре.
Предлагается итоговый алгоритм назвать Cascaded Reduced RSA (CRRSA).