chebyshev_factorization_method.sf 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 11 December 2019
  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. func lucasVmod(P, n, m) { # assumes Q = 1
  16. var(V1 = 2, V2 = P)
  17. for bit in (n.bits) {
  18. if (bit) {
  19. V1 = submod(mulmod(V2, V1, m), P, m)
  20. V2 = mulmod(V2, V2, m)-2
  21. }
  22. else {
  23. V2 = submod(mulmod(V2, V1, m), P, m)
  24. V1 = mulmod(V1, V1, m)-2
  25. }
  26. }
  27. return V1
  28. }
  29. func chebyshev_factorization(n, B1 = n.ilog(6)**3, a = 3) {
  30. var x = a
  31. var G = B1*B1
  32. var i = invmod(2, n)
  33. func chebyshevTmod(a, x) {
  34. mulmod(lucasVmod(2*x, a, n), i, n)
  35. }
  36. primes_each(2, B1.isqrt, {|p|
  37. G.ilog(p).times {
  38. x = chebyshevTmod(p, x) # T_k(x) (mod n)
  39. }
  40. })
  41. primes_each(B1.isqrt+1, B1, {|p|
  42. x = chebyshevTmod(p, x) # T_k(x) (mod n)
  43. is_coprime(x-1, n) || return gcd(x-1, n)
  44. })
  45. return gcd(x-1, n)
  46. }
  47. say chebyshev_factorization(257221 * 470783, 1000); #=> 257221 (p+1 is 1000-smooth)
  48. say chebyshev_factorization(1124075136413 * 3556516507813, 4000); #=> 1124075136413 (p+1 is 4000-smooth)
  49. say chebyshev_factorization(7553377229 * 588103349, 800); #=> 7553377229 (p+1 is 800-smooth)
  50. say chebyshev_factorization(333732865481 * 1632480277613, 3000); #=> 333732865481 (p-1 is 3000-smooth)
  51. say ''
  52. say chebyshev_factorization(15597344393 * 12388291753, 3000) #=> 15597344393 (p-1 is 3000-smooth)
  53. say chebyshev_factorization(43759958467 * 59037829639, 3200) #=> 43759958467 (p+1 is 3200-smooth)
  54. say chebyshev_factorization(112601635303 * 83979783007, 700) #=> 112601635303 (p-1 is 700-smooth)
  55. say chebyshev_factorization(228640480273 * 224774973299, 2000) #=> 228640480273 (p-1 is 2000-smooth)
  56. say ''
  57. say chebyshev_factorization(5140059121 * 8382882743, 2500, 2) #=> 5140059121 (p-1 is 2500-smooth)
  58. say chebyshev_factorization(18114813019 * 17402508649, 6000, 2) #=> 18114813019 (p+1 is 6000-smooth)
  59. say chebyshev_factorization(533091092393 * 440050095029, 300, 2) #=> 533091092393 (p+1 is 300-smooth)
  60. say ''
  61. for k in (3..20) {
  62. var n = 2.of { random_nbit_prime(k) }.prod
  63. var p = chebyshev_factorization(n, 2 * n.ilog2**2)
  64. if (p.is_prime) {
  65. say "#{n} = #{p} * #{n/p}"
  66. }
  67. }
  68. __END__
  69. 143 = 11 * 13
  70. 323 = 17 * 19
  71. 2773 = 59 * 47
  72. 12091 = 107 * 113
  73. 42781 = 179 * 239
  74. 181427 = 433 * 419
  75. 685603 = 967 * 709
  76. 3240379 = 1999 * 1621
  77. 12254063 = 3089 * 3967
  78. 38271817 = 6763 * 5659
  79. 119391583 = 9511 * 12553
  80. 367073731 = 20929 * 17539
  81. 3578349739 = 60961 * 58699
  82. 15888478703 = 121571 * 130693
  83. 36182994919 = 143593 * 251983
  84. 545782820497 = 668713 * 816169
  85. 3656558375893 = 1912639 * 1911787
  86. 12346497466267 = 3737821 * 3303127
  87. 31369209076123 = 5655031 * 5547133
  88. 148520973663353 = 13394431 * 11088263
  89. 412638129424819 = 17334017 * 23805107