Thuật toán rho của Pollard – Wikipedia

Thuật toán rho của Pollard là một thuật toán cho hệ số nguyên. Nó được phát minh bởi John Pollard vào năm 1975. [1] Nó chỉ sử dụng một lượng không gian nhỏ và thời gian chạy dự kiến ​​của nó tỷ lệ với căn bậc hai của kích thước của thừa số nguyên tố nhỏ nhất của số hỗn hợp được tính.

Ý tưởng cốt lõi [ chỉnh sửa ]

Giả sử chúng ta cần nhân tố một số

n = p q { displaystyle n = pq}

trong đó

p { displaystyle p}

là một yếu tố không tầm thường. Một modulo đa thức

n { displaystyle n}

được gọi là

g ( x ) { (x)}

(ví dụ:

g ( x ) = ( x 2 [19659036] + 1 ) mod n { displaystyle g (x) = (x ^ {2} +1) { bmod {n}}}

), được sử dụng để tạo một chuỗi giả ngẫu nhiên : Giá trị bắt đầu, giả sử 2, được chọn, và trình tự tiếp tục là

x 1 = g ( 2 ) { displaystyle x_ {1} = g (2 )}

x 2 = g ( g ( 2 ) ) { displaystyle x_ {2} = g (g (2))}

x 3 = g [19659022] ( g ( g ( 2 ) ) ) { displaystyle x_ {3} = g (g (g (2)))}

v.v … Trình tự này có liên quan đến một chuỗi khác

{ x [19659085] k mod p } { displaystyle {x_ {k} { bmod {p}} }}

. Kể từ

p { displaystyle p}

không được biết trước, trình tự này không thể được tính toán rõ ràng trong thuật toán. Tuy nhiên, trong đó nằm ở ý tưởng cốt lõi của thuật toán.

Bởi vì số lượng các giá trị có thể có cho các chuỗi này là hữu hạn, cả

{ x n } { displaystyle {x_ {n} }} [19659102Trìnhtự] {x_ {n} } “/>đó là mod

cuối cùng sẽ lặp lại, mặc dù chúng ta không biết cái sau. Giả sử rằng các chuỗi hành xử giống như số ngẫu nhiên. Do nghịch lý sinh nhật số lượng

x k { displaystyle x_ {k}}

trước khi sự lặp lại xảy ra được dự kiến ​​là [19659122] O ( N ) { displaystyle O ({ sqrt {N}})}

N { displaystyle N}

là số lượng các giá trị có thể. Vì vậy, trình tự

{ x k mod p } { displaystyle {x_ {k} { bmod {p}} }} [19659090] { displaystyle {x_ {k} { bmod {p}} }} “/> có thể sẽ lặp lại sớm hơn nhiều so với trình tự

v.v. được thể hiện dưới dạng các nút trong một đồ thị có hướng.

Điều này được phát hiện bởi thuật toán tìm chu kỳ của Floyd: hai nút

i { displaystyle i}

j { displaystyle j}

(tức là

x i { displaystyle x_ {i}}

x j { displaystyle x_ {j}}

) được giữ nguyên. Trong mỗi bước, một người di chuyển đến nút tiếp theo trong chuỗi và người khác di chuyển đến nút sau nút tiếp theo. Sau đó, nó được kiểm tra xem

gcd ( x i x j n 1 { displaystyle gcd (x_ {i} -x_ {j}, n) neq 1}

. Nếu nó không phải là 1, thì điều này có nghĩa là có sự lặp lại trong

{ x k mod p } { displaystyle {x_ { k} { bmod {p}} }}

trình tự (ví dụ

x i [19659086] mod p = x j mod p ) { displaystyle x_ {i} { bmod {p}} = x_ { j} { bmod {p}})}

. Điều này hoạt động bởi vì nếu

x i mod p { displaystyle x_ {i} { bmod {p}}}

giống với

x j mod p { displaystyle x_ {j} { bmod {p}}} [19659231] { displaystyle x_ {j} { bmod {p}}} “/>sự khác biệt giữa

Thuật toán [ chỉnh sửa ]

Thuật toán lấy làm đầu vào của nó n số nguyên được xác định; và

g ( x ) { displaystyle g (x)}

một đa thức trong x modulo n . Trong thuật toán ban đầu,

g ( x ) = ( x 2 ]) mod n { displaystyle g (x) = (x ^ {2} -1) { bmod {n}}}

nhưng ngày nay người ta thường sử dụng

g ( x ) = ] ( x 2 + 1 ) mod n { displaystyle g (x) = (x ^ {2} +1) { bmod {n}}}

