1 /* Factoring with Pollard's rho method.
3 Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2009
4 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free Software
8 Foundation; either version 3 of the License, or (at your option) any later
11 This program is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along with
16 this program. If not, see http://www.gnu.org/licenses/. */
27 static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6};
30 factor_using_division (mpz_t t, unsigned int limit)
36 unsigned int failures;
40 printf ("[trial division (%u)] ", limit);
48 mpz_div_2exp (t, t, f);
58 mpz_tdiv_qr_ui (q, r, t, 3);
59 if (mpz_cmp_ui (r, 0) != 0)
68 mpz_tdiv_qr_ui (q, r, t, 5);
69 if (mpz_cmp_ui (r, 0) != 0)
79 while (mpz_cmp_ui (t, 1) != 0)
81 mpz_tdiv_qr_ui (q, r, t, f);
82 if (mpz_cmp_ui (r, 0) != 0)
85 if (mpz_cmp_ui (q, f) < 0)
101 mpz_clears (q, r, NULL);
105 factor_using_division_2kp (mpz_t t, unsigned int limit, unsigned long p)
111 if (flag_verbose > 0)
113 printf ("[trial division (%u)] ", limit);
118 mpz_init_set_ui (f, 2 * p);
119 mpz_add_ui (f, f, 1);
120 for (k = 1; k < limit; k++)
122 mpz_tdiv_r (r, t, f);
123 while (mpz_cmp_ui (r, 0) == 0)
125 mpz_tdiv_q (t, t, f);
126 mpz_tdiv_r (r, t, f);
127 mpz_out_str (stdout, 10, f);
131 mpz_add_ui (f, f, 2 * p);
134 mpz_clears (f, r, NULL);
138 factor_using_pollard_rho (mpz_t n, unsigned long a, unsigned long p)
142 unsigned long long k, l, i;
144 if (flag_verbose > 0)
146 printf ("[pollard-rho (%lu)] ", a);
150 mpz_inits (t1, t2, NULL);
151 mpz_init_set_si (y, 2);
152 mpz_init_set_si (x, 2);
153 mpz_init_set_si (x1, 2);
154 mpz_init_set_ui (P, 1);
158 while (mpz_cmp_ui (n, 1) != 0)
166 mpz_powm_ui (x, x, p, n);
167 mpz_add_ui (x, x, a);
173 mpz_add_ui (x, x, a);
183 if (mpz_cmp_ui (t1, 1) != 0)
191 if (mpz_cmp_ui (t1, 1) != 0)
197 for (i = 0; i < k; i++)
201 mpz_powm_ui (x, x, p, n);
202 mpz_add_ui (x, x, a);
208 mpz_add_ui (x, x, a);
219 mpz_powm_ui (y, y, p, n); mpz_add_ui (y, y, a);
225 mpz_add_ui (y, y, a);
230 while (mpz_cmp_ui (t1, 1) == 0);
232 mpz_divexact (n, n, t1); /* divide by t1, before t1 is overwritten */
234 if (!mpz_probab_prime_p (t1, 10))
239 mpn_random (&a_limb, (mp_size_t) 1);
244 if (flag_verbose > 0)
246 printf ("[composite factor--restarting pollard-rho] ");
249 factor_using_pollard_rho (t1, a, p);
253 mpz_out_str (stdout, 10, t1);
260 if (mpz_probab_prime_p (n, 10))
262 mpz_out_str (stdout, 10, n);
269 mpz_clears (P, t2, t1, x1, x, y, NULL);
273 factor (mpz_t t, unsigned long p)
275 unsigned int division_limit;
277 if (mpz_sgn (t) == 0)
280 /* Set the trial division limit according the size of t. */
281 division_limit = mpz_sizeinbase (t, 2);
282 if (division_limit > 1000)
283 division_limit = 1000 * 1000;
285 division_limit = division_limit * division_limit;
288 factor_using_division_2kp (t, division_limit / 10, p);
290 factor_using_division (t, division_limit);
292 if (mpz_cmp_ui (t, 1) != 0)
294 if (flag_verbose > 0)
296 printf ("[is number prime?] ");
299 if (mpz_probab_prime_p (t, 10))
300 mpz_out_str (stdout, 10, t);
302 factor_using_pollard_rho (t, 1L, p);
307 main (int argc, char *argv[])
313 if (argc > 1 && !strcmp (argv[1], "-v"))
319 if (argc > 1 && !strcmp (argv[1], "-q"))
330 for (i = 1; i < argc; i++)
332 if (!strncmp (argv[i], "-Mp", 3))
334 p = atoi (argv[i] + 3);
336 mpz_mul_2exp (t, t, p);
337 mpz_sub_ui (t, t, 1);
339 else if (!strncmp (argv[i], "-2kp", 4))
341 p = atoi (argv[i] + 4);
346 mpz_set_str (t, argv[i], 0);
349 if (mpz_cmp_ui (t, 0) == 0)
362 mpz_inp_str (t, stdin, 0);
365 if (flag_verbose >= 0)
367 mpz_out_str (stdout, 10, t); printf (" = ");