[BACK]Return to factorize.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / demos

Annotation of OpenXM_contrib/gmp/demos/factorize.c, Revision 1.1.1.3

1.1       maekawa     1: /* Factoring with Pollard's rho method.
                      2:
1.1.1.3 ! ohara       3: Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
        !             4: Inc.
1.1       maekawa     5:
1.1.1.3 ! ohara       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.
        !             9:
        !            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.
        !            13:
        !            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.  */
1.1       maekawa    17:
1.1.1.2   maekawa    18: #include <stdlib.h>
1.1       maekawa    19: #include <stdio.h>
1.1.1.2   maekawa    20: #include <string.h>
                     21:
1.1       maekawa    22: #include "gmp.h"
                     23:
1.1.1.2   maekawa    24: int flag_verbose = 0;
1.1       maekawa    25:
                     26: static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6};
                     27:
1.1.1.2   maekawa    28: void
                     29: factor_using_division (mpz_t t, unsigned int limit)
1.1       maekawa    30: {
                     31:   mpz_t q, r;
                     32:   unsigned long int f;
1.1.1.2   maekawa    33:   int ai;
1.1       maekawa    34:   unsigned *addv = add;
1.1.1.2   maekawa    35:   unsigned int failures;
                     36:
                     37:   if (flag_verbose)
                     38:     {
                     39:       printf ("[trial division (%u)] ", limit);
                     40:       fflush (stdout);
                     41:     }
1.1       maekawa    42:
                     43:   mpz_init (q);
                     44:   mpz_init (r);
                     45:
1.1.1.2   maekawa    46:   f = mpz_scan1 (t, 0);
                     47:   mpz_div_2exp (t, t, f);
                     48:   while (f)
1.1       maekawa    49:     {
                     50:       printf ("2 ");
                     51:       fflush (stdout);
1.1.1.2   maekawa    52:       --f;
1.1       maekawa    53:     }
                     54:
                     55:   for (;;)
                     56:     {
                     57:       mpz_tdiv_qr_ui (q, r, t, 3);
                     58:       if (mpz_cmp_ui (r, 0) != 0)
                     59:        break;
                     60:       mpz_set (t, q);
                     61:       printf ("3 ");
                     62:       fflush (stdout);
                     63:     }
                     64:
                     65:   for (;;)
                     66:     {
                     67:       mpz_tdiv_qr_ui (q, r, t, 5);
                     68:       if (mpz_cmp_ui (r, 0) != 0)
                     69:        break;
                     70:       mpz_set (t, q);
                     71:       printf ("5 ");
                     72:       fflush (stdout);
                     73:     }
                     74:
1.1.1.2   maekawa    75:   failures = 0;
1.1       maekawa    76:   f = 7;
                     77:   ai = 0;
1.1.1.2   maekawa    78:   while (mpz_cmp_ui (t, 1) != 0)
1.1       maekawa    79:     {
                     80:       mpz_tdiv_qr_ui (q, r, t, f);
                     81:       if (mpz_cmp_ui (r, 0) != 0)
                     82:        {
                     83:          f += addv[ai];
1.1.1.2   maekawa    84:          if (mpz_cmp_ui (q, f) < 0)
                     85:            break;
1.1       maekawa    86:          ai = (ai + 1) & 7;
1.1.1.2   maekawa    87:          failures++;
                     88:          if (failures > limit)
                     89:            break;
1.1       maekawa    90:        }
                     91:       else
                     92:        {
1.1.1.2   maekawa    93:          mpz_swap (t, q);
1.1       maekawa    94:          printf ("%lu ", f);
                     95:          fflush (stdout);
1.1.1.2   maekawa    96:          failures = 0;
1.1       maekawa    97:        }
                     98:     }
                     99:
                    100:   mpz_clear (q);
                    101:   mpz_clear (r);
                    102: }
                    103:
                    104: void