. Đầu ra là một yếu tố không tầm thường của n hoặc thất bại. Nó thực hiện các bước sau: [2]

     x ← 2; y ← 2; d ← 1      trong khi  d = 1:         x ← g (x)         y ← g (g (y))         d ← gcd (| x - y |, n)      nếu  d = n:          thất bại trở lại       khác :          trở lại  d 

Ở đây x y tương ứng với

x i { displaystyle x_ {i}}

x j { displaystyle x_ {j}}

trong phần về ý tưởng cốt lõi. Lưu ý rằng thuật toán này có thể không tìm thấy một yếu tố không cần thiết ngay cả khi n là hợp số. Trong trường hợp đó, phương pháp có thể được thử lại, sử dụng giá trị bắt đầu khác 2 hoặc khác

g ( x ) { displaystyle g (x)} [19659026] g (x) “/>.

Hệ số hóa ví dụ [ chỉnh sửa ]

Đặt n = 8051 và g ( x x 2 + 1) mod 8051.

i x y GCD (| x y |, 8051)
1 [1965932] 5 [1965932] Năm 1969932] 1
2 26 7474 1
3 677 871 97
4 7474 1481 1

97 là một yếu tố không tầm thường của 8051. Các giá trị bắt đầu không phải là x = y = 2 có thể cung cấp cho đồng sáng lập (83) thay vì 97. Một lần lặp thêm được hiển thị ở trên để làm rõ rằng y di chuyển nhanh gấp đôi x. Lưu ý rằng ngay cả sau khi lặp lại, GCD có thể trở về 1.

Các biến thể [ chỉnh sửa ]

Năm 1980, Richard Brent đã xuất bản một biến thể nhanh hơn của thuật toán rho. Ông đã sử dụng các ý tưởng cốt lõi tương tự như Pollard nhưng một phương pháp phát hiện chu kỳ khác, thay thế thuật toán tìm chu kỳ của Floyd bằng phương pháp tìm chu trình của Brent [3] ]

Một cải tiến hơn nữa đã được thực hiện bởi Pollard và Brent. Họ đã quan sát thấy rằng nếu

gcd ( a n ) > 1 { displaystyle gcd (a, n)> 1}

sau đó cũng

gcd ( a b n ) > 1 { displaystyle gcd (ab, n)> 1}

gcd ( | x y | n ) { displaystyle gcd (| xy |, n)}

ở mỗi bước, nó đủ để xác định z là sản phẩm của 100 liên tiếp

| x y | { displaystyle | xy |}

gcd ( z n { displaystyle gcd (z, n)}

. Một kết quả tăng tốc độ lớn là 100 bước gcd được thay thế bằng 99 phép nhân modulo n và một gcd . Đôi khi, nó có thể khiến thuật toán bị lỗi bằng cách đưa ra một yếu tố lặp đi lặp lại, ví dụ khi n là một hình vuông. Nhưng sau đó nó đủ để quay trở lại thuật ngữ gcd trước đó, trong đó

gcd ( z n ) = 1 { displaystyle gcd (z, n) = 1}

và sử dụng thuật toán regular thông thường từ đó.

Ứng dụng [ chỉnh sửa ]

Thuật toán rất nhanh đối với các số có các yếu tố nhỏ, nhưng chậm hơn trong trường hợp tất cả các yếu tố đều lớn. Thành công đáng chú ý nhất của thuật toán was là hệ số của số 9 Số Fermat thứ chín số Fermat F 8 = 1238926361552897 * 9346163941535797776916355819999 vì hệ số nguyên tố p = 12389263661552897 nhỏ hơn nhiều so với yếu tố khác. Quá trình nhân tố diễn ra trong 2 giờ trên UNIVAC 1100/42 .

Ví dụ n = 10403 = 101 · 103 [ chỉnh sửa ]

Ở đây chúng tôi giới thiệu một biến thể khác, trong đó chỉ có một chuỗi duy nhất được tính toán và gcd được tính bên trong vòng lặp đó. phát hiện chu trình.

Mẫu mã C [ chỉnh sửa ]

Mẫu mã sau đây tìm thấy hệ số 101 của 10403 với giá trị bắt đầu là x = 2.

 #include    #include     int   gcd  ( int   a   int         int   phần còn lại ;       trong khi   ( b  ! =   0 )   19659443] a  %   b ;           a   =   b ;           b   =   }       trở lại   a ;  }    int   main   ( int   argc  19659454] argv  [])    {      int   đếm   số   =   10403 [1965944]   1 ;       int   x_fixed   =   2   kích thước   = [1965944] ] =   2   yếu tố   =   1 ; [1 9659517] trong khi   ( yếu tố   ==   1 )   {          printf  ( "---- loop% 4i --- -   n  "  vòng lặp );           cho   ( đếm   =   1 [1965944] ( đếm   <=   kích thước )   &&   ( yếu tố   <=   1  ] ++ )   {              x   =   ( x   *   x   +   1  %   số ;               yếu tố   =   gcd  ( abs  ( x     số );               printf  ( "Count =% 4i x =% 6i Fact =% i   n "    x   yếu tố );          }           kích thước   =   2   * [19659443] kích thước ;           x_fixed   =   x ;           loop   =   loop   +   }       printf  ( "hệ số là% i   n "   yếu tố ); [1965944] ;  }  

Đoạn mã trên sẽ hiển thị tiến trình thuật toán cũng như các giá trị trung gian. Dòng đầu ra cuối cùng sẽ là "hệ số là 101".

Mẫu mã Python [ chỉnh sửa ]

 def   gcd  ( a   b  trong khi   a  %   b  ! =   0 :           a   b   =   a  %   b       trở lại   b    số   =   10403   x_fixed   ] =   2   x   =   2   yếu tố   =   1    trong khi   yếu tố   == :       đếm   =   1       trong khi   đếm   <=   cycl_size    yếu tố [1965955] :           x   =   ( x  *  x   +   1 )  %   19659455] =   gcd  ( x   -   x_fixed [19659441]  số )           đếm   + =   1       cycl_size   * =   2       x_fixed   ] print  ( yếu tố )  

