Алгоритм нахождения простых чисел. Конструктивные техники для простых чисел. Схема алгоритма на базе малой теоремы Ферма

Лекция_4_часть_2.

Арифметические алгоритмы и их применение в криптографии.

Натуральное число p, больше единицы называется простым, если оно делится нацело только на 1 и на себя.

Теорема (Эвклид). Множество простых чисел бесконечно.

Обозначим через p(x) функцию, которая равна числу простых чисел p в интервале 1 < x

x / ln x < p(x) < 1,106 x / ln x .

Простые числа являются важным понятием в криптографии. Многие современные криптографические системы строятся на базе простого числа. Поэтому алгоритмы генерации простых чисел и проверки на простоту сформированного числа являются важными инструментами при создании криптографической системы.

Простые числа встречаются довольно часто.

Заметим, что существует около 10151 простых чисел длиной от 1 до 512 бит включительно , а количество простых чисел меньших 2512 приблизительно равно 2503/ Для чисел близких n вероятность произвольно выбранному числу оказаться простым числом, равна 1/ln(n). При случайном выборе двух простых чисел в диапазоне от 1 до 151 бита вероятность совпадения этих чисел ничтожно мала. Простые числа играют

важную роль в современной криптографии. Многие современные криптографические системы с открытыми (или не симметричными) ключами формируются с применением простых чисел.

Для простых чисел будем рассматривать три задачи:

· построение простых чисел;

· проверка чисел на простоту;

· факторизация (разложения) чисел на простые множители.

На самом деле все эти три задачи фактически дают ответ на один вопрос: является ли рассматриваемое число простым. Но для каждой из этих задач применяются свои методы. Для первой задачи, используя необходимые условия простоты, можно давать ответы типа:

· заданное число n не простое;

· вероятность того, что заданное число n не простое, меньше заданного числа e.

Для второй задачи можно строить некоторую последовательность чисел специального вида. И для чисел данной последовательности применять некоторые тесты до тех пор, пока не найдем среди них простое число.

Приведем некоторые определения, теоремы, алгоритмы, которые связаны с вопросами решения

поставленных задач

Определение 1. Числа Fk = 2a + 1, a = 2k, k = 0, 1, 2, …, называются числами Ферма.

Теорема 1. Число Ферма n = Fk при k > 0 является

простым тогда и только тогда, когда

Определение 2. Пусть p – простое число. Числа вида Mp = называются числами Мерсенна.

Интерес к числам Мерсенна вызван их связью с так называемыми совершенными числами - числами, равными сумме всех своих делителей, отличных, конечно, от самого числа. Ещё Евклид доказал (докажите и вы), что если простое число p имеет вид Mp , то число p(p+1)/2 является совершенным. Например,

3 = 2 2 – 1, 7 = 2 3 – 1

простые числа, и соответственно

Где Mp является числом Мерсенна. Напомним, совершенным числом называется число, которое равносумме всех своих делителей, меньших, чем оно само.

Числа Мерсенна редки. В 2001году было найдено тридцать девятое число Мерсенна для p = 1 3466 917.

Для проверки простоты чисел Мерсенна применяется следующая теорема .

Теорема 2. Пусть p – простое число, p > 2, Mp =

1. Рассмотрим последовательность L0, L1, …, которая

определяется соотношениями

L0 = 4, mod p, 0 ≤ j < p.

Число Mn – простое тогда и только тогда, когда Lq-2 =0 mod p.

ПРОВЕРКА НА ПРОСТОТУ

Простые числа необходимы для большинства криптографических систем с открытыми ключами.

Теоретический материал к вопросу построения больших простых чисел можно найти в и . Здесь будут сформулированы только некоторые практические

подходы к формированию больших простых чисел. Для генерации больших простых чисел могут быть использованы следующие два подхода:

· формируются случайные числа заданного порядка, и при помощи существующих тестов

проверяется, являются ли они простыми.

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

Сначала рассмотрим те тесты, которые используются при реализации первого подхода

формирования простого числа.

Пробное деление

Один из самых простых способов проверки числа p на простоту состоит в последовательном делении числа p на все нечетные числа, которые содержатся в

интервале . Если в процессе деления получим целый результат, то число p – составное. Если же при переборе всех нечетных чисел из интервала

разделить число p на эти числа нацело нельзя, то число p – простое. Данный метод называется пробным делением. Этот метод трудоемок по числу арифметических операций, и он используется в основном для проверки небольших простых чисел.

Решето Эратосфена

Если мы хотим составить таблицу всех простых чисел среди чисел

2, 3,…, N, то надо последовательно вычеркнуть все числа, которые делятся

· на 2, кроме 2;

· на 3, кроме 3;

· на 5 кроме 5;

· на следующее число, которое не вычеркнуто,

кроме этого числа;

и т. д.В итоге среди чисел от 1 до N останутся лишь простые числа. Для реализации метода нужен большой объем памяти ЭВМ, однако для составления таблиц простых чисел он является наилучшим . Более того, разрабатываются специальные процессоры, на которых операции «просеивания» выполняются очень эффективно .

Замечание. Пробное деление и решето Эратосфена можно применять при решении задачи разложения целого числа на множители.

Решето Эратосфена.

Для нахождения всех простых чисел не больше заданного числа n, следуя методу Эратосфена, нужно выполнить следующие шаги:

Выписать подряд все целые числа от двух до n (2, 3, 4, …, n).

Пусть переменная p изначально равна двум - первому простому числу.

Вычеркнуть из списка все числа от 2p до n, делящиеся на p (то есть, числа 2p, 3p, 4p, …)

Найти первое не вычеркнутое число, большее чем p, и присвоить значению переменной p это число.

Повторять шаги 3 и 4 до тех пор, пока p не станет больше, чем n

Все не вычеркнутые числа в списке - простые числа.

