pollard-gauss_factorization_method.sf 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. #!/usr/bin/ruby
  2. # Pollard's p−1 integer factorization algorithm, combined with Gaussian integers.
  3. # It can find a factor p if either p-1 or p+1 is B-smooth.
  4. # Let's consider the following Gaussian integer:
  5. # G = 1+2i = (1,2)
  6. # For some smooth bound B, we compute:
  7. # (x,y) = G^lcm(1..B)
  8. # We then check if gcd(y,n) is a non-trivial factor n.
  9. # See also:
  10. # https://en.wikipedia.org/wiki/Gaussian_integer
  11. # https://en.wikipedia.org/wiki/Pollard%27s_p_%E2%88%92_1_algorithm
  12. func pollard_gauss_factor (n, B = n.ilog2**3) {
  13. return n if ((n <= 1) || n.is_prime)
  14. return 2 if n.is_even
  15. var t = Gauss(1, 2)
  16. B.primes_each {|p|
  17. t = powmod(t, p**B.ilog(p), n)
  18. is_coprime(t.imag, n) || break
  19. }
  20. return gcd(t.imag, n)
  21. }
  22. say pollard_gauss_factor(1204123279); #=> 46511
  23. say pollard_gauss_factor(83910721266759813859) #=> 4545646757
  24. say pollard_gauss_factor(406816927495811038353579431); #=> 9074269
  25. say pollard_gauss_factor(38568900844635025971879799293495379321); #=> 17495058332072672321
  26. say pollard_gauss_factor(257221 * 470783, 700); #=> 470783 (p+1 is 700-smooth)
  27. say pollard_gauss_factor(333732865481 * 1632480277613, 3000); #=> 333732865481 (p-1 is 3000-smooth)
  28. say pollard_gauss_factor(33311699120128903709 * 556010720288850785597) #=> 556010720288850785597 (p-1 is 9137-smooth)
  29. say pollard_gauss_factor(4393290631695328772611 * 58637507352579687279739) #=> 58637507352579687279739 (p+1 is 55927-smooth)
  30. say pollard_gauss_factor(6353227783101038695489 * 896466791041143516471427) #=> 896466791041143516471427 (p+1 is 227651-smooth)