Алгоритм ро Полларда для логарифмов — алгоритм, предложенный Джоном Поллардом в 1978 году для решения задачи дискретного логарифмирования , аналогичный алгоритму ро Полларда для решения задачи разложения целых чисел .
Цель состоит в том, чтобы вычислить такое , что , где принадлежит циклической группе, порожденной . Алгоритм вычисляет целые числа , , , и такие, что . Если базовая группа является циклической порядка , то, подставляя как и отмечая, что две степени равны тогда и только тогда, когда показатели степени эквивалентны по модулю порядка основания, в данном случае по модулю , мы получаем, что является одним из решений уравнения . Решения этого уравнения легко получить с помощью расширенного алгоритма Евклида .
Чтобы найти необходимые , , , и алгоритм использует алгоритм поиска цикла Флойда для поиска цикла в последовательности , где функция предполагается случайной и, таким образом, вероятно, войдет в цикл приблизительной длины после шагов. Один из способов определить такую функцию — использовать следующие правила: Разбиение на три непересекающихся подмножества , , и приблизительно равного размера с помощью хэш-функции . Если находится в , то удвоить и ; если , то инкремент , если , то инкремент .
Пусть будет циклической группой порядка , и даны , и разбиение , пусть будет отображением
и определить карты и по
вход: a : генератор G b : элемент G выход: целое число x такое, что a x = b , или неудачаИнициализировать i ← 0, a 0 ← 0, b 0 ← 0, x 0 ← 1 ∈ Gпетля i ← i + 1 x i ← f ( x i −1 ), a i ← g ( x i −1 , a i −1 ), b i ← h ( x i −1 , b i −1 ) x 2 i −1 ← f ( x 2 i −2 ), a 2 i −1 ← g ( x 2 i −2 , a 2 i −2 ), b 2 i −1 ← h ( x 2 i −2 , b 2 i −2 ) x 2 i ← f ( x 2 i −1 ), a 2 i ← g ( x 2 i −1 , a 2 i −1 ), b 2 i ← h ( x 2 i −1 , b 2 i −1 ) при этом x i ≠ x 2 ir ← b i − b 2 i если r = 0 вернуть ошибку вернуть r −1 ( a 2 i − a i ) mod n
Рассмотрим, например, группу, сгенерированную 2 по модулю (порядок группы , 2 генерирует группу единиц по модулю 1019). Алгоритм реализуется следующей программой на языке C++ :
#include <stdio.h> const int n = 1018 , N = n + 1 ; /* N = 1019 -- простое число */ const int alpha = 2 ; /* генератор */ const int beta = 5 ; /* 2^{10} = 1024 = 5 (N) */ void new_xab ( int & x , int & a , int & b ) { switch ( x % 3 ) { case 0 : x = x * x % N ; a = a * 2 % n ; b = b * 2 % n ; break ; case 1 : x = x * alpha % N ; a = ( a + 1 ) % n ; break ; case 2 : x = x * beta % N ; b = ( b + 1 ) % n ; break ; } } int main ( void ) { int x = 1 , a = 0 , b = 0 ; int X = x , A = a , B = b ; for ( int i = 1 ; i < n ; ++ i ) { new_xab ( x , a , b ); new_xab ( X , A , B ); new_xab ( X , A , B ); printf ( "%3d %4d %3d %3d %4d %3d %3d \n " , i , x , a , b , X , A , B ); if ( x == X ) break ; } return 0 ; }
Результаты следующие (отредактировано):
иксаб XAB------------------------------ 1 2 1 0 10 1 1 2 10 1 1 100 2 2 3 20 2 1 1000 3 3 4 100 2 2 425 8 6 5 200 3 2 436 16 14 6 1000 3 3 284 17 15 7 981 4 3 986 17 17 8 425 8 6 194 17 19............................48 224 680 376 86 299 41249 101 680 377 860 300 41350 505 680 378 101 300 41551 1010 681 378 1010 301 416
То есть и так , для которого есть решение , как и ожидалось. Так как не является простым , есть другое решение , для которого выполняется.
Время выполнения составляет приблизительно . При использовании вместе с алгоритмом Полига–Хеллмана время выполнения комбинированного алгоритма составляет , где — наибольший простой множитель .