pollard-strassen_factorization_method_polymod.sf 969 B

1234567891011121314151617181920212223242526272829303132333435363738394041
  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 = PolyMod(1, n)
  14. var f = baby_steps.map {|k| (x-k) }.binsplit {|a,b| a * b }
  15. for k in (2 .. tries) {
  16. var b = powmod(a, k*d, n)
  17. var g = gcd(f(b), n)
  18. if (g.is_between(2, n-1)) {
  19. return g
  20. }
  21. }
  22. return 1
  23. }
  24. say pollard_strassen_factorization(43*97)
  25. say pollard_strassen_factorization(503*863)
  26. say pollard_strassen_factorization(2**32 + 1)
  27. say pollard_strassen_factorization(2**64 + 1)