На практике, алгоритм можно немного улучшить следующим образом. На шаге №3, числа можно вычеркивать, начиная сразу с числа p2, потому что все составные числа меньше его уже будут вычеркнуты к этому времени. И, соответственно, останавливать алгоритм можно, когда p 2 станет больше, чем n .

Пример для n = 20

Запишем натуральные числа начиная от 2 до 20 в ряд:

Первое число в списке 2 - простое. Пройдём по ряду чисел, вычёркивая все числа кратные 2 (каждое второе, начиная с 2^2 = 4):

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Следующее невычеркнутое число 3 - простое. Пройдём по ряду чисел, вычёркивая все числа кратные 3 (каждое третье, начиная с 3^2 = 9):

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Следующее невычеркнутое число 5 - простое. Пройдём по ряду чисел, вычёркивая все числа кратные 5 (каждое пятое, начиная с 5^2 = 25). И т. д.

Необходимо провести вычёркивания кратных для всех простых чисел p, для которых . В результате все составные числа будут вычеркнуты, а невычеркнутыми останутся все простые числа. Дляn = 20 уже после вычёркивания кратных числу 3 все составные числа получаются вычеркнутыми.

Теорема Вильсона

Для любого P эквивалентны следующие условия:

1). P –простое;

2). (P-1)!=-1 (mod P)

Неэффективен из-за большой трудоемкости.

Малая теорема Ферма утверждает, что если n простое, то выполняется условие: при всех a из {1, 2, …, n −1} имеет место сравнение

an −1 ≡ 1 (mod n ) (1)

Из этой теоремы следует, что если сравнение (1) не выполнено хотя бы для одного числа a в интервале {1, 2, …, n −1}, то n - составное. Поэтому можно предложить следующий вероятностный тест простоты:

выбираем случайное число a из {1, 2, …, n a , n ) = 1;

n - составное»;

проверяем выполнимость сравнения (1);

если сравнение не выполнено, то ответ «n - составное»;

если сравнение выполнено, то ответ неизвестен, но можно повторить тест еще раз.

Числа Кармайкла (Carmichael Numbers)

Особо плохими для теста Ферма являются так называемые числа Кармайкла. Они обладают следующим свойством: для любого a такого, что (a , n ) = 1 верно

Первые три числа Кармайкла таковы: 561, 1105, 1729. Среди первых 100000000 чисел их всего 255. Лишь недавно (1994 г.) было доказано, что таких чисел бесконечно много.

Вероятностный тест Миллера-Рабина

Пусть n - нечетное и n − 1 = 2st , t - нечетное.

Если число n является простым, то при всех a > 1 выполняется сравнение

an −1 ≡ 1 (mod n )

Поэтому, рассматривая элементы {at , a 2t , …, a 2s −1t } можно заметить, что либо среди них найдется равный −1 (mod n ), либо at ≡ 1 (mod n ).

На этом замечании основан следующий вероятностный тест простоты:

выбираем случайное число a из интервала {1, 2, …, n −1} и проверяем с помощью алгоритма Евклида условие (a , n ) = 1;

если оно не выполняется, то ответ «n - составное»;

вычисляем at (mod n );

если at ≡ ±1 (mod n ), то переходим к п. 1;

вычисляем a 2t , …, a 2s −1t до тех пор, пока не появится −1;

если ни одно из этих чисел не равно −1, то ответ «n - составное»;

если мы достигли −1, то ответ неизвестен (и тест можно повторить еще раз).

Составное число не будет определено как составное с вероятностью 1 ⁄ 4. (см. ).

Теорема

Если верна расширенная гипотеза Римана, то достаточно проверять все a из {2, 3, …, +1} (см. ).

Построение больших простых чисел.

Тест на основе малой теоремы Ферма

Малая теорема Ферма утверждает, что если n простое число, то выполняется условие: при всех a Î {2,3, …, n – 1} имеет место сравнение An - 1 º 1 mod n.

На основании этой теоремы можно построить вероятностный алгоритм проверки на простоту числа n.

Если для некоторого целого a из интервала соотношение an - 1 º 1 mod n не выполняется, то число n – составное. Если же теорема выполняется, то вывод, что число n простое, сделать нельзя, так как теорема дает лишь необходимое условие. Поэтому, если

для некоторого a имеет место соотношение an - 1 º 1 mod n, то говорят, что число n является псевдопростым по основанию a . Существует бесконечно много пар чисел a и n, где n – составное и псевдопростое. Вообще для любого a > 1 существуют бесконечно много псевдопростых чисел по основанию a . Вообще, справедливы следующие два утверждения. Если пара (2, n) удовлетворяют сравнению an-1 º 1 mod n, то и пара чисел (2, 2n - 1) также ему удовлетворяют.

· Для любого простого числа n и любого a > 2 такого, что (a2 - 1, n) = 1, число (a2n - 1)/(a2 - 1) является псевдопростым по основанию a.

Определение. Составные числа n, для которых при всех основаниях выполняется сравнение an - 1 º 1 mod n, называются числами Кармайкла.

Дано число n и параметр g = 1 для идентификации

результата проверки.

1) делается случайный выбор целого числа a из интервала ;

2) используя алгоритм Эвклида, вычисляется НОД для чисел a и n;

3) если НОД больше 1, то выполняется шаг 7;

4) для числа a проверяется сравнение an - 1 º 1 mod n;

5) если сравнение не выполняется, то определяется параметр g = 0 (число составное) переход на шаг 7.

6) если сравнение выполнено, то можно повторить тест;

7) выдать результат проверки (g = 0 – число составное).

При завершении работы алгоритма возможны следующие выводы:

· число n – составное (g = 0);

· если g = 1, то число n является либо простым, либо составным и числом Кармайкла.

