Тест Миллера — Рабина
Тест Миллера — Рабина — это вероятностный полиномиальный тест простоты, предназначенный для определения того, является ли натуральное число составным или, вероятно, простым. Алгоритм основан на проверке свойств чисел, вытекающих из малой теоремы Ферма и свойств квадратичных вычетов. В отличие от детерминированных тестов (например, решета Эратосфена), тест Миллера — Рабина не даёт абсолютной гарантии простоты, но позволяет с высокой степенью достоверности отличить простые числа от составных. Тест широко используется в криптографии, в частности, при генерации больших простых чисел для алгоритмов RSA и Диффи — Хеллмана.
История
Тест был предложен американским математиком Гари Миллером в 1976 году. Первоначальная версия Миллера была детерминированной, однако её корректность зависела от недоказанной обобщённой гипотезы Римана (ОГР). В 1980 году израильский учёный Михаэль Рабин модифицировал алгоритм, сделав его вероятностным и устранив зависимость от ОГР. Рабин показал, что если выбрать несколько случайных оснований проверки, то вероятность ошибки может быть сделана сколь угодно малой. С тех пор тест Миллера — Рабина стал одним из наиболее практичных и распространённых методов проверки чисел на простоту.
Математические основы
Тест опирается на два ключевых свойства простых чисел:
- Малая теорема Ферма: Если \( p \) — простое число и \( a \) — целое число, не кратное \( p \), то \( a^{p-1} \equiv 1 \pmod{p} \).
- Свойство квадратичных вычетов: Если \( p \) — простое нечётное число, то сравнение \( x^2 \equiv 1 \pmod{p} \) имеет только два решения: \( x \equiv 1 \) и \( x \equiv -1 \).
Из второго свойства следует, что если для некоторого числа \( n \) существует такое \( a \), что \( a^2 \equiv 1 \pmod{n} \), но \( a \not\equiv \pm 1 \pmod{n} \), то \( n \) — составное. Такое \( a \) называется нетривиальным квадратным корнем из единицы по модулю \( n \). Нахождение нетривиального корня является свидетельством составности числа.
Тест Миллера — Рабина использует представление числа \( n-1 \) в виде \( n-1 = d \cdot 2^s \), где \( d \) — нечётное число, а \( s \geq 0 \). Затем для выбранного основания \( a \) вычисляется последовательность:
- \( x_0 = a^d \mod n \)
- \( x_1 = x_0^2 \mod n \)
- \( x_2 = x_1^2 \mod n \)
...
- \( x_s = x_{s-1}^2 \mod n = a^{n-1} \mod n \)
Если \( n \) простое, то в силу малой теоремы Ферма \( x_s \) должно быть равно 1. Кроме того, если на каком-либо шаге \( x_k = 1 \), а предыдущее значение \( x_{k-1} \) не равно \( \pm 1 \), то это означает нахождение нетривиального корня, и \( n \) — составное.
Алгоритм
Алгоритм принимает на вход нечётное число \( n > 2 \) (чётные числа, кроме 2, сразу отбрасываются) и параметр надёжности \( k \), определяющий количество испытаний. Если \( n = 2 \), оно сразу признаётся простым. Если \( n \) чётное или меньше 2, оно составное.
- Представить \( n-1 \) как \( d \cdot 2^s \), где \( d \) — нечётное.
- Повторить \( k \) раз:
- Выбрать случайное целое число \( a \) в интервале \( [2, n-2] \).
- Вычислить \( x = a^d \mod n \).
- Если \( x = 1 \) или \( x = n-1 \), перейти к следующей итерации (число не опровергнуто).
- Для \( r \) от 1 до \( s-1 \):
- \( x = x^2 \mod n \).
- Если \( x = n-1 \), перейти к следующей итерации.
- Если \( x = 1 \), то число \( n \) — составное (найден нетривиальный корень).
- Если цикл завершился без обнаружения \( n-1 \), число \( n \) — составное.
- Если после \( k \) итераций не найдено свидетельств составности, число объявляется вероятно простым.
Вероятность ошибки
Каждое испытание со случайным основанием \( a \) может дать один из трёх результатов:
- Свидетель простоты — \( a \) не доказывает составность.
- Свидетель составности — \( a \) доказывает, что \( n \) составное.
Для составного нечётного числа \( n \) доля свидетелей составности среди всех чисел \( a \) в интервале \( [2, n-2] \) составляет не менее \( 3/4 \). Это означает, что вероятность того, что одно случайное основание не обнаружит составность, не превышает \( 1/4 \). После \( k \) независимых испытаний вероятность того, что составное число будет ошибочно признано простым, не превышает \( (1/4)^k \).
На практике для криптографических приложений обычно выбирают \( k = 20 \), что даёт вероятность ошибки менее \( 10^{-12} \). Для ещё большей надёжности можно увеличить \( k \) до 40 или 64.
Примеры работы
Пример 1: Простое число (n = 17)
\( n = 17 \), \( n-1 = 16 = 1 \cdot 2^4 \), \( d = 1, s = 4 \).
Выберем случайное основание, например \( a = 3 \).
- \( x_0 = 3^1 \mod 17 = 3 \)
- \( x_1 = 3^2 = 9 \mod 17 = 9 \)
- \( x_2 = 9^2 = 81 \mod 17 = 13 \) (так как \( 81 - 4\cdot 17 = 81 - 68 = 13 \))
- \( x_3 = 13^2 = 169 \mod 17 = 16 \) (так как \( 169 - 9\cdot 17 = 169 - 153 = 16 \)) — это \( n-1 \).
Условие \( x_r = n-1 \) выполнено, поэтому \( a = 3 \) является свидетелем простоты для \( n = 17 \). После нескольких таких испытаний (если все они дают аналогичный результат) число признаётся вероятно простым.
Пример 2: Составное число (n = 15, число Кармайкла)
\( n = 15, n-1 = 14 = 7 \cdot 2^1, d = 7, s = 1 \).
Выберем основание \( a = 2 \):
- \( x_0 = 2^7 \mod 15 = 128 \mod 15 = 8 \)
- \( x_1 = 8^2 \mod 15 = 64 \mod 15 = 4 \)
Ни одно из условий \( x = 1 \) или \( x = n-1 = 14 \) не выполняется. Число 15 объявляется составным. Действительно, \( 15 = 3 \times 5 \).
Достоинства и недостатки
Достоинства
- Высокая скорость: время выполнения пропорционально \( O(k \log^3 n) \), что позволяет проверять тысячи чисел в секунду, включая числа длиной в сотни десятичных знаков.
- Простота реализации: алгоритм легко программируется на любом языке.
- Управляемая точность: вероятность ошибки экспоненциально убывает с ростом числа испытаний.
- Отсутствие ложноположительных результатов: если тест объявил число составным, это всегда верно. Ошибки возможны только в сторону «вероятно простое» для составных чисел.
Недостатки
- Вероятностная природа: в отличие от теста AKS, тест Миллера — Рабина не даёт абсолютной гарантии простоты. Для криптографических задач это обычно приемлемо, но для математических доказательств требуется дополнительная верификация.
- Чувствительность к качеству генератора случайных чисел: плохой ГСЧ может снизить эффективную надёжность теста.
- Не применим к числам Мерсенна: для чисел вида \( 2^p - 1 \) существуют более эффективные специализированные тесты (тест Люка — Лемера).
Применение
Основная область применения теста Миллера — Рабина — криптография. Он используется:
- При генерации ключей для алгоритмов RSA, DSA, ECDSA.
- В протоколах Диффи — Хеллмана для выбора безопасных простых чисел.
- В системах цифровой подписи и шифрования с открытым ключом.
- В стандартах криптографической защиты, таких как ГОСТ Р 34.10-2012 и NIST SP 800-89.
Кроме того, тест применяется в теории чисел для быстрой проверки больших чисел на простоту перед более сложными детерминированными тестами.
Варианты и улучшения
- Тест Миллера — Рабина с фиксированными основаниями: для чисел определённого размера можно использовать небольшой набор оснований, гарантирующих детерминированную проверку. Например, для \( n < 2^{64} \) достаточно оснований \( \{2, 3, 5, 7, 11, 13\} \).
- Комбинированные тесты: часто тест Миллера — Рабина используется вместе с тестом Люка (например, тест Baillie-PSW), что повышает надёжность без существенного увеличения времени.
- Параллельные реализации: алгоритм легко распараллеливается, что ускоряет проверку больших наборов чисел.
Источники
- Miller, G. (1976). «Riemann's Hypothesis and Tests for Primality». Journal of Computer and System Sciences.
- Rabin, M. O. (1980). «Probabilistic algorithm for testing primality». Journal of Number Theory.
- Crandall, R., Pomerance, C. (2005). «Prime Numbers: A Computational Perspective». Springer.
- Menezes, A., van Oorschot, P., Vanstone, S. (1996). «Handbook of Applied Cryptography». CRC Press.
- Cormen, T. H., Leiserson, C. E., Rivest, R. L., Stein, C. (2009). «Introduction to Algorithms». MIT Press.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →