pollard-strassen_factorization_method.sf 1.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. #!/usr/bin/ruby
  2. # Pollard-Strassen O(n^(1/4)) factorization algorithm.
  3. # Illustrated by David Harvey in the following video:
  4. # https://yewtu.be/watch?v=_53s-0ZLxbQ
  5. func pollard_strassen_factorization(n, d = min(200, 1+n.ilog2), tries = min(1000, 10*d)) {
  6. # In the original algorithm, d = ceil(n^(1/4))
  7. # d = 1+n.iroot(4)
  8. # However, the polynomial evaluation is very slow when d is too large.
  9. var a = random_prime(n)
  10. var baby_steps = @(1..d).map_reduce {|b|
  11. mulmod(b, a, n)
  12. }
  13. var x = Poly(1)
  14. var f = baby_steps.map {|k| (x-k) % n }.binsplit {|a,b| a * b }
  15. var b = powmod(a, d, n)
  16. for k in (2 .. tries) {
  17. #b = powmod(a, k*d, n) # original operation
  18. b = powmod(b, k, n) # p-1 smooth approach
  19. var g = gcd(lift(f(Mod(b, n))), n)
  20. if (g.is_between(2, n-1)) {
  21. return g
  22. }
  23. }
  24. return 1
  25. }
  26. say pollard_strassen_factorization(503*863)
  27. say pollard_strassen_factorization(2**64 + 1)
  28. say pollard_strassen_factorization(2.of { 1e7.random_prime }.prod)