Kết quả [ chỉnh sửa ]

Trong bảng sau, cột thứ ba và thứ tư chứa thông tin bí mật không được biết đến người cố gắng tính hệ số pq = 10403. Chúng được bao gồm để hiển thị cách thuật toán hoạt động. Nếu chúng ta bắt đầu với x = 2 và tuân theo thuật toán, chúng ta sẽ nhận được các số sau:

x x đã sửa x mod 101 x đã sửa mod 101 bước
2 2 2 2 0
5 2 5 2 1
26 2 26 2 2
677 26 71 26 3
598 26 93 26 4
3903 26 65 26 5
3418 26 85 26 6
156 3418 55 85 7
3531 3418 97 85 8
5168 3418 17 85 9
3724 3418 88 85 10
979 [1965932] 3418 69 85 11
9812 3418 15 85 12
5983 3418 24 85 13
9970 3418 72 85 14
236 9970 34 72 15
3682 9970 46 72 16
2016 9970 97 72 17
7087 9970 17 72 18
10289 9970 88 72 19
2594 9970 69 72 20
8499 9970 15 72 21
4973 9970 24 72 22
2799 9970 72 72 23

Modulo lặp lại đầu tiên 101 là 97 xảy ra ở bước 17. Sự lặp lại không được phát hiện cho đến bước 23, khi x (mod 101) = x đã sửa (mod 101). Điều này làm cho gcd (x – x_fixed, n) = gcd (2799 – 9970, n) là p = 101 và một yếu tố được tìm thấy.

Độ phức tạp [ chỉnh sửa ]

Nếu số ngẫu nhiên giả x = g (x) xảy ra trong thuật toán Pollard là một số ngẫu nhiên thực tế, nó sẽ đạt được thành công đó. Một nửa thời gian, bởi nghịch lý sinh nhật trong

O ( p ) O ( 1 / 4 ) { displaystyle O ({ sqrt {p}}) leq O (n ^ {1/4})}

lặp lại. Người ta tin rằng phân tích tương tự cũng áp dụng cho thuật toán rho thực tế, nhưng đây là một tuyên bố heuristic, và phân tích nghiêm ngặt của thuật toán vẫn còn mở. [4]

Tài liệu tham khảo [ chỉnh sửa ] [19659870] ^ Pollard, JM (1975), "Một phương pháp nhân tố Monte Carlo", Toán học số BIT 15 (3): 331 điều34, doi : 10.1007 / bf01933667
  • ^ Cormen, Thomas H. ; Leiserson, Charles E. ; Rivest, Ronald L. & Stein, Clifford (2009), "Phần 31.9: Hệ số nguyên", Giới thiệu về thuật toán (biên tập thứ ba), Cambridge, MA: MIT Press, trang 975 điều980, ISBN 980-0-262-03384-8 (phần này chỉ thảo luận về thuật toán rho của Pollard).
  • ^ Brent, Richard P. (1980), "Thuật toán nhân tố hóa Monte Carlo được cải tiến" BIT 20 : 176 Thay184, doi : 19 10.1007 / BF01933190
  • ^ Galbraith, Steven D. (2012), "14.2.5 Hướng tới phân tích nghiêm ngặt về Pollard rho", Toán học về Mật mã khóa công khai Nhà xuất bản Đại học Cambridge, Trang. 272 Từ273, ISBN Muff107013926 .
  • Đọc thêm [ chỉnh sửa ]

    19659258]]