Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Практическая криптография

..pdf
Скачиваний:
6
Добавлен:
12.11.2023
Размер:
16.23 Mб
Скачать

11.4 Большие простые числа

223

нерном калькуляторе. Проиллюстрировать, насколько медленно возрастает значение натурального логарифма больших чисел, можно на следующем при­ мере: натуральный логарифм числа немного меньше, чем 0,7 к.) Число длиной в 2000 бит находится в диапазоне от 21999 до 22000. В этом диапа­ зоне примерно одно из каждых 1386 чисел является простым. Кроме того, ббльшую часть чисел этого диапазона сразу же можно откинуть как состав­ ные, например четные числа.

Ниже приведен пример генерации больших простых чисел.

ф у н к ц и я G E N E R A T B L A R G E P R I M E

вход: I Нижняя граница диапазона, в котором должно находиться простое число.

иВерхняя граница диапазона, в котором должно находиться простое число.

выход: р

Простое число в диапазоне

и.

Проверим корректность задания диапазона. assert 2 < / < и

Подсчитаем максимальное количество попыток.

г *- 100 ( |k>g2uj + 1)

repeat

г <—г - 1

/assert г > 0

^Выберем в заданном интервале случайное число п. п E R I , . .. ,и

Продолжим попытки до тех пор, пока не найдем простое число.

until ISP R IM E (TI) retu rn n

Оператор E R используется для обозначения случайного выбора числа из заданного множества. Разумеется, для выполнения этой операции понадобит­ ся генератор псевдослучайных чисел.

Описанный алгоритм достаточно прост. Вначале мы проверяем, что ин­ тервал задан корректно. Случаи / < 2 и I > и не представляют для нас интереса и влекут за собой массу проблем. Обратите внимание на граничное условие: случай I = 2 не допускается3. Затем мы подсчитываем, какое ко­ личество попыток нужно совершить, чтобы найти простое число. Существу­ ют интервалы, которые не содержат простых чисел. Например, в интервале

3Алгоритм Рабина-Миллера, который мы будем применять позднее, не слишком хо­ рошо работает, когда на его вход подается число 2. Это не страшно — мы и так зна­ ем, что 2 является простым числом, поэтому генерировать его с помощью функции G ENERATELARGEP RIME нет никакой нужды.

224 Глава 11. Простые числа

