ИНФОРМАЦИОННАЯ БЕЗОПАСНОСТЬ АХБОРОТ ХАВФСИЗЛИГИ Анализ арифметических операций современной криптографии и способы их аппаратной реализации Расулов О.Х. (ГУП «UNICON.UZ») В статье исследуются наиболее эффективные арифметические операции над большими числами, используемые в современной криптографии и рассмотрены методы синтеза арифметических операций над большими числами с использованием современных программируемых логических интегральных схем. Ушбу мақолада замонавий криптографияда қўланиладиган энг эффектив катта сонлар устидаги арифметик амаллар тадқиқ қилинган. Шунингдек дастурланадиган мантиқий интеграл схемалар ёрдамида катта сонлар устидаги арифметик амалларни синтез қилиш усуллари кўриб чиқилган. In this article most effective big number arithmetic used in modern cryptography are analyzed. Also synthetic methods of big number arithmetic’s operations with using Field Programmable Gate Arrays are examined. Процесс разработки аппаратных или аппаратно-программных средств криптографической защиты информации (СКЗИ) на основе современных асимметричных криптографических алгоритмов, в том числе и национальных асимметричных криптографических алгоритмов [1], непосредственно связан с необходимостью реализации арифметических операций, лежащих в основе алгоритмов. Так, стандарт O’z DST 1092:2009 использует числа размерностью не менее 256 бит, что в десятичном представлении составляет ≈ 1077 (семьдесят семь десятичных цифр) [2]. Ряд таких операций связан с обработкой относительно больших объемов информации, что ведет к необходимости выбора элементной базы с повышенной производительностью. Вместе с тем, применение высокопроизводительных элементов, имеющих вычислительные возможности, такие как микропроцесоры и микроконтроллеры (далее – процессоры) накладывают некоторые существенные ограничения, препятствующие их использование в конкретных разработках. К таким ограничениям, в частности относятся: - большие габариты, что делает невозможным их применение в малогабаритных и носимых устройствах, как например в USB – ключах; - большое потребление электроэнергии, что снижает эффективность их использования в устройствах с батарейным питанием; - большое количество выводов: большинство высокопроизводительных процессоров имеют количество выводов от 300 и выше, что приводит к нежелательным схемотехническим усложнениям проектируемых устройств. Кроме того, конструктивное расположение выводов в современных корпусах влечет за собой необходимость в дорогостоящем специализированном оборудовании, что исключает возможность широкого развития разработок такого рода (как правило, все процессоры с числом выводов ≥ 200 выпускаются в корпусах с шариковыми выводами BGA); - неоптимизированная система команд под конкретную задачу: эффективность программного кода (а значит и скорость выполнения программы) напрямую зависит от фиксированной системы команд конкретного процессора; - ограниченная разрядность данных: современные процессоры имеют фиксированную разрядность данных (8, 16 или 32 разряда), что приводит к увеличению программного кода при выполнении криптографических операций, и как следствие – к снижению производительности устройства в целом; - линейность программного кода: в процессорах отсутствуют возможности независимого и параллельного выполнения нескольких трудоемких операций одновременно; - высокая стоимость, которая растет пропорционально увеличению производительности. Исходя из вышеуказанного, можно сделать вывод, что использование высокопроизводительных процессоров для выполнения криптографических операций в аппаратных средствах зачастую малоэффективно и нецелесообразно. Одним из способов повышения эффективности выполнения криптографических операций в аппаратных средствах является их построение по принципу «ведущий ведомый». Способ предполагает использование процессора общего назначения в качестве центрального управляющего модуля устройства («ведущий»), и специализированного арифметического сопроцессора («ведомый»), выполняющего все трудоемкие операции под управлением ведущего. Постановка задачи. В асимметричной криптографии используются следующие алгебраические операции и алгоритмы: - алгоритмы проверки числа на простоту [3]; - алгебраические операции над большими числами: модульное умножение, модульное возведение в степень, нахождение остатка от деления, вычисление обратного числа по модулю. Наиболее трудоемкими операциями в асимметричной криптографии являются операции модульного умножения больших чисел и модульного возведения в степень больших чисел. Следует отметить, что модульное возведение в степень состоит из итерационной последовательности модульных умножений. Если учесть, что возведение в степень в криптографических алгоритмах применяется как непосредственно, так и косвенно (проверка на простоту, вычисление обратного числа по модулю и др.), то становится очевидным, что главной задачей, которую необходимо реализовать в арифметическом сопроцессоре является аппаратное модульное умножение больших чисел. M = a b (mod n), (1) где a,b – множители; M–произведение; n–модуль (простое число); a,b,M < n; все величины – большие положительные целые числа. В основе всех модулярных операций лежит необходимость нахождения остатка от деления результата операции на модуль. При использовании больших чисел операция деления является наиболее трудоемкой и требует наибольшего времени выполнения. Поэтому, постановкой задачи является реализация эффективных алгоритмов выполнения операции модульного умножения без использовании операции деления. Решение задачи: На сегодняшний день разработано несколько эффективных алгоритмов модульного умножения больших чисел, исключающих необходимость операции деления. Наиболее популярными из них являются: - алгоритм Баррета [4, 5]; - алгоритм Монтгомери [6, 7]. Рассмотрим отдельно каждый алгоритм. Основой алгоритма Баррета считается разложение произведения вида AB AB(mod N ) AB N , N (2) где - операция округления числа до меньшего ближайшего целого значения. Тогда, используя предварительно вычисляемую величину d , N 2m (3) где d = 2k, k – размер слова в битах, m – количество слов в модуле N, алгоритм умножения будет выглядеть следующим образом: Шаг 1. Вычислить M = A B. M d m1 Шаг 2. Вычислить q = . d m1 Шаг 3. Вычислить M = M (mod d ) – (q N) (mod d m+1) . Шаг 4. Если M < 0 принять M = M m+1 +d . Шаг 5. Пока M ≥ N вычислять M = M – N. Шаг 6. Выдать результат «M». Конец алгоритма. Проанализируем алгоритм с точки зрения его аппаратной реализации. На шаге 1 производится обычное (без вычисления остатка от деления) умножение двух больших чисел. Эта операция особой трудоемкости не представляет и ее можно производить традиционным методом или ускоренным методом Карацубы [4]. В результате умножения формируется произведение с разрядностью 2n. Поскольку d является числом, равным степени двойки, шаг 2 фактически представляет собой последовательность «сдвиг M вправо на (m-1) слов» «умножение на μ» «сдвиг вправо на (m+1) слов». Шаг 3 фактически состоит из следующих операций: умножить q на N, оставить младшие (m+1) слов (поскольку d является степенью двойки) и результат вычесть из младших (m+1) m+1 слов M. Проверку результата на отрицательность (на шаге 4) можно упростить, если на шаге 3 проверять M (mod d m+1) ≥ (q N) (mod d m+1) перед вычитанием. В этом случае шаг 4 можно исключить полностью. Шаг 5 является единственным итерационным шагом алгоритма: необходимо производить вычитание M = M – N, пока не будет выполнено условие M < N. Однако исследования автора алгоритма [6] показывают, что таких вычитаний будет не больше трех. Процедуры умножения на шагах 2 и 3 являются целочисленными умножениями и могут быть реализованы так же, как и на шаге 1. Исходя из приведенного анализа, можно сделать вывод, что сам по себе алгоритм модульного умножения Баррета большой трудоемкости не представляет и вполне мог бы быть реализован аппаратно. Тем не менее, эффективность алгоритма Баррета полностью зависит от того, насколько эффективно будут выполнены предварительные вычисления. В последнем случае это константа μ, которая должна быть вычислена делением больших чисел (3). Если принять, что в течении многократного использования криптографического алгоритма модуль N будет неизменен, тогда константу можно вычислять всего один раз и временные затраты на ее вычисление (то есть на выполнения алгоритма деления) на общем фоне будут незначительны. Алгоритм Монтгомери [6, 7] представляет собой умножение двух чисел по модулю третьего нечетного числа без операции деления. Алгоритм основан на так называемой «редукции Монтгомери»: M = MonPro(A, B, N) = A B r -1 (mod N), (4) где MonPro(A, B, N) – операция редукции Монтгомери; A, B – множители; r -1 – дополнительный множитель; N – нечетный модуль. Как видно, (4) в точности повторяет искомую формулу (1), за исключением паразитного множителя r -1, появляющегося в результате выполнения операции MonPro. Эта величина является обратным числом r по модулю N таким, что r -1 r ≡ 1 (mod N) , где r = 2n, n – длина модуля N в битах. Для того, чтобы избавиться от этого множителя, умножаемые предварительно необходимо привести к виду «представления Монтгомери»: A A r (mod N), B B r (mod N) числа (5) Тогда, в соответствии с (4) MonPro(Ar, Br, N) = Ar Br r -1 (mod N) = ABr2r -1 (mod N)= ABr (mod N), (6) и в соответствии с (1) можно считать, что MonPro(Ar, Br, N) = ABr (mod N) = Mr (mod N) Тот факт, что произведение в результате операции MonPro() равняется Mr а не M удобен, поскольку при необходимости многократного перемножения, каждый результат умножения необходимо передавать в функцию MonPro как аргумент, для чего в соответствии с (5) M необходимо переводить в представление Монтгомери M Mr (mod N). На практике, вычисления производятся над числами с базисом d = 2k , (7) где k – разрядность одного слова вычислительной системы. Тогда, алгоритм умножения Монтгомери для вычисления MonPro(Ar, Br, N) = Mr (mod N), обобщенно можно выразить следующим образом: k – разрядность одного слова в битах, m – длина модуля N в словах (по k бит в каждом). Большие числа хранятся в виде массивов слов. Аргументы A, B приведены к виду представления Монтгомери (5). Шаг 1. Принять X = 0, d = 2k Шаг 2. Принять i = 0. Шаг 3. Вычислить q = (x0 + ai b0) (d – n0)-1 (mod d). Шаг 4. Вычислить X = (X + ai B + q N) / d. Шаг 5. Если i < m, принять i = i + 1 и перейти на шаг 4. Шаг 6. Если X ≥ N вычислить X = X – N. Шаг 7. Выдать результат «Mr (mod N) = X». Конец алгоритма. Проанализируем алгоритм с точки зрения его аппаратной реализации. На шаге 3 вычисляется промежуточное значение q из трех составляющих: - составляющая (x0 + ai b0) вычисляется легко, так как вычисления производятся над однословными величинами; - составляющая (d – n0)-1 есть однословное число, обратная величина N по модулю d, ее вычисление особой трудоемкости не представляет. Эта величина не меняется на всех итерациях, а значит ее можно вычислить один раз на начальных шагах алгоритма. Более того, если модуль N остается неизменным (а это так для большинства операций криптографического алгоритма), эту величину целесообразно вычислить однократно и хранить как константу на всем протяжении «жизни» модуля N; -в соответствии с (7), составляющая (mod d) говорит о том, что результат перемножения первых двух составляющих просто отсекается до размера одного слова. В связи с этим, первую составляющую целесообразно вычислять также на уровне одного слова, без учета переносов в операциях умножения и сложения. Шаг 4 состоит из вычисления дроби, в числителе которой производится две операции умножения однословной величины на большое число. Трудоемкости эта операция не представляет, так как такое умножение легко реализовать традиционным способом. Далее, осуществляется операция сложения трех слагаемых – больших чисел, что так же не представляет особой трудоемкости. Следующая операция – деление числителя на d. Именно эта операция привлекает разработчиков, поскольку деление на степень двойки (7) не что иное как сдвиг вправо на количество бит, равное этой степени. Для нашего случая – это сдвиг массива на один элемент, что также не представляет трудоемкости. Таким образом, алгоритм Монтгомери позволяет производить модульное умножение двух больших чисел, без необходимости применения трудоемкой операции деления на модуль. По окончанию умножения, если необходимо, результат Mr (mod N) можно легко привести к виду M (mod N), снова используя редукцию Монтгомери, задавая единицу в качестве одного из аргументов: MonPro(1, Mr, N) = Mr r -1 (mod N) = M (mod N) (8) Алгоритм умножения Монтгомери с успехом применяется большинством разработчиков СКЗИ. Однако, для эффективного применения такого умножения, необходимо решить, каким образом приводить большие множители к виду представления Мнотгомери (5). Строго говоря, единого подхода к решению данной проблемы не существует, поскольку здесь без операции деления все таки не обойтись. В [8] предлагается любопытный способ решения данной проблемы. Суть ее заключается в предварительном вычислении константы r2 (mod N) Тогда, приведение аргументов к виду представления Монтгомери можно выполнить используя все ту же редукцию: MonPro(A, r2, N) = A r2 r -1 (mod N) = A r (mod N) (9) Результирующий алгоритм модульного умножения будет выглядеть следующим образом: Шаг 1. Вычислить Ar = MonPro(A, r2, N) = A r (mod N). Шаг 2. Вычислить Br = MonPro(B, r2, N) = B r (mod N). Шаг 3. Вычислить Mr = MonPro(Ar, Br, N) = M r (mod N). Если умножение не является промежуточным и необходимо получить величину M = A B (mod N), то алгоритм будет выглядеть еще проще: Шаг 1. Вычислить Ar = MonPro(A, r2, N) = A r (mod N). Шаг 2. Вычислить M = MonPro(Ar, B, N) = A r B r -1 (mod N) = A B. С учетом того, что в криптографических алгоритмах модуль N является относительно постоянной величиной, целесообразно предварительно однократно вычислять значение r2 (mod N) и в дальнейших вычислениях использовать ее как константу. При аппаратной реализации рассмотренных операций целесообразно использовать интегральные схемы, которые выпускаются под общим названием «программируемые логические интегральные схемы» (ПЛИС) [9]. В отличие от обычных цифровых микросхем, логика работы ПЛИС не определяется при изготовлении, а задаётся на стадии разработки конкретного устройства посредством синтеза (проектирования). Для синтеза используются программаторы и отладочные среды, позволяющие задать желаемую структуру цифрового устройства в виде принципиальной электрической схемы или программы на специальных языках описания аппаратуры Verilog, VHDL, AHDL и др. С практической точки зрения, целесообразность использования ПЛИС в аппаратных устройствах заключается в отсутствии временных затрат при выполнении многих арифметических и логических операций. Так, простой псевдокод if(C == 0) then D=A&B else D=A+B end if в процессорном исполнении в зависимости от системы команд процессора будет выполнен как минимум за три машинных цикла: - команда сравнения (1 цикл); - команда выполнения одной из операций (1 цикл); - команда перехода (1 цикл). В исполнении ПЛИС этот псевдокод будет выполнен «на лету», без привязки к тактовой частоте, с использованием асинхронной логической схемы как показано на рис. 1. A B & D 0 Mux 1 + C Рис. 1. Логическая схема выполнения псевдокода В реальных устройствах со сложными логическими взаимосвязями и ветвлениями, выигрыш в эффективности использования ПЛИС по сравнению с использованием процессора очевиден. Кроме того, в отличии от процессоров, на базе ПЛИС можно построить логическую схему с любой разрядностью операндов, не привязываясь к понятиям «машинное слово», «разрядность процессора» и т.д. Одним из самых больших мировых производителей выпускающих ПЛИС является фирма Xilinx. По способу хранения конфигурации, Xilinx изготавливает ПЛИС по трем технологиям: - на основе синхронного ОЗУ (SRAM) – ПЛИС с архитектурой FPGA, при этом конфигурация ПЛИС храниться во внутреннем ОЗУ, а инициализация осуществляется из внешнего массива памяти. По данной технологии выпускаются микросхемы сериий Spartan и Virtex; - на основе FLASH – ПЛИС с архитектурой CPLD, конфигурация сохраняется во внутренней энергонезависимой FLASH-памяти и в любой момент времени может быть перезаписана непосредственно из персональго компьютера или любого другого внешнего устройства. По такой технологии выпускаются микросхемы серии XC9500; - на основе EEPROM – ПЛИС с архитектурой CPLD, конфигурация сохраняется во внутренней энергонезависимой EEPROM-памяти и в любой момент времени может быть перезаписана непосредственно из персональго компьютера или любого другого внешнего устройства. По такой технологии выпускаются микросхемы серии CoolRunner. Наиболее эффективными ПЛИС по соотношению цена/логическая емкость являются микросхемы FPGA семейства Spartan-3 (Spartan-3, Spartan-3Е, Spartan-3A). Они разработаны специально для использования в электронных устройствах для серийного производства и имеют невысокую стоимость комплектующих. В семейство входит несколько кристаллов, отличающихся логической емкостью: минимальный по емкости кристалл содержит 50 000 логических вентилей, максимальный – 5 000 000. Кристаллы семейства расчитаны на работу с максимальной внутренней тактовой частотой до 500 МГц. В зависимости от того, в каком виде большие числа хранятся в памяти ПЛИС, можно определить два основных способа выполнения арифметических и логических операций над ними. Числа можно хранить в регистровой памяти «целиком» (например, 1024 битное число хранится в 1024 битном регистре). В этом случае часть операций, таких как сложение и поразрядные логические операции, можно производить сразу над всеми битами числа. Например, для выполнения поразрядной коньюнкции двух 2048-битных чисел хранящихся в регистрах, достаточно написать на любом языке HDL обычный оператор поразрядного И (на языке VHDL «A <= B and C»). Количество бит в числах, а так же количество самих больших чисел ограничено только физическими возможностями ПЛИС. Так, в каждом КЛБ имеется по 8 базовых ячеек памяти – триггеров. В кристалле с минимальной логической емкостью семейства Spartan-3 (микросхема XC3S50) содержится 192 КЛБ, то есть 1 536 триггеров. В таком кристалле можно хранить только одно 1024 битное число, или например три 512 битных числа. В кристалле с максимальной логической емкостью (XC3S5000) содержится 8 320 КЛБ или 66 560 триггеров. В таком кристалле можно например хранить до 65 х 1024 битных числа. Таким образом, если выполнять только логические операции и арифметическое сложение/вычитание над большими числами, целесообразно выбирать кристалл, начиная с XC3S1000 (15 360 триггеров) и выше. Модульное умножение больших чисел можно реализовать используя например алгоритм Монтгомери. При условии оптимального подхода к проектированию, возможно осуществить модульное умножение за один – два такта. Возведение в степень потребует большего количества итераций и элементов памяти. Для задач криптографического сопроцессора, необходимо выбирать кристалл не менее XC3S4000 (55 296 триггеров). На практике, во многих случаях хранение чисел в многоразрядных регистрах «целиком» может оказаться нецелесообразным. Тогда можно воспользоваться встроенными блоками оперативной памяти. Так как блочная память имеет фиксированную разрядность, большие числа необходимо разбивать на слова, размером равным выбранной разрядности блочной памяти. В смысле хранения чисел, такой подход аналогичен хранению чисел в массивах в процессорных системах. Однако, при выполнении логических и арифметических операций с такими массивами, выигрыш во времени выполнения как каждой итерации, так и всей операции в целом будет существенным по сравнению с процессорной обработкой. Каждый из 18 килобитных блоков памяти в семействе Spartan-3 может конфигурироваться от 16К х 1 бит до 512 х 36 бит. Количество таких блоков памяти зависит от кристалла: в кристалле с минимальной логической емкостью имеется 4 блока памяти, кристалл с максимальной емкостью содержит 104 таких блока. Каждый кристалл содержит аппаратные 18 х 18 битные умножители по количеству блоков памяти, которые можно использовать в итерационных операциях умножения хранящихся в памяти чисел. Значит, конфигурацию блоков памяти целесообразно осуществлять таким образом, чтобы разрядность слов не превышала разрядность умножителей. В нашем случае наиболее оптимальным является хранить числа в виде массива 16 битных слов. Теперь можно произвести расчет максимально возможного количества чисел на одном кристалле: 1) Блок памяти конфигурируется как 1024 х 16 бит. 2) Для хранения одного 1024битного числа необходимо 64 слова, а значит в одном блоке возможно хранить до 16 1024-битных чисел. 3) В кристалле с минимальной логической емкостью содержится 4 блока памяти, в которых всего можно разместить до 64 1024-битных чисел, что приравнивается к максимально возможному количеству чисел в регистровой памяти кристалла с максимальной емкостью. При таком подходе к размещению чисел появляется ряд преимуществ: - полностью высвобождаются триггеры и логические элементы КЛБ, предоставляя разработчику возможность их использования для любых дополнительных задач; - появляется возможность реализации криптографических операций на любом кристалле, независимо от его логической емкости. При итерационном умножении двух 1024-битных чисел потребуется 64 х 64 = 4 096 системных такта, что по сравнению с процессорными системами такой же (16-битной) разрядности эффективнее как минимум в 8 – 10 раз. Выводы Рассмотренные алгоритмы модульного умножения больших чисел вполне могут быть реализованы в аппаратных устройствах. Для обоих алгоритмов требуются предварительные вычисления, связанные с необходимостью использования алгоритма деления больших чисел, поэтому представляющие наибольшую трудоемкость: - для алгоритма Баррета требуется предвычисление константы «μ», используя целочисленное деление; - для алгоритма Монтгомери требуется предвычисление константы «r2 (mod N)», используя деление с остатком. Одним из оптимальных способов реализации криптографических модулей СКЗИ является применение ПЛИС в качестве арифметического сопроцессора. ПЛИС, выпускаемые современными мировыми производителями имеют все физические возможности для их использования в это качестве. Применение алгоритмов модульного умножения больших чисел Монтгомери или Баррета на базе ПЛИС в конечном итоге повышает эффективность и производительность аппаратных СКЗИ. Литература 1. Прикладная криптография. Протоколы, алгоритмы, исходные тексты на языке Си. Б. Шнайер. – М.: ТРИУМФ, 2002. 2. O’z DSt 1092: 2009 Информаци онная технология. Криптографическая защита информации. Процессы формирования и проверки электронной цифровой подписи. 3. Теоретико-числовые алгоритмы в криптографии. О. Василенко. – М.: МЦНМО, 2003. 4. Умножение многозначных чисел на автоматах. А.Карацуба, Ю.Офман. М.: Доклады Академии Наук СССР т.145, 2, 1962. 5. Implementing the Rivest Shamir Adleman public key encryption algorithm on standard digital signal processor. P.D.Barrett. In Advances in CryptologyCrypto’86, Springer, 1987. 6. Криптография на Си и С++ в действии. М. Вельшенбах. – М.: ТРИУМФ, 2004. 7. Modular Multiplication without Trial Division. P.L. Montgomery. Mathematics of Computation, Vol. 44, No. 170, 1985. 8. Efficient Architectures for implementing Montgomery Modular Multiplication and RSA Modular Exponentiation on Reconfigurable Logic. A. Daly, W. Marnane. FPGA’02, 2002. 9. Современные семейства ПЛИС фирмы Xilinx. М. Кузелин, Д. Кнышев, В. Зотов. – М.: Горячая Линия – Телеком, 2004.