GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/* Factoring with Pollard's rho method.12Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005 Free Software3Foundation, Inc.45This program is free software; you can redistribute it and/or modify it under6the terms of the GNU General Public License as published by the Free Software7Foundation; either version 2, or (at your option) any later version.89This program is distributed in the hope that it will be useful, but WITHOUT ANY10WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A11PARTICULAR PURPOSE. See the GNU General Public License for more details.1213You should have received a copy of the GNU General Public License along with14this program; see the file COPYING. If not, write to the Free Software15Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */1617#include <stdlib.h>18#include <stdio.h>19#include <string.h>2021#include "gmp.h"2223int flag_verbose = 0;2425static unsigned add[] = {4, 2, 4, 2, 4, 6, 2, 6};2627void28factor_using_division (mpz_t t, unsigned int limit)29{30mpz_t q, r;31unsigned long int f;32int ai;33unsigned *addv = add;34unsigned int failures;3536if (flag_verbose)37{38printf ("[trial division (%u)] ", limit);39fflush (stdout);40}4142mpz_init (q);43mpz_init (r);4445f = mpz_scan1 (t, 0);46mpz_div_2exp (t, t, f);47while (f)48{49printf ("2 ");50fflush (stdout);51--f;52}5354for (;;)55{56mpz_tdiv_qr_ui (q, r, t, 3);57if (mpz_cmp_ui (r, 0) != 0)58break;59mpz_set (t, q);60printf ("3 ");61fflush (stdout);62}6364for (;;)65{66mpz_tdiv_qr_ui (q, r, t, 5);67if (mpz_cmp_ui (r, 0) != 0)68break;69mpz_set (t, q);70printf ("5 ");71fflush (stdout);72}7374failures = 0;75f = 7;76ai = 0;77while (mpz_cmp_ui (t, 1) != 0)78{79mpz_tdiv_qr_ui (q, r, t, f);80if (mpz_cmp_ui (r, 0) != 0)81{82f += addv[ai];83if (mpz_cmp_ui (q, f) < 0)84break;85ai = (ai + 1) & 7;86failures++;87if (failures > limit)88break;89}90else91{92mpz_swap (t, q);93printf ("%lu ", f);94fflush (stdout);95failures = 0;96}97}9899mpz_clear (q);100mpz_clear (r);101}102103void104factor_using_division_2kp (mpz_t t, unsigned int limit, unsigned long p)105{106mpz_t r;107mpz_t f;108unsigned int k;109110if (flag_verbose)111{112printf ("[trial division (%u)] ", limit);113fflush (stdout);114}115116mpz_init (r);117mpz_init_set_ui (f, 2 * p);118mpz_add_ui (f, f, 1);119for (k = 1; k < limit; k++)120{121mpz_tdiv_r (r, t, f);122while (mpz_cmp_ui (r, 0) == 0)123{124mpz_tdiv_q (t, t, f);125mpz_tdiv_r (r, t, f);126mpz_out_str (stdout, 10, f);127fflush (stdout);128fputc (' ', stdout);129}130mpz_add_ui (f, f, 2 * p);131}132133mpz_clear (f);134mpz_clear (r);135}136137void138factor_using_pollard_rho (mpz_t n, int a_int, unsigned long p)139{140mpz_t x, x1, y, P;141mpz_t a;142mpz_t g;143mpz_t t1, t2;144int k, l, c, i;145146if (flag_verbose)147{148printf ("[pollard-rho (%d)] ", a_int);149fflush (stdout);150}151152mpz_init (g);153mpz_init (t1);154mpz_init (t2);155156mpz_init_set_si (a, a_int);157mpz_init_set_si (y, 2);158mpz_init_set_si (x, 2);159mpz_init_set_si (x1, 2);160k = 1;161l = 1;162mpz_init_set_ui (P, 1);163c = 0;164165while (mpz_cmp_ui (n, 1) != 0)166{167S2:168if (p != 0)169{170mpz_powm_ui (x, x, p, n); mpz_add (x, x, a);171}172else173{174mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);175}176mpz_sub (t1, x1, x); mpz_mul (t2, P, t1); mpz_mod (P, t2, n);177c++;178if (c == 20)179{180c = 0;181mpz_gcd (g, P, n);182if (mpz_cmp_ui (g, 1) != 0)183goto S4;184mpz_set (y, x);185}186S3:187k--;188if (k > 0)189goto S2;190191mpz_gcd (g, P, n);192if (mpz_cmp_ui (g, 1) != 0)193goto S4;194195mpz_set (x1, x);196k = l;197l = 2 * l;198for (i = 0; i < k; i++)199{200if (p != 0)201{202mpz_powm_ui (x, x, p, n); mpz_add (x, x, a);203}204else205{206mpz_mul (x, x, x); mpz_add (x, x, a); mpz_mod (x, x, n);207}208}209mpz_set (y, x);210c = 0;211goto S2;212S4:213do214{215if (p != 0)216{217mpz_powm_ui (y, y, p, n); mpz_add (y, y, a);218}219else220{221mpz_mul (y, y, y); mpz_add (y, y, a); mpz_mod (y, y, n);222}223mpz_sub (t1, x1, y); mpz_gcd (g, t1, n);224}225while (mpz_cmp_ui (g, 1) == 0);226227mpz_div (n, n, g); /* divide by g, before g is overwritten */228229if (!mpz_probab_prime_p (g, 3))230{231do232{233mp_limb_t a_limb;234mpn_random (&a_limb, (mp_size_t) 1);235a_int = (int) a_limb;236}237while (a_int == -2 || a_int == 0);238239if (flag_verbose)240{241printf ("[composite factor--restarting pollard-rho] ");242fflush (stdout);243}244factor_using_pollard_rho (g, a_int, p);245}246else247{248mpz_out_str (stdout, 10, g);249fflush (stdout);250fputc (' ', stdout);251}252mpz_mod (x, x, n);253mpz_mod (x1, x1, n);254mpz_mod (y, y, n);255if (mpz_probab_prime_p (n, 3))256{257mpz_out_str (stdout, 10, n);258fflush (stdout);259fputc (' ', stdout);260break;261}262}263264mpz_clear (g);265mpz_clear (P);266mpz_clear (t2);267mpz_clear (t1);268mpz_clear (a);269mpz_clear (x1);270mpz_clear (x);271mpz_clear (y);272}273274void275factor (mpz_t t, unsigned long p)276{277unsigned int division_limit;278279if (mpz_sgn (t) == 0)280return;281282/* Set the trial division limit according the size of t. */283division_limit = mpz_sizeinbase (t, 2);284if (division_limit > 1000)285division_limit = 1000 * 1000;286else287division_limit = division_limit * division_limit;288289if (p != 0)290factor_using_division_2kp (t, division_limit / 10, p);291else292factor_using_division (t, division_limit);293294if (mpz_cmp_ui (t, 1) != 0)295{296if (flag_verbose)297{298printf ("[is number prime?] ");299fflush (stdout);300}301if (mpz_probab_prime_p (t, 3))302mpz_out_str (stdout, 10, t);303else304factor_using_pollard_rho (t, 1, p);305}306}307308main (int argc, char *argv[])309{310mpz_t t;311unsigned long p;312int i;313314if (argc > 1 && !strcmp (argv[1], "-v"))315{316flag_verbose = 1;317argv++;318argc--;319}320321mpz_init (t);322if (argc > 1)323{324p = 0;325for (i = 1; i < argc; i++)326{327if (!strncmp (argv[i], "-Mp", 3))328{329p = atoi (argv[i] + 3);330mpz_set_ui (t, 1);331mpz_mul_2exp (t, t, p);332mpz_sub_ui (t, t, 1);333}334else if (!strncmp (argv[i], "-2kp", 4))335{336p = atoi (argv[i] + 4);337continue;338}339else340{341mpz_set_str (t, argv[i], 0);342}343344if (mpz_cmp_ui (t, 0) == 0)345puts ("-");346else347{348factor (t, p);349puts ("");350}351}352}353else354{355for (;;)356{357mpz_inp_str (t, stdin, 0);358if (feof (stdin))359break;360mpz_out_str (stdout, 10, t); printf (" = ");361factor (t, 0);362puts ("");363}364}365366exit (0);367}368369370