9 0 ,..., 96 все числа являются составными. Программа никогда не должна “зависнуть”, невзирая на то, что было подано ей на вход, поэтому ограничим количество попыток и сгенерируем ошибку в случае, если это количество бу­ дет превышено. Как уже отмечалось, в окружении числа и примерно одно из каждых 0,7 •log2и чисел является простым. (Функция log2 — это лога­ рифм по основанию 2. Для простоты ее можно определить следующим об­ разом: log2(x) := Inж /In2). Подсчитать число log2и довольно сложно, а вот [log2и\ +1 намного проще: это количество бит, необходимое для того, чтобы представить и в виде двоичного числа. Таким образом, если длина числа и равна 2017 бит, тогда [log2и\ + 1 = 2017. Множитель 100 гарантирует, что мы с большой вероятностью найдем простое число. Для достаточно больших интервалов вероятность того, что простое число не будет найдено, составляет менее 2-128, поэтому ею можно пренебречь. В то же время наличие данного ограничения гарантирует, что выполнение функции G E N E RA TE LA R G E P R IM E когда-нибудь завершится. В этом примере мы весьма небрежно использова­ ли утверждения assert для генерации ошибки; реальная программа должна выдать ошибку с объяснениями того, что было сделано неправильно.

Основной цикл алгоритма очень прост. Проверив, не исчерпано ли чис­ ло попыток, мы выбираем случайное число и с помощью функции isPRIME выясняем, не является ли оно простым.

Убедитесь, что полученное число п действительно выбрано равноверо­ ятным случайным образом из диапазона /, ... , и. Кроме того, если простое число необходимо сохранить в секрете, интервал Z,... , и должен быть доста­ точно большим. Если злоумышленник знает, какой интервал вы используете, и этот интервал содержит менее 2128 простых чисел, он потенциально сможет перебрать их все.

При желании вы можете гарантировать, что сгенерированное случайное число является нечетным, установив наименее значимый бит только что сге­ нерированного числа п. Поскольку число 2 не находится в заданном интер­ вале, изменение бита никак не повлияет на вероятностное распределение вы­ бираемых вами простых чисел, зато наполовину сократит число попыток, которые вам пришлось бы осуществить для обнаружения простого числа. К сожалению, данная операция допустима только в том случае, если и яв­ ляется нечетным. В противном случае установка наименее значимого бита может выбросить п за пределы допустимого диапазона.

Функция ISP R IM E — это фильтр, состоящий из двух этапов. Первый этап — это простой тест, в котором мы пытаемся проверить делимость п на все малые простые числа. Это позволит быстро откинуть множество составных чисел, которые делятся на малые простые числа. Если же такие делители не бу­ дут найдены, в ход пойдет “тяжелая артиллерия” — тест Рабина-Миллера (Rabin-Miller).

11.4 Большие простые числа

225

ф ун кц и я ISP R IM E

 

вход:

п

Целое число > 3.

 

выход:

b

Булево значение, указывающее, является ли п простым чис­

 

 

лом.

 

assert п > 3

for р € {все простые числа < 1000} do if р является делителем п then

return р = п

fi

od

return R A B I N - M l L L E R ( n )

Если у вас нет желания генерировать малые простые числа, можете немно­ го схитрить. Вместо того чтобы проверять делимость на все простые числа, вы можете проверять делимость на 2 и все нечетные числа 3 , 5 , 7 , , 999 в по­ рядке возрастания последних. Эта последовательность содержит все простые числа до 1000, а также множество не интересующих нас составных чисел. Порядок использования чисел по возрастанию важен для того, чтобы малое составное число наподобие 9 было правильно распознано как составное. Гра­ ница 1000 выбрана произвольным образом и может быть изменена в целях оптимизации производительности.

Все, что нам остается, — это рассмотреть тот самый таинственный тест Рабина-Миллера, который выполняет всю тяжелую работу.

11.4.1П р овер к а того, является ли число п росты м

Оказывается, проверить, является ли число простым, невероятно легко (по крайней мере по сравнению с разложением числа на множители и по­ иском его простых делителей). К сожалению, подобные “легкие” алгоритмы далеко не совершенны. Все они определяют простые числа с некоторой до­ лей вероятности. Существует определенный риск получить неверный ответ. Повторяя одну и ту же проверку несколько раз, мы можем сократить веро­ ятность ошибки до приемлемого уровня.

Для проверки того, является ли число простым, будем использовать тест Рабина-Миллера. Математическое обоснование этого теста выходит за рамки нашей книги, хотя его структура довольно проста. Цель теста — определить, является ли нечетное число п простым. Мы выбираем случайное число а, меньшее п (число а называется базисом (basis)), и проверяем наличие опре­ деленного свойства а по модулю п, которое выполняется всегда, когда п яв­ ляется простым числом. Тем не менее мы можем доказать, что, даже если п не является простым числом, это свойство будет выполняться максимум

226

Глава 11. Простые числа

для 25% всех возможных значений базиса. Повторяя этот тест для различ­ ных случайных значений а, можно убедиться в правильности полученного ответа. Если п действительно является простым числом, оно всегда будет проходить тест как простое число. Если не является — это смогут выявить по крайней мере 75% возможных значений а, и вероятность того, что состав­ ное число п успешно пройдет несколько тестов как простое, можно снизить до любого уровня. Мы ограничим вероятность получения неверного результата до 2-128, чтобы достичь запланированного уровня безопасности.

Приведем тест Рабина-Миллера.

ф ун к ц и я R ABIN-M ILLER

вход: п Нечетное число > 3.

выход: b Булево значение, указывающее, является ли п простым чис­ лом.

assert п > 3 Л п mod 2 = 1

Вначале найдем такую пару (s,t), что s — нечетное и 2*s = п — 1. (s ,t)«- ( п - 1,0)

while s mod 2 = 0 do (s, t) «— (s/2, t + 1)

od

Вероятность получения неверного результата будет отслеживать­ ся с помощью переменной к. Эта вероятность не превышает 2~к. Будем прокручивать цикл до тех пор, пока вероятность получения неверного результата не станет достаточно низкой.

fc<- 0

while к < 128 do

Выберем случайное а, такое, что 2 < а < п —1. а е г 2,...,п — 1

Ресурсоемкая операция: возведение в степень по модулю, v <- а5mod п

Если v = 1, п успешно проходит тест для базиса а. if v ф 1 then

Если п — простое число, тогда последовательность v, v2, .. . , v2* должна завершиться числом 1, а последним числом, не рав­ ным единице, должно быть п —1.

i <— 0

while v ф п - 1 do if i = t 1 then return false

11.4 Большие простые числа

227

(г>, г) <— (v2 mod п,г + 1)

fi

od

fi

Если мы добрались до этого этапа, значит, число п успешно прошло проверку на простоту для базиса а. Таким образом, мы сокра­ тили вероятность получения неверного результата в 22 раза, поэтому значение к можно увеличить на 2.

к <— к + 2

od

r e t u r n t r u e

Данный алгоритм работает только для нечетных п, больших или рав­ ных 3, поэтому вначале мы проверяем соответствующее условие. Функция ISPRIME должна вызывать функцию R A B IN -M IL L E R только с корректным ар­ гументом, однако каждая функция сама отвечает за проверку собственных входных и выходных значений. Никто не знает, как программное обеспечение может измениться в будущем.

В основе теста Рабина-Миллера лежит идея, известная как малая теорема Ферма4. Для любого простого числа п и для всех 1 < а < п справедливо от­ ношение an~l mod п = 1. Чтобы понять доказательство этого утверждения, требуется более глубокое знание математики, чем то, на которое ориентиро­ вана эта книга. Небольшой тест (называемый также алгоритмом проверки на простоту Ферма) позволяет доказать это утверждение для ряда случайно выбранных значений а. К сожалению, существует несколько “неприятных” чисел, называемых числами Кармайкла (Carmichael). Эти числа являются составными, но проходят тест Ферма для всех (почти) базисов а.

Тест Рабина-Миллера является разновидностью теста Ферма. Вначале мы записываем п — 1 как 2£s, где s — нечетное число. Если требуется вы­ числить an_1, можно вначале подсчитать а3 и затем возвести полученный результат в квадрат t раз, чтобы получить a3'2* = ап-1. Если a9 = l(modn), тогда многократное возведение в квадрат не изменит результата, поэтому получаем, что an~l = l^modn). Если ^же а3 ф l(modn), тогда мы анали­ зируем числа a3,a3'2, а3’2 ,а3'23, ... ,а3'2* (разумеется, взятые по модулю п). Если п является простым числом, тогда, согласно теореме Ферма, последним элементом приведенной выше последовательности должна быть 1. Отметим также, что если п — простое, тогда единственными числами, удовлетворяю­ щими уравнению х 2 = l(modn), являются 1 и п — 1. (Легко проверить, что

Существует несколько теорем, названных именем Ферма (Fermat). Наибольшую из­ вестность приобрела последняя теорема Ферма, касающаяся уравнения ап + Ьп = с'1. Ее доказательство слишком велико, чтобы приводить его здесь.

228

Глава 11. Простые числа

(n -

I)2 = l(modn).) Таким образом, если п — простое, тогда одно из чи­

сел в этой последовательности должно равняться п 1, так как в противном случае последнее число никогда не будет равно единице. В действительности это и все, что проверяет тест Рабина-Миллера. Если хотя бы одно случайно выбранное а показывает, что число п является составным, мы сразу же воз­ вращаем результат false. Если же п продолжает успешно проходить тест как простое число, мы повторяем проверку для другого значения а до тех пор, по­ ка вероятность получения неверного результата не составит менее чем 2~128.

Если применить этот тест к случайно выбранному числу, вероятность ошибки будет во много раз меньше установленного нами предела. Почти все составные числа п могут быть распознаны тестом Рабина-Миллера при ис­ пользовании практически любых базисов. Создатели многих программных библиотек исходили именно из этого и ограничивались выполнением провер­ ки примерно для 5-10 базисов. Идея в принципе неплоха, хотя нам нужно было исследовать, сколько попыток требуется для достижения уровня ошиб­ ки 2-128 или менее. Однако обратите внимание, что данное утверждение спра­ ведливо только при применении функции ISP RIM E к случайно выбранным числам. Позднее мы столкнемся с ситуациями, когда тест Рабина-Миллера будет применяться к числам, полученным от кого-нибудь другого. Эти числа могут быть выбраны злоумышленником, поэтому функция ISPRIME долж­ на выполнить все необходимые действия для гарантированного достижения уровня ошибки 2-128.

Выполнение всех 64 тестов Рабина-Миллера необходимо тогда, когда чис­ ло, проверяемое на простоту, получено от кого-нибудь другого. Это совершен­ но излишне, когда мы пытаемся сгенерировать простое число случайным об­ разом. С другой стороны, пытаясь сгенерировать простое число, мы потратим бблыную часть времени на отбрасывание составных чисел. (Практически все составные числа будут распознаны в ходе первого же теста Рабина-Миллера.) Поскольку для получения простого числа нам, вероятно, придется отбросить сотни составных чисел, выполнение 64 тестов для простого числа, когда оно в конце концов будет найдено, займет ненамного больше времени, чем вы­ полнение 10 аналогичных тестов.

В более ранней версии этой главы у функции R A BIN -M IL LE R был еще один аргумент, который мог применяться для выбора максимальной вероят­ ности ошибки. Впоследствии он оказался чудесным примером бесполезного параметра, а потому был удален. Гораздо проще (да к тому же и безопаснее применительно к возможности неправильного использования) всегда прово­ дить проверку до тех пор, пока уровень ошибки не снизится до 2-128.

У нас все еще остается вероятность 2“ 128 того, что функция ISP R IM E вы­ даст неверный ответ. Чтобы понять, насколько в действительности мала эта вероятность, представьте себе, что вас убьет случайно залетевший метеорит

11.4 Большие простые числа

229

в то время, когда вы читаете это предложение. Так вот, вероятность этого печального события значительно превышает 2-128. Все еще живы? Тогда не беспокойтесь о функции ISPRIME.

11.4.2Оценивание степеней

Бблыиая часть времени выполнения теста Рабина-Миллера уходит на вы­ числение a3 mod га. Мы не можем вначале подсчитать значение а3 и затем взять его по модулю га. Ни один компьютер в мире не обладает достаточным количеством памяти даже для того, чтобы просто разместить в ней значение а3, не говоря уже о процессорной мощности, необходимой для вычисления последнего. И а и s могут быть в тысячи бит длиной. Вместе с тем нам нуж­ но только a3 mod га. Поэтому мы можем применять операцию mod га ко всем промежуточным результатам, что не позволит числам разрастись до гигант­ ских размеров.

Существует несколько способов вычисления a3mod га, но мы приведем лишь несколько простых соображений. Чтобы подсчитать a3mod га, исполь­ зуйте приведенные ниже правила.

Если 5 = 0, тогда ответом будет 1.

Если 5 > 0 и является четным числом, тогда вначале подсчитайте

 

у := a3!'1 mod п, используя эти же правила. Окончательный результат

 

будет выглядеть следующим образом: a3 mod п = у2 mod га.

Если s > 0 и является нечетным числом, тогда вначале подсчитайте у := а^3-1)/2 mod га, используя эти же правила. Окончательный резуль­ тат будет выглядеть следующим образом: as mod га = а •у2mod га.

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

Сколько операций умножения потребуется, чтобы вычислить as mod га? Пусть к — это число бит значения s; другими словами, 2fc_1 < s < 2к. Тогда данный алгоритм требует выполнения не более чем 2к умножений по моду­ лю га. Это совсем неплохо. Если мы проверяем, является ли простым 2000битовое число, тогда длина s тоже будет составлять около 2000 бит и нам понадобится лишь 4000 вычислений. Этот объем работы, хотя и достаточ­ но большой, определенно доступен вычислительным возможностям большин­ ства настольных компьютеров.

Многие криптографические системы с открытым ключом используют опе­ рации возведения в степень по модулю наподобие рассмотренной выше. Хоро­

230

Глава 11. Простые числа

шая библиотека арифметических операций многократной точности должна иметь оптимизированную функцию для оценки таких операций. С выполне­ нием этой задачи неплохо справляется особый тип умножения, называемый умножением Монтгомери (Montgomery). Существуют также способы вычис­ ления а3 с использованием меньшего количества умножений [10, глава 4]. Каждый из этих приемов может сэкономить от 10 до 30% времени, необ­ ходимого для возведения в степень по модулю, поэтому в комбинации друг с другом они могут принести немалую пользу.

Прямые реализации операций возведения в степень по модулю зачастую бывают чувствительны к тайминг-атакам. Более подробно тайминг-атаки и способы борьбы с ними рассматриваются в главе 16.

Глава 12

Алгоритм Диффи-Хеллмана

Обсуждая вопросы криптографии с открытым ключом, мы собираемся проследить исторический путь ее развития. Впервые понятие криптографии с открытым ключом было введено в 1976 году Уитфилдом Диффи (Whitfield Diffie) и Мартином Хеллманом (Martin Heilman) в опубликованной ими статье New Directions in Cryptography (Новые направления в криптографии) [21].

До сих пор речь шла только о шифровании и аутентификации с общими секретными ключами. Но где же взять эти общие секретные ключи? Если вы хотите общаться, скажем, с 10 друзьями, то можете встретиться и обме­ няться секретными ключами друг с другом для дальнейшего использования в общении. Но, как и все секретные ключи, эти ключи должны подвергаться регулярному обновлению, поэтому вам придется вновь и вновь встречать­ ся и обмениваться ключами. Для группы из 10 друзей нужно 45 секретных ключей. По мере увеличения этой группы количество необходимых ключей возрастает квадратически. Для ста человек, желающих общаться друг с дру­ гом, вам понадобится уже 4950 ключей! Ситуация быстро выходит из-под контроля.

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

Диффи и Хеллман сформулировали этот вопрос, но смогли дать на него лишь частичный ответ. Полученное ими решение известно сегодня как прото­ кол обмена ключами Диффи-Хеллмана (Diffie-Hellman key exchange protocol),

сокращенно DH [21].

232

Глава 12. Алгоритм Диффи-Хеллмана

Идея протокола DH поистине остроумна. Оказывается, что два человека, взаимодействующие друг с другом по небезопасному каналу общения, могут договориться об использовании секретного ключа таким образом, что оба получат один и тот же ключ, не раскрывая его злоумышленнику, который прослушивает канал общения.

12.1Группы

Если вы читали предыдущую главу, то не удивитесь, узнав, что в алго­ ритме Диффи-Хеллмана задействованы простые числа. В этой главе буквой р будет обозначаться большое простое число. Длина р составляет примерно 2000-4000 бит. Большинство вычислений в этой главе выполнены по модулю р, что не всегда будет указано явно. Протокол DH использует Z* — мульти­ пликативную группу по модулю р, которая описана в разделе 11.3.3.

Выберем любой элемент группы д и рассмотрим числа 1,5,<72,53, ••. (ра­ зумеется, взятые по модулю р). Это бесконечная последовательность чисел. С другой стороны, количество элементов группы Z* конечно. (Напомним, что группа Z* состоит из чисел 1,... ,р — 1, для которых определена опера­ ция умножения по модулю р.) По этой причине на каком-то этапе элементы последовательности должны начать повторяться. Предположим, что дг = д*, где г < j. Поскольку мы можем выполнять деление по модулю р, значит, можем поделить каждую сторону этого равенства на д\ в результате чего

получим:

1 = gi~l. Другими словами, существует число q := j — г, такое,

что gq =

l(modp). Назовем наименьшее положительное число q, для кото­

рого выполняется равенство gq = l(modp), порядком (order) числа д. (К со­ жалению, данная тема включает в себя большое количество терминов. Мы предпочитаем использовать стандартную терминологию, а не изобретать соб­ ственные слова. В противном случае читатели нашей книги могут запутаться, обратившись к другой литературе.)

Последовательно возводя д в степень, мы можем получить следующие числа: 1,5,52, •••,9Ч~1- После этого элементы последовательности начнут по­ вторяться, так как gq = 1. Число д называют образующим элементом (gene­ rator) и говорят, что оно порождает множество 1, 5,52, ••. ,д ч~1. Количество элементов, которое может быть представлено в виде степеней 5, в точности равно q, т.е. порядку числа д.

Одно из свойств умножения по модулю р таково: существует по крайней мере одно число д, которое может породить все элементы группы Z*. Другими словами, существует по крайней мере одно д, для которого q = р — 1. Таким образом, вместо того чтобы рассматривать группу Z* как множество чисел 1, — ,р —1, мы можем представить ее и как множество 1, 5, 52, ... )др~2. Число