Здесь уместно заметить , что числа Кармайкла достаточно редки. Так существуют всего 2 163 чисел Кармайкла, которые не превосходят 25 000 000 000, и всего 16 чисел, которые не превосходят числа 100 000.

Схема алгоритма на базе малой теоремы Ферма

Пусть дано нечетное число p. Надо проверить является ли число p простым.

1. Выбирается случайное число a, меньшее p.

2. Если НОД (a, p) ¹ 1, то p – составное число.

3. Вычисляется сравнение L(a, p) º a(p - 1)/2 mod p.

4. Вычисляется символ Якоби J(a, p).

5. Если L(a, p) ¹ J(a, p), то число p – составное.

6. Если L(a, p) = J(a, p), то вероятность того, что

число p – составное не превышает 50 %.

Если проверка повторяется k раз, то вероятность

того, что число p – составное, не превышает 1/2k.

Тест Рабина - Миллера

Обоснование алгоритма Рабина - Миллера можно

найти в . Здесь дадим только самые общие

соображения. Известно, что если число p – простое, то

уравнение x2 º 1 mod p имеет лишь два решения: x º ±1

mod p. Итак, пусть p – нечетное целое число, которое

надо проверить на простоту. Если p – простое, то по

теореме Ферма для любого целого a взаимно простого с

p выполняется сравнение am - 1 º 1 mod p. Так как p - 1 –

четно, то получаем a(m - 1)/2 º ±1 mod p. Если оказывается,

что (m - 1)/2 – четно, то можно повторить рассуждение,

при котором получим, что a(m - 1)/4 º ±1 mod p, и т. д.

Поэтому, чтобы проверить на простоту нечетное

число p, выбираем случайным образом число a из

