Это не официальный сайт wikipedia.org 01.01.2023

Ро-алгоритм Полларда — Википедия

Ро-алгоритм Полларда

Ро-алгоритм ( ρ -алгоритм) — предложенный Джоном Поллардом[en] в 1975 году алгоритм, служащий для факторизации (разложения на множители) целых чисел. Данный алгоритм основывается на алгоритме Флойда поиска длины цикла в последовательности и некоторых следствиях из парадокса дней рождения. Алгоритм наиболее эффективен при факторизации составных чисел с достаточно малыми множителями в разложении. Сложность алгоритма оценивается как O ( N 1 / 4 ) [1].

Числовая последовательность зацикливается, начиная с некоторого n. Цикл может быть представлен в виде греческой буквы ρ.

ρ-алгоритм Полларда строит числовую последовательность, элементы которой образуют цикл, начиная с некоторого номера n, что может быть проиллюстрировано, расположением чисел в виде греческой буквы ρ, что послужило названием семейству алгоритмов[2][3].

История алгоритмаПравить

В конце 60-х годов XX века Роберт Флойд придумал достаточно эффективный метод решения задачи нахождения цикла, также известный, как алгоритм «черепаха и заяц»[4]. Джон Поллард, Дональд Кнут и другие математики проанализировали поведение этого алгоритма в среднем случае. Было предложено несколько модификаций и улучшений алгоритма[5].

В 1975 году Поллард опубликовал статью[6], в которой он, основываясь на алгоритме Флойда обнаружения циклов, изложил идею алгоритма факторизации чисел, работающего за время, пропорциональное N 1 / 4  [6][1]. Автор алгоритма назвал его методом факторизации Монте-Карло, отражая кажущуюся случайность чисел, генерируемых в процессе вычисления. Однако позже метод всё-таки получил своё современное название — ρ-aлгоритм Полларда[7].

В 1981 году Ричард Брент и Джон Поллард с помощью алгоритма нашли наименьшие делители чисел Ферма F n = 2 2 n + 1   при 5 n 13  [8]. Скорость алгоритма сильно зависит лишь от величины наименьшего делителя исходного числа, но не от самого числа. Так, поиск наименьшего делителя седьмого числа Ферма — F 7 = 340282366920938463463374607431768211457 = 59 649 589 127 497 217 5 704 689 200 685 129 054 721 ;  , занимает гораздо больше времени, чем поиск делителя двенадцатого числа Ферма (т.к. его делитель 114689 значительно меньше, хотя само число состоит более чем из 1200 десятичных цифр).

В рамках проекта «Cunningham project[en]» алгоритм Полларда помог найти делитель длиной 19 цифр числа 2 2386 + 1  . Большие делители также могли бы быть найдены, однако открытие метода факторизации с помощью эллиптических кривых сделало алгоритм Полларда неконкурентоспособным[9].

Описание алгоритмаПравить

Оригинальная версияПравить

Рассматривается последовательность целых чисел x n  , такая что x 0 = 2   и x i + 1 = ( x i 2 1 ) ( m o d N )  , где N   — число, которое нужно факторизовать. Оригинальный алгоритм выглядит следующим образом[10][6]:

1. Вычисляются тройки чисел
( x i , x 2 i , Q i ) , i = 1 , 2 , . . .  , где Q i j = 1 i ( x 2 j x j ) ( m o d N )  .
Причём каждая такая тройка получается из предыдущей.
2. Каждый раз, когда число i   кратно числу m   (скажем, m = 100  ), вычисляется наибольший общий делитель d i = G C D ( Q i , N )   любым известным методом.
3. Если 1 < d i < N  , то частичное разложение числа N   найдено, причём N = d i × ( N / d i )  .
Найденный делитель d i   может быть составным, поэтому его также необходимо факторизовать. Если число N / d i   составное, то продолжаем алгоритм с модулем N = N / d i  .
4. Вычисления повторяются S   раз. Если при этом число не было до конца факторизовано, выбирается, например, другое начальное число x 0  .

Современная версияПравить

Пусть N   составное целое положительное число, которое требуется разложить на множители. Алгоритм выглядит следующим образом[11]:

  1. Случайным образом выбирается небольшое число x 0  [12] и строится последовательность { x n } , n = 0 , 1 , 2 , . . .  , определяя каждое следующее как x n + 1 = F ( x n ) ( m o d N )  .
  2. Одновременно на каждом i-ом шаге вычисляется d = G C D ( N , | x i x j | )   для каких-либо i  , j   таких, что j < i  , например, i = 2 j  .
  3. Если d > 1  , то вычисление заканчивается, и найденное на предыдущем шаге число d   является делителем N  . Если N / d   не является простым числом, то процедуру поиска делителей продолжается, взяв в качестве N   число N = N / d  .