1.1.1.2   maekawa   105: factor_using_division_2kp (mpz_t t, unsigned int limit, unsigned long p)
1.1       maekawa   106: {
1.1.1.2   maekawa   107:   mpz_t r;
                    108:   mpz_t f;
                    109:   unsigned int k;
                    110:
                    111:   mpz_init (r);
                    112:   mpz_init_set_ui (f, 2 * p);
                    113:   mpz_add_ui (f, f, 1);
                    114:   for (k = 1; k < limit; k++)
                    115:     {
                    116:       mpz_tdiv_r (r, t, f);
                    117:       while (mpz_cmp_ui (r, 0) == 0)
                    118:        {
                    119:          mpz_tdiv_q (t, t, f);
                    120:          mpz_tdiv_r (r, t, f);
                    121:          mpz_out_str (stdout, 10, f);
                    122:          fflush (stdout);
                    123:          fputc (' ', stdout);
                    124:        }
                    125:       mpz_add_ui (f, f, 2 * p);
                    126:     }
                    127:
                    128:   mpz_clear (f);
                    129:   mpz_clear (r);
                    130: }
                    131:
                    132: void
                    133: factor_using_pollard_rho (mpz_t n, int a_int, unsigned long p)
                    134: {
                    135:   mpz_t x, x1, y, P;
1.1       maekawa   136:   mpz_t a;
1.1.1.2   maekawa   137:   mpz_t g;
                    138:   mpz_t t1, t2;
                    139:   int k, l, c, i;
                    140:
                    141:   if (flag_verbose)
                    142:     {
                    143:       printf ("[pollard-rho (%d)] ", a_int);
                    144:       fflush (stdout);
                    145:     }
                    146:
                    147:   mpz_init (g);
                    148:   mpz_init (t1);
                    149:   mpz_init (t2);
1.1       maekawa   150:
                    151:   mpz_init_set_si (a, a_int);
1.1.1.2   maekawa   152:   mpz_init_set_si (y, 2);
                    153:   mpz_init_set_si (x, 2);
                    154:   mpz_init_set_si (x1, 2);
                    155:   k = 1;
                    156:   l = 1;
                    157:   mpz_init_set_ui (P, 1);
                    158:   c = 0;
1.1       maekawa   159:
                    160:   while (mpz_cmp_ui (n, 1) != 0)
                    161:     {
1.1.1.2   maekawa   162: S2:
                    163:       if (p != 0)
1.1       maekawa   164:        {
1.1.1.2   maekawa   165:          mpz_powm_ui (x, x, p, n); mpz_add (x, x, a);
1.1       maekawa   166:        }
                    167:       else
                    168:        {
1.1.1.2   maekawa   169:          mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
1.1       maekawa   170:        }
1.1.1.2   maekawa   171:       mpz_sub (t1, x1, x); mpz_mul (t2, P, t1); mpz_mod (P, t2, n);
                    172:       c++;
                    173:       if (c == 20)
                    174:        {
                    175:          c = 0;
                    176:          mpz_gcd (g, P, n);
                    177:          if (mpz_cmp_ui (g, 1) != 0)
                    178:            goto S4;
                    179:          mpz_set (y, x);
                    180:        }
                    181: S3:
                    182:       k--;
                    183:       if (k != 0)
                    184:        goto S2;
                    185:
                    186:       mpz_gcd (g, P, n);
                    187:       if (mpz_cmp_ui (g, 1) != 0)
                    188:        goto S4;
                    189:
                    190:       mpz_set (x1, x);
                    191:       k = l;
                    192:       l = 2 * l;
                    193:       for (i = 0; i < k; i++)
                    194:        {
                    195:          if (p != 0)
                    196:            {
                    197:              mpz_powm_ui (x, x, p, n); mpz_add (x, x, a);
                    198:            }
                    199:          else
                    200:            {
                    201:              mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);
                    202:            }
                    203:        }
                    204:       mpz_set (y, x);
                    205:       c = 0;
                    206:       goto S2;
                    207: S4:
                    208:       do
                    209:        {
                    210:          if (p != 0)
                    211:            {
                    212:              mpz_powm_ui (y, y, p, n); mpz_add (y, y, a);
                    213:            }
                    214:          else
                    215:            {
                    216:              mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);
                    217:            }
                    218:          mpz_sub (t1, x1, y); mpz_gcd (g, t1, n);
                    219:        }
                    220:       while (mpz_cmp_ui (g, 1) == 0);
1.1       maekawa   221:
1.1.1.2   maekawa   222:       if (!mpz_probab_prime_p (g, 3))
1.1       maekawa   223:        {
1.1.1.2   maekawa   224:          do
1.1.1.3 ! ohara     225:             {
        !           226:               mp_limb_t a_limb;
        !           227:               mpn_random (&a_limb, (mp_size_t) 1);
        !           228:               a_int = (int) a_limb;
        !           229:             }
1.1.1.2   maekawa   230:          while (a_int == -2 || a_int == 0);
                    231:
                    232:          if (flag_verbose)
1.1       maekawa   233:            {
1.1.1.2   maekawa   234:              printf ("[composite factor--restarting pollard-rho] ");
                    235:              fflush (stdout);
1.1       maekawa   236:            }
1.1.1.2   maekawa   237:          factor_using_pollard_rho (g, a_int, p);
                    238:          break;
                    239:        }
                    240:       else
                    241:        {
                    242:          mpz_out_str (stdout, 10, g);
                    243:          fflush (stdout);
                    244:          fputc (' ', stdout);
                    245:        }
                    246:       mpz_div (n, n, g);
                    247:       mpz_mod (x, x, n);
                    248:       mpz_mod (x1, x1, n);
                    249:       mpz_mod (y, y, n);
                    250:       if (mpz_probab_prime_p (n, 3))
                    251:        {
                    252:          mpz_out_str (stdout, 10, n);
                    253:          fflush (stdout);
                    254:          fputc (' ', stdout);
                    255:          break;
1.1       maekawa   256:        }
                    257:     }
                    258:
1.1.1.2   maekawa   259:   mpz_clear (g);
                    260:   mpz_clear (P);
                    261:   mpz_clear (t2);
                    262:   mpz_clear (t1);
1.1       maekawa   263:   mpz_clear (a);
1.1.1.2   maekawa   264:   mpz_clear (x1);
1.1       maekawa   265:   mpz_clear (x);
                    266:   mpz_clear (y);
                    267: }
                    268:
1.1.1.2   maekawa   269: void
                    270: factor (mpz_t t, unsigned long p)
                    271: {
                    272:   unsigned int division_limit;
                    273:
1.1.1.3 ! ohara     274:   if (mpz_sgn (t) == 0)
        !           275:     return;
        !           276:
1.1.1.2   maekawa   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;
                    281:   else
                    282:     division_limit = division_limit * division_limit;
                    283:
                    284:   if (p != 0)
                    285:     factor_using_division_2kp (t, division_limit / 10, p);
                    286:   else
                    287:     factor_using_division (t, division_limit);
                    288:
                    289:   if (mpz_cmp_ui (t, 1) != 0)
                    290:     {
                    291:       if (flag_verbose)
                    292:        {
                    293:          printf ("[is number prime?] ");
                    294:          fflush (stdout);
                    295:        }
                    296:       if (mpz_probab_prime_p (t, 3))
                    297:        mpz_out_str (stdout, 10, t);
                    298:       else
                    299:        factor_using_pollard_rho (t, 1, p);
                    300:     }
1.1       maekawa   301: }
                    302:
1.1.1.2   maekawa   303: main (int argc, char *argv[])
1.1       maekawa   304: {
                    305:   mpz_t t;
                    306:   unsigned long p;
                    307:   int i;
                    308:
1.1.1.2   maekawa   309:   if (argc > 1 && !strcmp (argv[1], "-v"))
                    310:     {
                    311:       flag_verbose = 1;
                    312:       argv++;
                    313:       argc--;
                    314:     }
                    315:
1.1.1.3 ! ohara     316:   mpz_init (t);
        !           317:   if (argc > 1)
1.1       maekawa   318:     {
1.1.1.3 ! ohara     319:       p = 0;
        !           320:       for (i = 1; i < argc; i++)
1.1       maekawa   321:        {
1.1.1.3 ! ohara     322:          if (!strncmp (argv[i], "-Mp", 3))
        !           323:            {
        !           324:              p = atoi (argv[i] + 3);
        !           325:              mpz_set_ui (t, 1);
        !           326:              mpz_mul_2exp (t, t, p);
        !           327:              mpz_sub_ui (t, t, 1);
        !           328:            }
        !           329:          else if (!strncmp (argv[i], "-2kp", 4))
        !           330:            {
        !           331:              p = atoi (argv[i] + 4);
        !           332:              continue;
        !           333:            }
        !           334:          else
        !           335:            {
        !           336:              mpz_set_str (t, argv[i], 0);
        !           337:            }
1.1       maekawa   338:
1.1.1.3 ! ohara     339:          if (mpz_cmp_ui (t, 0) == 0)
        !           340:            puts ("-");
        !           341:          else
        !           342:            {
        !           343:              factor (t, p);
        !           344:              puts ("");
        !           345:            }
        !           346:        }
        !           347:     }
        !           348:   else
        !           349:     {
        !           350:       for (;;)
1.1.1.2   maekawa   351:        {
1.1.1.3 ! ohara     352:          mpz_inp_str (t, stdin, 0);
        !           353:          if (feof (stdin))
        !           354:            break;
        !           355:          mpz_out_str (stdout, 10, t); printf (" = ");
        !           356:          factor (t, 0);
1.1.1.2   maekawa   357:          puts ("");
                    358:        }
1.1       maekawa   359:     }
1.1.1.2   maekawa   360:
1.1.1.3 ! ohara     361:   exit (0);
1.1       maekawa   362: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>