интервала и вычисляем a t (mod p), a 2 t (mod p0, …, a bt (mod p), где t – нечетное и число b = 2s. Если одно из этих чисел не совпадает с +1 или -1, то можно сделать вывод, что число p является числом составным. Если значения чисел совпадают с +1 или -1, то повторяем этот тест k раз. После повторения этого теста k раз вероятность того, что составное число p не будет выявлено, не превосходит 1/4k. После высказанных соображений перейдем к формулировке алгоритма Рабина - Миллера.

Схема алгоритма Рабина - Миллера

Пусть дано нечетное число p. Надо проверить является ли число p простым. Далее предположим, что p - 1 = 2st.

1. Выбираем случайное число a, меньшее p и

определяем k = 0.

2. Вычисляем с помощью алгоритма Эвклида НОД двух чисел a и p. Если НОД (a, p) ¹ 1, то p – составное число.

3. Вычисляем b º at mod p. Если b = 1 или b = p - 1, то число p вероятно простое.

4. Если b¹ 1 и b ¹ p - 1, то вычисляем b º b2 mod p и k= k + 1.

5. Если число b = p - 1, то число p вероятно простое.

Перейти на шаг 7.

6. Пока k < s выполнять пункт 4.

7. Завершить работу алгоритма.

Рассмотрим примеры.

Пример.

Пусть p = 181. Имеем p - 1 = 45 ´ 22. По

представленному разложению определяем значение

параметра t = 45.

1. Выбираем случайное число a = 52 < p, и

определяем k = 0.

2. Используем алгоритм Эвклида для вычисления

НОД двух чисел 52 и 181:

делим число 181 на число 52, получаем 181 = 52 ·

делим число 52 на число 25, получаем 52 = 25 · 2

делим число 25 на число 2, получаем 25 = 12 · 2 +

делим число 2 на число 1, получаем 2 = 1 · 2 + 0; получаем, что НОД двух чисел 181 и 52 равен 1.

Так как НОД не позволяет установить является ли число 181 составным, то продолжаем выполнять алгоритм Рабина - Миллера.

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

b º 52t mod 181 º 5245 mod 181:

522 mod 181 º 2704 mod 181 º 170 mod 181,

524 mod 181 º 1702 mod 181 º 28900 mod 181 º

528 mod 181 º 1212 mod 181 º 14641 mod 181 º

5216 mod 181 º 1612 mod 181 º 25921 mod 181 º

5232 mod 181 º 382` mod 181 º 1444 mod 181 º

5240 mod 181 º (5232 mod 181)(528 mod 181) º

º (177 ´ 161) mod 181 º 28497 mod 181 º 80 mod

5241 mod 181º (5240 mod 181)(52 mod 181) º (80 ´

º 4160 mod 181 º 178 mod 181,

5245 mod 181 º (5241 mod 181)(524 mod 181) º (178 ´

º 21538 mod 181 = 180 mod 181.

Итак, получили b = 180 = p - 1. Откуда следует, что

число p = 181 вероятно простое.

Замечание.

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

чисел на простоту надо делать при помощи программ на компьютере.

В дается некоторое руководство при генерации простых чисел для практических приложений. Это руководство сводится к реализации нескольких этапов

1. Сгенерируйте случайное n-битовое число p.

2. Установите старший и младший биты равными 1.

Старший бит в этом случае гарантирует требуемую длину простого числа, а младший –

его нечетность.

3. Убедитесь, что число p не делится на малые простые числа 3, 5, 7, 11 и т. д. Наиболее

надежна проверка делимости на все простые числа, меньше 2000.

4. Выполните тест Рабина - Миллера для некоторого случайного числа a. Если p проходит тест, то сгенерируйте другое случайное число a и повторите тест. Для практических приложений достаточно повторить тест Рабина – Миллера пять раз.

5. Если p не проходит один из тестов, надо сгенерировать другое число p и повторить

данное руководство снова.

Другое число p, если оно оказалось не простым, можно получить не генерируя новое, а последовательно перебирая все целые, начиная от p + 1, p + 2, и т. д., пока не найдется простое число.

Перейдем теперь к вопросу о генерировании больших простых чисел.

Построение больших простых чисел и детерминированные алгоритмы проверки чисел на

Простоту/

Рассмотрим еще один способ формирования простых чисел. Этот способ базируется на определенной процедуре генерирования простых чисел, проверка которых осуществляется с помощью тестов на простоту.

Такой подход применяется, например, в стандарте

электронной цифровой подписи (ЭЦП) ГОСТ Р 34.10–94 и

основывается на следующей теореме .

Теорема 5.

Пусть p = qN + 1, где q – нечетное

простое число, N – четное число и p < (2q + 1)2. Число p

является простым, если выполняются два условия:

1) 2qN = 1 mod p;

2) 2N ≠ 1 mod p.

Генерация простого числа с использованием теоремы 5 осуществляется по несколько упрощенной в принятом стандарте схеме . Пусть требуется

сформировать простое число p длины t ≥ 17 бит. С этой целью строится убывающая последовательность чисел {ti}, где i = 0, 1, …, s, для которых t0 = t, ti = .

формулы pi - 1 = piN + 1, где число N удовлетворяет следующим условиям :

· N – четное;

· N – такое, что длина числа pi - 1 = piN + 1 в

точности должна быть равна ti - 1.

В стандарте ГОСТ дается некоторый алгоритм вычисления числа N. Для учебного варианта N –

случайное четное число, которое получают с помощью датчика случайных чисел (если N – нечетно, то N = N + 1).

Число pi - 1 считается полученным, если одновременно выполнены следующие два условия:

1) 2b = 1 mod pi, b = pi - 1N;

2) 2N ≠ 1 mod pi.

Если хотя бы одно из условий не выполняется, то значение числа N увеличивается на 2, и вычисляется

новое значение pi - 1, которое снова проверяется на простоту по двум условиям. Данный процесс продолжается до тех пор, пока не будет получено простое число pi - 1 (т. е. условия 1 и 2 алгоритма генерации простого числа будут выполнены).

Заметим, что с 2002 года вышеупомянутый отечественный стандарт ЭЦП заменен на новый ГОСТ Р 34.10–2001 .

Другим примером является выработка простых чисел p и q для получения модуля n =pq в RSA. В этом случае простые числа должны быть больших размеров и случайными в том смысле, что вероятность выбора любого конкретного простого числа должна быть достаточно малой для того, чтобы не дать злоумышленнику возможность использовать эту вероятность для оптимизации стратегии поиска . Иногда к простым числам могут предъявляться дополнительные требования для того, чтобы они были устойчивы к каким-либо специализированным атакам. Третий пример – выработка неприводимого многочлена f(x) степени m над конечным полем для построения конечного поля . В этом случае также необходима выработка элемента высокого порядка в .

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

Подходы к генерации больших простых чисел

Самым естественным методом является генерация случайного числа n необходимого размера и проверка его на простоту. Это можно сделать, проверяя, является ли какое-нибудь число от 2 до делителем n . На практике требуются более эффективные методы, но общая идея выглядит следующим образом.

1. Генерация случайного числа n необходимого размера, называемого кандидат.

2. Проверка числа n на простоту.

3. Если n – составное, вернуться на первый шаг.

Небольшой модификацией является выбор кандидатов из некоторой последовательности, начинающейся с n . Такой последовательностью является, например, n, n+2, n+4, n+6, … Использование специальных последовательностей позволяет увеличить вероятность того, что кандидат будет простым числом, а также находить простые числа, удовлетворяющие специальным требованиям.

На втором шаге может быть использован тест, однозначно определяющий, если кандидат – простое число (детерминированные тесты) или тест, устанавливающий более слабое утверждение, а именно то, что n – вероятно простое (вероятностные тесты). В последнем случае нужно очень аккуратно относиться к определению. Большинство вероятностных тестов на простоту однозначно определяет, если n – составное, но не обеспечивает математического доказательства простоты числа n , когда оно определяется вероятно простым. Тесты на простоту, которые позволяют однозначно определить, является ли n простым, используются крайне редко, поскольку обычно они требуют гораздо больших вычислительных ресурсов.

Последним различием между различными техниками генерации больших простых чисел является использование «случайности». Обычно кандидаты генерируются как функции от случайных входных данных. Техника для определения простоты числа может использовать или не использовать случайные числа. В некоторых случаях необходимо, чтобы простое число имело дополнительные свойства. К примеру, чтобы сделать извлечение дискретного логарифма стойким к алгоритму Полига-Хеллмана требуется , чтобы p-1 имело большой простой делитель. Поэтому техники для генерации параметров открытых ключей, таких как простые числа специальной формы, должны это учитывать .

Вероятностные тесты на простоту

Далее будут рассмотрены два вероятностных теста на простоту : Соловея-Штрассена (Solovay-Strassen) и Миллера-Рабина (Miller-Rabin). По историческим причинам также представлен тест Ферма (Fermat), однако его нельзя назвать вероятностным тестом на простоту, поскольку он не различает простые числа и особые составные числа, именуемые числами Кармайкла (Carmichael numbers) .

Тест Ферма (Fermat test)

Теорема Ферма утверждает, что если n – простое число и a – любое целое число, тогда . Потому если n – целое число, чья простота под вопросом, нахождение такого a в этом интервале, что это равенство не выполняется, докажет, что n – составное.

И наоборот, если найти целое число a , такое что , утверждается, что n – простое, в том смысле, что оно удовлетворяет теореме Ферма для основания a . Отсюда вытекает следующее определение. Составное n такое, что называется псевдопростым по основанию a . Примером такого числа является число 341 (11 х 31) – оно псевдопростое по основанию 2, поскольку .

Тест Ферма

Выход : Ответ на вопрос является n простым или составным (n – составное или n –простое).

1. В цикле i от 1 до t выполнить: 1.1 Выбрать случайное a : . 1.2 Вычислить . 1.3 Если , тогда вернуть («n – составное»). 2. Вернуть («n – простое»).

Если алгоритм утверждает, что n – составное, то оно однозначно составное. С другой стороны, если алгоритм утверждает, что n – простое, нет никаких гарантий того, что n – действительно простое. Однако, поскольку для заданного основания a псевдопростых чисел не так много, тест Ферма выдает правильный результат на большинстве входных значений, но не на всех .

Составные числа n , удовлетворяющие этому сравнению называются псевдопростыми Эйлера-Якоби (Euler–Jacobi pseudoprime) по основанию a .

Алгоритм Соловея - Штрассена параметризуется количеством раундов k . В каждом раунде случайным образом выбирается число a < n . Если НОД(a,n) > 1 , то выносится решение, что n составное. Иначе проверяется справедливость сравнения . Если оно не выполняется, то выносится решение, что n - составное. Если это сравнение выполняется, то a является свидетелем простоты числа n . Далее выбирается другое случайное a , и процедура повторяется. После нахождения k свидетелей простоты в k раундах выносится заключение, что n является простым числом с вероятностью .

Тест Соловея-Штрассена

Вход: n > 2, тестируемое нечётное натуральное число;

k - параметр, определяющий точность теста.

Выход : составное, означает, что n точно составное;

n вероятно является простым.

1.В цикле i от 1 до k выполнить: 1.1. Выбрать a - случайное целое от 2 до n-1 , включительно; 1.2. Если НОД(a, n) > 1, тогда вернуть (составное); 1.3.Если , тогда вернуть (составное). 2.Вернуть (простое с вероятностью ).

Тест Миллера-Рабина (Miller-Rabin test)

Тест Миллера - Рабина - вероятностный полиномиальный тест простоты. Тест Миллера - Рабина позволяет эффективно определять, является ли данное число составным. Однако, с его помощью нельзя строго доказать простоту числа. Тем не менее, тест Миллера - Рабина часто используется в криптографии для получения больших случайных простых чисел.

Алгоритм был разработан Гари Миллером (Gary Miller) в 1976 году и модифицирован Майклом Рабином (Michael Rabin) в 1980 году.

Пусть n - нечётное число большее 1. Число n-1 однозначно представляется в виде , где t нечётно. Целое число a , 1 < a < n , называется свидетелем простоты числа n , если выполняется одно из условий:

Существует целое число k , такое, что .

Теорема Рабина утверждает, что составное нечётное число n имеет не более различных свидетелей простоты, где - функция Эйлера (Euler"s phi function) .

Тест Миллера-Рабина

Алгоритм Миллера - Рабина параметризуется количеством раундов r . Рекомендуется брать r порядка величины , где n - проверяемое число.

Для данного n находятся такие целое число s и целое нечётное число t , что . Выбирается случайное число a , 1 < a < n . Если a не является свидетелем простоты числа n , то выдается ответ «m - составное», и алгоритм завершается. Иначе, выбирается новое случайное число a , и процедура проверки повторяется. После нахождения r свидетелей простоты выдается ответ «n - вероятно простое», и алгоритм завершается.

Вход : n > 2, нечётное натуральное число, которое необходимо проверить на простоту;

r - количество раундов.

Выход : составное, означает, что n является составным числом;

вероятно простое, означает, что n с высокой вероятностью является простым числом.

1. Представить n − 1 в виде , где t нечётно, можно сделать последовательным делением n - 1 на 2. 2. В цикле по i от 1 до r выполнить: 2.1. Выбрать случайное целое число a в отрезке . 2.2. , вычисляется с помощью алгоритма возведения в степень по модулю. 2.3. Если x = 1 или x = m − 1 , то перейти на следующую итерацию цикла 2. 2.4. В цикле по j от 1 до s − 1 выполнить: 2.4.1. . 2.4.2. Если x = 1, то вернуть (составное). 2.4.3. Если x = m − 1 , то перейти на следующую итерацию цикла 2. 2.5. Вернуть (составное). 3. Вернуть (вероятно простое).

Из теоремы Рабина следует, что если r случайно выбранных чисел оказались свидетелями простоты числа n , то вероятность того, что n составное, не превосходит .

Детерминированные тесты на простоту

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

Проверка чисел Мерсенна (Mersenne primes)

Существуют эффективные алгоритмы для проверки простоты некоторых особых классов чисел, таких как числа Мерсенна и числа Ферма . Особенно важными считаются именно числа Мерсенна , поскольку для них сложение в поле может быть произведено очень эффективно.

Этот факт приводит нас к детерминированному алгоритму проверки простоты числа Мерсенна за полиномиальное время.

Тест Люка-Лемера (Lucas–Lehmer primality test)

Выход : простое или составное.

1. Проверить наличие делителей у s в промежутке от 2 до ; 2. Если найден хоть один, то вернуть (составное); 3. Установить u = 4 ; 4. В цикле по k от 1 до s-2 выполнить ; 5.Если u = 0 вернуть (простое), в противном случае вернуть (составное).

На сентябрь 2013 года самым большим известным простым числом является число Мерсенна , найденное 25 января 2013 года Кертисом Купером (Curtis Cooper) в рамках проекта распределённых вычислений GIMPS . Десятичная запись числа n содержит 17 425 170 цифр.

Всего известно 48 простых чисел Мерсенна, причём порядковые номера с уверенностью установлены только у первых 42-х. Интересно отметить, что 46-е найденное простое число Мерсенна было найдено на две недели позднее 45-го найденного простого числа Мерсенна и оказалось меньше его.

Также существуют тесты на простоту, использующие факторизацию числа n-1 , эллиптические кривые , и другие, однако они довольно громоздки и потому не будут рассматриваться здесь.

Генерация простых чисел

В этом подразделе будут рассмотрены алгоритмы генерации простых чисел для криптографических целей.

Случайный поиск вероятно простых чисел

Как уже отмечалось выше, простейшим способом является случайный выбор числа необходимого размера и проверка его вероятностным тестом на простоту, например, тестом Миллера-Рабина. Однако, если кандидат n делится на малое простое число, проверка делимости на небольшие простые числа позволит отбросить не прошедшего кандидата n быстрее, чем по алгоритму Миллера-Рабина. Поскольку вероятность того, что случайное целое число имеет небольшой простой делитель, достаточно высока, до применения теста Миллера-Рабина стоит проверить n на простые делители до некоторой границы B . Это можно сделать последовательным делением n на все простые числа, меньше B или вычислением НОД n и произведения нескольких простых чисел, меньших B .

Случайный поиск простого числа с использованием теста Миллера-Рабина.

Вход : целое число k , параметр безопасности t .

Выход : случайное вероятно простое целое число длиной k бит.

1. Сгенерировать случайное число n длиной k бит; 2. Использовать деление n на простые числа, меньше B для проверки существования простого делителя; 3. Если хотя бы один найден – вернуться на шаг 1; 4. Проверить простоту n тестом Миллера-Рабина; 5. Если n – вероятно простое, то вернуть (n ), в противном случае вернуться на шаг 1.

Генерация сильно простых чисел

Вход : целое число l в интервале от 0 до 8.

Выход : 160-битное простое число q , L -битное простое число p , где L=512+64l и q|(p-1)

1. Вычислить L = 512+64l . Найти n , b : L-1 = 160n+b , где b в интервале от 0 до 159; 2. В цикле выполнить следующее: 2.1. Выбрать случайное число s (не обязательно хранить его в секрете) длины g больше или равной 160; 2.2. Вычислить ; 2.3. Сформировать q , установив самый старший и самый младший биты U в 1; 2.4. Проверить q на простоту тестом Миллера-Рабина с параметром t > 17; 2.5. Если q – составное, то вернуться на шаг 2; 3. Установить i =0, j =2; 4. В цикле пока i < 4096 выполнить: 4.1. В цикле для k от 0 до n выполнить: Установить ; 4.2. Для целого числа , определить ; 4.3. Вычислить и установить p = X – (c-1); 4.4. Если тогда выполнить: 4.4.1. Проверить p на простоту тестом Миллер-Рабина для параметра t > 4; 4.4.2. Если p – вероятно простое, вернуть (q,p ); 4.5. Установить i=i+1 , j=j+n+1 ; 5. Вернуться на шаг 2.

Конструктивные техники для простых чисел

Алгоритм Морера (Maurer’s algorithm) генерирует случайные однозначно простые числа, которые почти равномерно распределены над множеством всех простых чисел необходимого размера. Ожидаемое время генерации немногим больше, чем генерация вероятно простого числа алгоритмом случайного поиска простого числа с параметром t =1 .

Пусть n > 2 – целое число и предположим, что n=1+2Rq , где q – простое и q > R .

1. Если существует целое число a : и , то n – простое.

2. Если n – простое, вероятность, что случайно выбранное число a удовлетворяет условиям и , равна .

Алгоритм Морера рекурсивно генерирует простое число q и затем выбирает целые числа R < q , пока не будет доказано по первому пункту вышеописанной теоремы, что n=1+2Rq – простое по некоторому основанию a .

Алгоритм Морера

Вход : положительное целое число k .

Выход : простое число n длины k бит.

1. Если k < 21 тогда в цикле выполнить: 1.1. Выбрать случайное целое число n длины k бит; 1.2. Последовательно поделить n на все простые числа от 2 до ; 1.3. Если нашелся хоть один делитель, вернуться на шаг 1, в противном случае вернуть (n ); 2. Установить c = 0.1, m = 20; 3. Установить ; 4. Если k > 2m тогда в цикле выполнить: выбрать случайное число s в интервале , установить до тех пор пока (k - rk) > m . В противном случае установить r = 0.5; 5. Вычислить q , как результат алгоритма Морера с параметром (); 6. Установить ; 7. Установить success=0; 8. Пока success=0 выполнить в цикле: 8.1. Выбрать случайное целое число R в интервале [I+1, 2I ] и установить n = 2Rq + 1 ; 8.2. Использовать деление n на простые числа < B для нахождения простых делителей: 8.3. Если простые делители не найдены выполнить: 8.3.1. Выбрать случайное целое a в интервале ; 8.3.2. Вычислить ; 8.3.3. Если b = 1 выполнить: 8.3.1.1. Вычислить ; 8.3.1.2. Если d =1 установить success = 1; 9.Вернуть (n ).

Неприводимые многочлены

2. Пусть f(x) - полином степени m в . Тогда f(x) неприводим над тогда и только тогда, когда .

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

Вход : Простое число p и нормированный многочлен f(x) степени m в .

Выход : Ответ на вопрос, приводим ли многочлен f(x) над .

1. Установить u(x)=x ; 2. В цикле по i от 1 до выполнить: 2.1. Вычислить ; 2.2. Вычислить d(x) = НОД (f(x), u(x)-x) ; 2.3. Если вернуть (приводимый); 3. Вернуть (неприводимый).

Отсюда следует метод для нахождения неприводимого многочлена степени m в – сгенерировать случайный нормированный многочлен степени m в , проверить его на неприводимость и повторять до тех пор, пока неприводимый многочлен не будет найден. Число многочленов, которые необходимо перебрать для того, чтобы найти неприводимый многочлен в среднем равно m .

Генерация случайного нормированного неприводимого многочлена над

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

Теорема 4. Пусть нечетные натуральные числа, причем для каждого простого делителя числа 5 существует целое число а такое, что

Тогда каждый простой делитель числа N удовлетворяет сравнению

Доказательство. Пусть простой делитель числа некоторый делитель 5. Из условий (10) следует, что в поле вычетов справедливы соотношения

Обозначим буквой порядок элемента а в мультипликативной группе поля Первые два из соотношений (11) означают, что входит в разложение на простые множители числа в степени такой же, как и в разложение последнее - что делится на Таким образом, каждый простой делитель числа 5 входит в разложение в степени не меньшей, чем в так что делится на 5. Кроме того, четно. Теорема 2 доказана.

Следствие. Если выполнены условия теоремы то простое число.

Действительно, пусть N равняется произведению не менее двух простых чисел. Каждое из них, согласно утверждению теоремы 2, не меньше, чем Но тогда Противоречие и доказывает следствие.

Покажем теперь, как с помощью последнего утверждения, имея большое простое число 5, можно построить существенно большее простое число Выберем для этого случайным образом четное число на промежутке положим Затем проверим число N на отсутствие малых простых делителей, разделив его на малые простые числа; испытаем N некоторое количество раз с помощью алгоритма 5. Если при этом выяснится, что составное число, следует выбрать новое значение и опять повторить вычисления. Так следует делать до тех пор, пока не будет найдено число выдержавшее испытания алгоритмом достаточно много раз. В этом случае появляется надежда на то, что простое число, и следует попытаться доказать простоту с помощью тестов теоремы 2.

Для этого можно случайным образом выбирать число и проверять для него выполнимость соотношений

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

Предположим, что построенное число N действительно является простым. Зададимся вопросом, сколь долго придется перебирать числа а, пока не будет найдено такое, для которого будут выполнены условия (12). Заметим, что для простого числа N первое условие (12), согласно малой теореме Ферма, будет выполняться всегда. Те же числа а, для которых нарушается второе условие (12), удовлетворяют сравнению Как известно, уравнение в поле вычетов имеет не более решений. Одно из них Поэтому на промежутке имеется не более чисел, для которых не выполняются условия (12). Это означает, что, выбирая случайным образом числа а на промежутке при простом N можно с вероятностью большей, чем найти число а, для которого будут выполнены условия теоремы 2, и тем доказать, что N действительно является простым числом.

Заметим, что построенное таким способом простое число N будет удовлетворять неравенству т. е. будет записываться вдвое большим количеством цифр, чем исходное простое число 5. Заменив теперь число 5 на найденное простое число N и повторив с этим

новым S все указанные выше действия, можно построить еще большее простое число. Начав с какого-нибудь простого числа, скажем, записанного 10 десятичными цифрами (простоту его можно проверить, например, делением на маленькие табличные простые числа), и повторив указанную процедуру достаточное число раз, можно построить простые числа нужной величины.

Обсудим теперь некоторые теоретические вопросы, возникающие в связи с нахождением простых чисел вида где числа удовлетворяют неравенствам Прежде всего, согласно теореме Дирихле, доказанной еще в 1839 г., прогрессия содержит бесконечное количество простых чисел. Нас интересуют простые числа, лежащие недалеко от начала прогрессии. Оценка наименьшего простого числа в арифметической прогрессии была получена в 1944 г. Ю.В. Линником. Соответствующая теорема утверждает, что наименьшее простое число в арифметической прогрессии не превосходит где С - некоторая достаточно большая абсолютная постоянная. В предположении справедливости расширенной гипотезы Римана можно доказать, , что наименьшее такое простое число не превосходит при любом положительном

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

Очень важен в связи с описываемым методом построения простых чисел также вопрос о расстоянии между соседними простыми числами в арифметической прогрессии. Ведь убедившись, что при некотором число составное, можно следующее значение взять равным и действовать так далее, пока не будет найдено простое число И если расстояние между соседними простыми числами в прогрессии велико, нет надежды быстро построить нужное число Перебор чисел до того момента, как мы наткнемся на простое число N окажется слишком долгим. В более простом вопросе о расстоянии между соседними простыми числами в натуральном ряде доказано лишь, что что, конечно, не очень хорошо для наших целей. Вместе с тем существует так называемая гипотеза Крамера (1936 г.), что дающая вполне приемлемую оценку. Примерно такой же результат следует и из расширенной гипотезы Римана. Вычисления на ЭВМ показывают, что простые

числа в арифметических прогрессиях расположены достаточно плотно.

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

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

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

2 3 5 7 11 13 17 19 23 29 31… $250.000…

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

Алгоритм был придуман и тутже реализован на изучаемом языке. Программа запрашивала у пользователя число N и искала все простые числа до N включительно. После первого успешного теста сразу же возникло непреодолимое желание ввести N = «много». Программа работала, но не так быстро как хотелось бы. Естественно, дело было в многочисленных проверках (порядка N*N/2), поэтому пришлось избавиться от лишних. В итоге получилось 5 похожих алгоритмов каждый из которых работал быстре предыдущего. Недавно захотелось их вспомнить и реализовать, но на этот раз на Python.

Итак, поехали. Первый алгоритм, ударивший в студенческую голову, продемонстрирован в Листинге 1.
# Листинг 1 # вводим N n = input("n=") # создаем пустой список для хранения простых чисел lst = # в k будем хранить количество делителей k = 0 # пробегаем все числа от 2 до N for i in xrange(2, n+1): # пробегаем все числа от 2 до текущего for j in xrange(2, i): # ищем количество делителей if i % j == 0: k = k + 1 # если делителей нет, добавляем число в список if k == 0: lst.append(i) else: k = 0 # выводим на экран список print lst
Очень быстро понимаешь, что в подсчете делителей каждого числа нет никакой надобности и поэтому переменную k можно освободить от своих обязанностей. Действительно, если хотябы один делитель имеется, то число уже не простое. Смотрим Листинг 2.
# Листинг 2 n = input("n=") lst = for i in xrange(2, n+1): for j in xrange(2, i): if i % j == 0: # если делитель найден, число не простое. break else: lst.append(i) print lst
Конструкция break позволяет нам завершить выполнение внутреннего цикла и перейти к следующей итерации внешнего.
Далее возникает вопрос: «а зачем делить на 4, если на 2 число не делится?». Приходим к выводу, что искать делители нужно только среди простых чисел не превышающих делимое. Наш алгоритм превращается в… см. Листинг 3.
# Листинг 3 n = input("n=") lst= for i in xrange(2, n+1): # пробегаем по списку (lst) простых чисел for j in lst: if i % j == 0: break else: lst.append(i) print lst
А потом вспоминаем теорию чисел и понимаем, что переберать надо только числа, не превосходящие корня из искомого. К примеру, если число M имеет делитель pi, то имеется делитель qi, такой, что pi * qi = M. То есть, чтобы найти пару, достаточно найти меньшее. Среди всех пар, предполагаемая пара с максимальным наименьшим - это пара с равными pi и qi, то есть pi * pi = M => pi = sqrt(M). Смотрим Листинг 4.
# Листинг 4 from math import sqrt n = input("n=") lst= for i in xrange(2, n+1): for j in lst: if j >
Код из Листинга 4 при N=10000 выполняется примерно в 1000 раз быстрее, чем самый первый вариант. Есть еще один «ускоритель», проверять только те числа, которые заканчиваются на 1, 3, 7 или 9 (так как остальные очевидно делятся на 2 или 5). Наблюдаем Листинг 5.
# Листинг 5 from math import sqrt n = input("n=") lst= for i in xrange(2, n+1): if (i > 10): if (i%2==0) or (i%10==5): continue for j in lst: if j > int((sqrt(i)) + 1): lst.append(i) break if (i % j == 0): break else: lst.append(i) print lst
В следствии незначительного изменения Листинга 5 получаем небольшую прибавку в скорости:
# Листинг 6 from math import sqrt n = input("n=") lst= for i in xrange(3, n+1, 2): if (i > 10) and (i%10==5): continue for j in lst: if j > int((sqrt(i)) + 1): lst.append(i) break if (i % j == 0): break else: lst.append(i) print lst
Итого: Программа из последнего листинга выполняется, примерно, в 1300 раз быстрее первоначального варианта.
Я не ставил перед собой задачи написать программу максимально быстро решающую данную задачу, это скорее демонстрация начинающим программистам того, что правильно составленный алгоритм играет далеко не последнюю роль в оптимизации Ваших программ.

P.S.
Благодаря замечаниям получаем Листинг 7:
# Листинг 7 n = input("n=") lst= for i in xrange(3, n+1, 2): if (i > 10) and (i%10==5): continue for j in lst: if j*j-1 > i: lst.append(i) break if (i % j == 0): break else: lst.append(i) print lst

При N=10000, поучаем время:
time 1 = 26.24
time 2 = 3.113
time 3 = 0.413
time 4 = 0.096
time 5 = 0.087
time 6 = 0.083
time 7 = 0.053

Решето Эратосфена:
# Листинг 8 n = input("n=") a = range(n+1) a = 0 lst = i = 2 while i <= n: if a[i] != 0: lst.append(a[i]) for j in xrange(i, n+1, i): a[j] = 0 i += 1 print lst

Результаты при n = 1 000 000:
time 7 = 7.088
time 8 = 1.143

k {\displaystyle k} , на алгоритм генерации которого накладываются определенные ограничения. Получение случайных простых чисел является неотъемлемой частью процедур выработки ключей во многих криптографических алгоритмах, включая RSA и ElGamal .

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

Требования к алгоритму и его реализации

Требования к алгоритмам генерации случайных простых чисел сводятся к следующим двум:

  • Распределение получаемых простых чисел должно быть близко к равномерному на множестве всех k -битных простых чисел. Существует несколько способов обеспечить выполнимость этого требования.
  • Процесс генерации конкретного случайного простого числа нельзя воспроизвести, даже зная детали алгоритма и его реализации. Обычно выполнение этого требования обеспечивается использованием криптостойкого ГПСЧ , проинициализированного некоторым ключом , получаемым извне (т. е. не являющимся частью алгоритма или его реализации). В качестве ключа может выступать, например, значение криптографической хеш-функции от секретной фразы, запрашиваемой у пользователя.

Типовые алгоритмы генерации случайных простых чисел

Везде далее предполагается использование криптографически стойкого ГПСЧ , проинициализированного с помощью секретного ключа (детали зависят от используемого ГПСЧ и способа получения и представления ключа).

Тестирование простоты

Проверить (вероятную) простоту числа p , содержащего k битов, можно так:

  1. Убедиться, что p не делится на небольшие простые числа 3, 5, 7, 11, и т.д. до некоторого небольшого предела (например, 256). Такая проверка позволяет эффективно отсечь множество заведомо составных чисел, прежде чем проверять их посредством более трудоёмких алгоритмов. Так, проверка делимости p на простые числа 2, 3, 5 и 7 отсеивает все четные числа и 54% нечетных чисел, проверка делимости p на все простые числа до 100 отсеивает 76% нечетных чисел, а проверка делимости p на все простые числа до 256 отсеивает 80% нечетных чисел.
  2. Выполнить тест Миллера - Рабина с количеством раундов не меньше k .

Если число p не проходит хотя бы одной проверки - оно не является простым. В противном случае с большой вероятностью (зависящей от количества раундов) число p является простым.

Прямое построение

Второй шаг можно ускорить, если рассматривать только нечетные числа или числа сравнимые с 1 и 5 по модулю 6 и т.п.

(n -1)-методы

(n -1)-методы построения простых чисел используют знание о простых делителях числа n -1 для тестирования простоты n с помощью