На практике функция F ( x )   выбирается не слишком сложной для вычисления (но в то же время не линейным многочленом), при условии того, что она не должна порождать взаимно однозначное отображение. Обычно в качестве F ( x )   выбираются функции F ( x ) = x 2 ± 1 ( m o d N )  [12] или F ( x ) = x 2 ± a ( m o d N )  [13]. Однако функции x 2 2   и x 2   не подходят[10].

Если известно, что для делителя p   числа N   справедливо p 1 ( m o d k )   при некотором k > 2  , то имеет смысл использовать F ( x ) = x k + b  [10].

Существенным недостатком алгоритма в такой реализации является необходимость хранить большое число предыдущих значений x j  .

Улучшения алгоритмаПравить

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

Пусть F ( x ) = ( x 2 1 ) mod N  . Тогда, если ( x j x i ) 0 ( mod p )  , то ( F ( x j ) F ( x i ) ) 0 ( mod p )  , поэтому, если пара ( x i , x j )   даёт решение, то решение даст любая пара ( x i + k , x j + k )  .

Поэтому нет необходимости проверять все пары ( x i , x j )  , а можно ограничиться парами вида ( x i , x j )  , где j = 2 k  , и k   пробегает набор последовательных значений 1, 2, 3, …, а i   принимает значения из интервала [ 2 k + 1 ; 2 k + 1 ]  . Например, k = 3  , j = 2 3 = 8  , а i [ 9 ; 16 ]  [11].

Эта идея была предложена Ричардом Брентом в 1980 году[14] и позволяет уменьшить количество выполняемых операций приблизительно на 25 %[15].

Ещё одна вариация ρ-алгоритма Полларда была разработана Флойдом. Согласно Флойду, значение y   обновляется на каждом шаге по формуле y = F 2 ( y ) = F ( F ( y ) )  , поэтому на шаге i   будут получены значения x i = F i ( x 0 )  , y i = x 2 i = F 2 i ( x 0 )  , и НОД на этом шаге вычисляется для N   и y x  [11].

Пример факторизации числаПравить

Данный пример наглядно демонстрирует ρ-алгоритм факторизации (версия алгоритма, с улучшением Флойда), для числа N = 8051:

Таблица: факторизация числа 8051
n = 8051, F(x) = (x2 + 1) mod n , x0 = y0 = 2
i xi=F(xi-1) yi=F(F(yi-1)) НОД(|xiyi|, 8051)
1 5 26 1
2 26 7474 1
3 677 871 97

Используя другие варианты полинома F ( x )  , можно также получить делитель 83:

Таблица: факторизация числа 8051
n = 8051, F(x) = (x2 + 3) mod n , x0 = y0 = 2
i xi=F(xi-1) yi=F(F(yi-1)) НОД(|xiyi|, 8051)
1 7 52 1
2 52 1442 1
3 2707 778 1
4 1442 3932 83

Таким образом, d1 = 97, d2 = 83 — нетривиальные делители числа 8051.

После нахождения делителя числа, в ρ-алгоритме предлагается продолжать вычисления и искать делители числа N / d  , если N / d   не является простым. В этом простом примере данного шага совершать не потребовалось[11].

Обоснование ρ-алгоритма ПоллардаПравить

Алгоритм основывается на известном парадоксе дней рождения.

Парадокс дней рождений, кратко:
Пусть λ > 0  . Для случайной выборки из l + 1   элементов, каждый из которых меньше q  , где l = 2 λ q  , вероятность того, что два элемента окажутся одинаковыми p > 1 e λ  .

Следует отметить, что вероятность p = 0.5   в парадоксе дней рождения достигается при λ 0.69  .

Пусть последовательность { u n }   состоит из разностей x i x j  , проверяемых в ходе работы алгоритма. Определяется новая последовательность { z n }  , где z n = u n m o d q  , q   — меньший из делителей числа N  .

Все члены последовательности { z n }   меньше N  . Если рассматривать её как случайную последовательность целых чисел, меньших q  , то, согласно парадоксу дней рождения, вероятность того, что среди l + 1   её членов попадутся два одинаковых, превысит 1 / 2   при λ 0.69  , тогда l   должно быть не меньше 2 λ q 1.4 q 1.18 q  .

Если z i = z j  , тогда x i x j 0 m o d q  , то есть, x i x j = k q   для некоторого целого k  . Если x i x j  , что выполняется с большой вероятностью, то искомый делитель q   числа N   будет найден как G C D ( N , | x i x j | )  . Поскольку q n 1 / 4  , то с вероятностью, превышающей 1 / 2   , делитель N   будет найден за 1.18 × N 1 / 4   итераций[11].

Сложность алгоритмаПравить

