pollard_p-1_factorization.sf 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. #!/usr/bin/ruby
  2. # Simple implementation of Pollard's p−1 integer factorization algorithm, with the B2 stage.
  3. # See also:
  4. # https://en.wikipedia.org/wiki/Pollard%27s_p_%E2%88%92_1_algorithm
  5. func pollard_pm1_factor (n, B1 = n.ilog(6)**3, B2 = B1*B1.ilog2) {
  6. return n if ((n <= 1) || n.is_prime)
  7. return 2 if n.is_even
  8. var t = 2
  9. var G = B1*B1
  10. primes_each(2, B1.isqrt, {|p|
  11. G.ilog(p).times {
  12. t = powmod(t, p, n)
  13. }
  14. })
  15. primes_each(B1.isqrt+1, B1, {|p|
  16. t = powmod(t, p, n)
  17. is_coprime(t-1, n) || return gcd(t-1, n)
  18. })
  19. var Q = B1.next_prime
  20. var TQ = powmod(t, Q, n)
  21. var table = []
  22. primes_each(Q.next_prime, B2, {|p|
  23. TQ = mulmod(TQ, (table[p-Q] := powmod(t, p - Q, n)), n)
  24. is_coprime(TQ-1, n) || return gcd(TQ-1, n)
  25. Q = p
  26. })
  27. return 1
  28. }
  29. say pollard_pm1_factor(1204123279) #=> 25889
  30. say pollard_pm1_factor(83910721266759813859) #=> 4545646757
  31. say pollard_pm1_factor(406816927495811038353579431) #=> 9074269
  32. say pollard_pm1_factor(38568900844635025971879799293495379321) #=> 17495058332072672321