chebyshev_factorization_method.pl 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 23 January 2020
  4. # https://github.com/trizen
  5. # A simple factorization method, using the Chebyshev T_n(x) polynomials, based on the identity:
  6. # T_{m n}(x) = T_m(T_n(x))
  7. # where:
  8. # T_n(x) = (1/2) * V_n(2x, 1)
  9. # where V_n(P, Q) is the Lucas V sequence.
  10. # See also:
  11. # https://oeis.org/A001075
  12. # https://en.wikipedia.org/wiki/Lucas_sequence
  13. # https://en.wikipedia.org/wiki/Iterated_function
  14. # https://en.wikipedia.org/wiki/Chebyshev_polynomials
  15. use 5.020;
  16. use warnings;
  17. use experimental qw(signatures);
  18. use ntheory qw(prime_iterator sqrtint primes logint);
  19. use Math::AnyNum qw(:overload lucasVmod gcd invmod mulmod is_coprime);
  20. sub chebyshev_factorization ($n, $B = logint($n, 2)**2, $a = 127) {
  21. my $x = $a;
  22. my $G = $B * $B;
  23. my $i = invmod(2, $n);
  24. my sub chebyshevTmod ($a, $x) {
  25. mulmod(lucasVmod(2 * $x, 1, $a, $n), $i, $n);
  26. }
  27. foreach my $p (@{primes(2, sqrtint($B))}) {
  28. for (1 .. logint($G, $p)) {
  29. $x = chebyshevTmod($p, $x); # T_k(x) (mod n)
  30. }
  31. }
  32. my $it = prime_iterator(sqrtint($B) + 1);
  33. for (my $p = $it->() ; $p <= $B ; $p = $it->()) {
  34. $x = chebyshevTmod($p, $x); # T_k(x) (mod n)
  35. is_coprime($x - 1, $n) || return gcd($x - 1, $n);
  36. }
  37. return gcd($x - 1, $n);
  38. }
  39. say chebyshev_factorization(2**64 + 1, 20); #=> 274177 (p-1 is 20-smooth)
  40. say chebyshev_factorization(257221 * 470783, 1000); #=> 470783 (p-1 is 1000-smooth)
  41. say chebyshev_factorization(1124075136413 * 3556516507813, 4000); #=> 1124075136413 (p+1 is 4000-smooth)
  42. say chebyshev_factorization(7553377229 * 588103349, 800); #=> 7553377229 (p+1 is 800-smooth)
  43. say '';
  44. say chebyshev_factorization(333732865481 * 1632480277613, 3000); #=> 333732865481 (p-1 is 3000-smooth)
  45. say chebyshev_factorization(15597344393 * 12388291753, 3000); #=> 15597344393 (p-1 is 3000-smooth)
  46. say chebyshev_factorization(43759958467 * 59037829639, 3200); #=> 43759958467 (p+1 is 3200-smooth)
  47. say chebyshev_factorization(112601635303 * 83979783007, 700); #=> 112601635303 (p-1 is 700-smooth)
  48. say chebyshev_factorization(228640480273 * 224774973299, 2000); #=> 228640480273 (p-1 is 2000-smooth)
  49. say '';
  50. say chebyshev_factorization(5140059121 * 8382882743, 2500); #=> 5140059121 (p-1 is 2500-smooth)
  51. say chebyshev_factorization(18114813019 * 17402508649, 6000); #=> 18114813019 (p+1 is 6000-smooth)
  52. say chebyshev_factorization(533091092393 * 440050095029, 300); #=> 533091092393 (p+1 is 300-smooth)