Чтобы оценить сложность алгоритма, рассматривается последовательность, строящаяся в процессе вычислений, как случайная (разумеется, ни о какой строгости при этом говорить нельзя). Чтобы полностью факторизовать число N   длиной β   бит, достаточно найти все его делители, не превосходящие N  , что требует максимум порядка N   арифметических операций, или N 1 / 4 β 2 = 2 β / 4 β 2   битовых операций.

Поэтому сложность алгоритма оценивается, как O ( N 1 / 4 )  [16]. Однако в этой оценке не учитываются накладные расходы по вычислению наибольшего общего делителя. Полученная сложность алгоритма, хотя и не является точной, достаточно хорошо согласуется с практикой.

Справедливо следующее утверждение: пусть N   — составное число. Тогда существует такая константа C  , что для любого положительного числа λ   вероятность события, состоящего в том, что ρ-алгоритм Полларда не найдет нетривиального делителя N   за время C λ N ( log N ) 2  , не превосходит величины e λ  . Данное утверждение следует из парадокса дней рождения[17].

Особенности реализацииПравить

Объём памяти, используемый алгоритмом, можно значительно уменьшить.

 int Rho-Поллард (int N)
 { 
   int x = random(1, N-2);
   int y = 1; int i = 0; int stage = 2;
   while (Н.О.Д.(N, abs(x - y)) == 1)
   {
     if (i == stage){
       y = x;
       stage = stage*2; 
     }
     x = (x*x + 1) (mod N);
     i = i + 1;
   }
   return Н.О.Д(N, abs(x-y));
 }

В этом варианте вычисление требует хранить в памяти всего три переменные N  , x  , и y  , что выгодно отличает алгоритм в такой реализации от других методов факторизации чисел[11].

Распараллеливание алгоритмаПравить

Алгоритм Полларда допускает распараллеливание с использованием как систем с разделяемой памятью, так и систем с распределенной памятью (передача сообщений), однако второй случай является наиболее интересным с практической точки зрения[18].

Система с распределенной памятьюПравить

Существующий метод распараллеливания заключается в том, что каждый вычислительный узел исполняет один и тот же последовательный алгоритм, однако, исходное число x 0   и/или полином F ( x )   берутся различными. Для упрощения распараллеливания, предлагается получать их из генератора случайных чисел. Однако такая параллельная реализация не даёт линейного ускорения[19].

Предположим что есть P   одинаковых исполнителей. Если мы используем P   различных последовательностей (то есть различных полиномов F ( x )  ), то вероятность того, что первые k   чисел в этих последовательностях будут различными по модулю p  , будет примерно равна exp ( k 2 P / 2 p )  . Таким образом, максимальное ускорение можно оценить как P 1 / 2  [9].

Ричард Крэндалл предположил, что достижимо ускорение O ( P / ( log P ) 2 )  , однако данное утверждение пока не проверено[20].

Система с общей памятьюПравить

Предыдущий метод, очевидно, можно использовать и на системах с общей памятью, однако, гораздо разумнее использовать единый генератор F ( x )  [21].

ПримечанияПравить

  1. 1 2 Pollard, 1974, с. 521–528.
  2. Christensen, 2009, 3.3.3.0.
  3. Chatterjee, 2008, 5.2.2.
  4. Floyd, 1967, с. 636–644.
  5. Brent, 1980, An improved Monte Carlo factorization algorithm, с. 176.
  6. 1 2 3 Pollard, 1975, A Monte Carlo method for factorization, с. 176.
  7. Koshy, 2007, Elementary Number Theory with Applications.
  8. Childs, 2009, A Concrete Introduction to Higher Algebra.
  9. 1 2 Brent, 1999, Some parallel algorithms for integer factorization..
  10. 1 2 3 Pollard, 1975, A Monte Carlo method for factorization.
  11. 1 2 3 4 5 6 Ишмухаметов, 2011, с. 64.
  12. 1 2 Mollin, 2006, с. 215—216.
  13. Золотых Н. Ю. Лекции по компьютерной алгебре. Лекция 11. ρ-метод Полларда. Архивная копия от 30 октября 2014 на Wayback Machine
  14. Brent, 1980, An improved Monte Carlo factorization algorithm, с. 176—184.
  15. Reisel, 2012, Selected Areas in Cryptography. Prime Numbers and Computer Methods for Factorization. 2nd ed..
  16. Cormen, 2001, Introduction to Algorithms. Section 31.9. Integer Factorization. Pollard's rho heuristic..
  17. Ишмухаметов, 2011, с. 63.
  18. Косяков, 2014, с. 12.
  19. Kuhn, 2001, Random Walks Revisited: Extensions of Pollard’s Rho Algorithm for Computing Multiple Discrete Logarithms, с. 212—229.
  20. Crandall, 1999, Parallelization of Polldar-rho factorization.
  21. Косяков, 2014, с. 19.

ЛитератураПравить