1
/* Factoring with Pollard's rho method.
3
Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
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 2, or (at your option) any later version.
10
This program is distributed in the hope that it will be useful, but WITHOUT ANY
11
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
12
PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License along with
15
this program; see the file COPYING. If not, write to the Free Software
16
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
26
static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6};
29
factor_using_division (mpz_t t, unsigned int limit)
35
unsigned int failures;
39
printf ("[trial division (%u)] ", limit);
47
mpz_div_2exp (t, t, f);
57
mpz_tdiv_qr_ui (q, r, t, 3);
58
if (mpz_cmp_ui (r, 0) != 0)
67
mpz_tdiv_qr_ui (q, r, t, 5);
68
if (mpz_cmp_ui (r, 0) != 0)
78
while (mpz_cmp_ui (t, 1) != 0)
80
mpz_tdiv_qr_ui (q, r, t, f);
81
if (mpz_cmp_ui (r, 0) != 0)
84
if (mpz_cmp_ui (q, f) < 0)
105
factor_using_division_2kp (mpz_t t, unsigned int limit, unsigned long p)
112
mpz_init_set_ui (f, 2 * p);
113
mpz_add_ui (f, f, 1);
114
for (k = 1; k < limit; k++)
116
mpz_tdiv_r (r, t, f);
117
while (mpz_cmp_ui (r, 0) == 0)
119
mpz_tdiv_q (t, t, f);
120
mpz_tdiv_r (r, t, f);
121
mpz_out_str (stdout, 10, f);
125
mpz_add_ui (f, f, 2 * p);
133
factor_using_pollard_rho (mpz_t n, int a_int, unsigned long p)
143
printf ("[pollard-rho (%d)] ", a_int);
151
mpz_init_set_si (a, a_int);
152
mpz_init_set_si (y, 2);
153
mpz_init_set_si (x, 2);
154
mpz_init_set_si (x1, 2);
157
mpz_init_set_ui (P, 1);
160
while (mpz_cmp_ui (n, 1) != 0)
165
mpz_powm_ui (x, x, p, n); mpz_add (x, x, a);
169
mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
171
mpz_sub (t1, x1, x); mpz_mul (t2, P, t1); mpz_mod (P, t2, n);
177
if (mpz_cmp_ui (g, 1) != 0)
187
if (mpz_cmp_ui (g, 1) != 0)
193
for (i = 0; i < k; i++)
197
mpz_powm_ui (x, x, p, n); mpz_add (x, x, a);
201
mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
212
mpz_powm_ui (y, y, p, n); mpz_add (y, y, a);
216
mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);
218
mpz_sub (t1, x1, y); mpz_gcd (g, t1, n);
220
while (mpz_cmp_ui (g, 1) == 0);
222
if (!mpz_probab_prime_p (g, 3))
227
mpn_random (&a_limb, (mp_size_t) 1);
228
a_int = (int) a_limb;
230
while (a_int == -2 || a_int == 0);
234
printf ("[composite factor--restarting pollard-rho] ");
237
factor_using_pollard_rho (g, a_int, p);
242
mpz_out_str (stdout, 10, g);
250
if (mpz_probab_prime_p (n, 3))
252
mpz_out_str (stdout, 10, n);
270
factor (mpz_t t, unsigned long p)
272
unsigned int division_limit;
274
if (mpz_sgn (t) == 0)
277
/* Set the trial division limit according the size of t. */
278
division_limit = mpz_sizeinbase (t, 2);
279
if (division_limit > 1000)
280
division_limit = 1000 * 1000;
282
division_limit = division_limit * division_limit;
285
factor_using_division_2kp (t, division_limit / 10, p);
287
factor_using_division (t, division_limit);
289
if (mpz_cmp_ui (t, 1) != 0)
293
printf ("[is number prime?] ");
296
if (mpz_probab_prime_p (t, 3))
297
mpz_out_str (stdout, 10, t);
299
factor_using_pollard_rho (t, 1, p);
303
main (int argc, char *argv[])
309
if (argc > 1 && !strcmp (argv[1], "-v"))
320
for (i = 1; i < argc; i++)
322
if (!strncmp (argv[i], "-Mp", 3))
324
p = atoi (argv[i] + 3);
326
mpz_mul_2exp (t, t, p);
327
mpz_sub_ui (t, t, 1);
329
else if (!strncmp (argv[i], "-2kp", 4))
331
p = atoi (argv[i] + 4);
336
mpz_set_str (t, argv[i], 0);
339
if (mpz_cmp_ui (t, 0) == 0)
352
mpz_inp_str (t, stdin, 0);
355
mpz_out_str (stdout, 10, t); printf (" = ");