Code coverage tests

This page documents the degree to which the PARI/GP source code is tested by our public test suite, distributed with the source distribution in directory src/test/. This is measured by the gcov utility; we then process gcov output using the lcov frond-end.

We test a few variants depending on Configure flags on the pari.math.u-bordeaux.fr machine (x86_64 architecture), and agregate them in the final report:

The target is to exceed 90% coverage for all mathematical modules (given that branches depending on DEBUGLEVEL or DEBUGMEM are not covered). This script is run to produce the results below.

LCOV - code coverage report
Current view: top level - basemath - ifactor1.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.18.0 lcov report (development 29818-b3e15d99d2) Lines: 1579 1918 82.3 %
Date: 2024-12-27 09:09:37 Functions: 93 107 86.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2000  The PARI group.
       2             : 
       3             : This file is part of the PARI/GP package.
       4             : 
       5             : PARI/GP is free software; you can redistribute it and/or modify it under the
       6             : terms of the GNU General Public License as published by the Free Software
       7             : Foundation; either version 2 of the License, or (at your option) any later
       8             : version. It is distributed in the hope that it will be useful, but WITHOUT
       9             : ANY WARRANTY WHATSOEVER.
      10             : 
      11             : Check the License for details. You should have received a copy of it, along
      12             : with the package; see the file 'COPYING'. If not, write to the Free Software
      13             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      14             : #include "pari.h"
      15             : #include "paripriv.h"
      16             : 
      17             : #define DEBUGLEVEL DEBUGLEVEL_factorint
      18             : 
      19             : /***********************************************************************/
      20             : /**                       PRIMES IN SUCCESSION                        **/
      21             : /***********************************************************************/
      22             : 
      23             : /* map from prime residue classes mod 210 to their numbers in {0...47}.
      24             :  * Subscripts into this array take the form ((k-1)%210)/2, ranging from
      25             :  * 0 to 104.  Unused entries are */
      26             : #define NPRC 128 /* nonprime residue class */
      27             : 
      28             : static unsigned char prc210_no[] = {
      29             :   0, NPRC, NPRC, NPRC, NPRC, 1, 2, NPRC, 3, 4, NPRC, /* 21 */
      30             :   5, NPRC, NPRC, 6, 7, NPRC, NPRC, 8, NPRC, 9, /* 41 */
      31             :   10, NPRC, 11, NPRC, NPRC, 12, NPRC, NPRC, 13, 14, NPRC, /* 63 */
      32             :   NPRC, 15, NPRC, 16, 17, NPRC, NPRC, 18, NPRC, 19, /* 83 */
      33             :   NPRC, NPRC, 20, NPRC, NPRC, NPRC, 21, NPRC, 22, 23, NPRC, /* 105 */
      34             :   24, 25, NPRC, 26, NPRC, NPRC, NPRC, 27, NPRC, NPRC, /* 125 */
      35             :   28, NPRC, 29, NPRC, NPRC, 30, 31, NPRC, 32, NPRC, NPRC, /* 147 */
      36             :   33, 34, NPRC, NPRC, 35, NPRC, NPRC, 36, NPRC, 37, /* 167 */
      37             :   38, NPRC, 39, NPRC, NPRC, 40, 41, NPRC, NPRC, 42, NPRC, /* 189 */
      38             :   43, 44, NPRC, 45, 46, NPRC, NPRC, NPRC, NPRC, 47, /* 209 */
      39             : };
      40             : 
      41             : /* first differences of the preceding */
      42             : static unsigned char prc210_d1[] = {
      43             :   10, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6,
      44             :   4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6,
      45             :   2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, 2,
      46             : };
      47             : 
      48             : static int
      49      900975 : unextprime_overflow(ulong n)
      50             : {
      51             : #ifdef LONG_IS_64BIT
      52      900389 :   return (n > (ulong)-59);
      53             : #else
      54         586 :   return (n > (ulong)-5);
      55             : #endif
      56             : }
      57             : 
      58             : /* return 0 for overflow */
      59             : ulong
      60     1038073 : unextprime(ulong n)
      61             : {
      62             :   long rc, rc0, rcn;
      63             : 
      64     1038073 :   switch(n) {
      65        6858 :     case 0: case 1: case 2: return 2;
      66        2434 :     case 3: return 3;
      67        1668 :     case 4: case 5: return 5;
      68        1162 :     case 6: case 7: return 7;
      69             :   }
      70     1025951 :   if (n <= maxprime())
      71             :   {
      72      124964 :     long i = PRIMES_search(n);
      73      124964 :     return i > 0? n: pari_PRIMES[-i];
      74             :   }
      75      900978 :   if (unextprime_overflow(n)) return 0;
      76             :   /* here n > 7 */
      77      900944 :   n |= 1; /* make it odd */
      78      900944 :   rc = rc0 = n % 210;
      79             :   /* find next prime residue class mod 210 */
      80             :   for(;;)
      81             :   {
      82     1984677 :     rcn = (long)(prc210_no[rc>>1]);
      83     1984677 :     if (rcn != NPRC) break;
      84     1083733 :     rc += 2; /* cannot wrap since 209 is coprime and rc odd */
      85             :   }
      86      900944 :   if (rc > rc0) n += rc - rc0;
      87             :   /* now find an actual (pseudo)prime */
      88             :   for(;;)
      89             :   {
      90    10624154 :     if (uisprime(n)) break;
      91     9723210 :     n += prc210_d1[rcn];
      92     9723210 :     if (++rcn > 47) rcn = 0;
      93             :   }
      94      900969 :   return n;
      95             : }
      96             : 
      97             : GEN
      98      126847 : nextprime(GEN n)
      99             : {
     100             :   long rc, rc0, rcn;
     101      126847 :   pari_sp av = avma;
     102             : 
     103      126847 :   if (typ(n) != t_INT)
     104             :   {
     105          14 :     n = gceil(n);
     106          14 :     if (typ(n) != t_INT) pari_err_TYPE("nextprime",n);
     107             :   }
     108      126840 :   if (signe(n) <= 0) { set_avma(av); return gen_2; }
     109      126840 :   if (lgefint(n) == 3)
     110             :   {
     111      118710 :     ulong k = unextprime(uel(n,2));
     112      118710 :     set_avma(av);
     113      118710 :     if (k) return utoipos(k);
     114             : #ifdef LONG_IS_64BIT
     115           6 :     return uutoi(1,13);
     116             : #else
     117           1 :     return uutoi(1,15);
     118             : #endif
     119             :   }
     120             :   /* here n > 7 */
     121        8130 :   if (!mod2(n)) n = addui(1,n);
     122        8130 :   rc = rc0 = umodiu(n, 210);
     123             :   /* find next prime residue class mod 210 */
     124             :   for(;;)
     125             :   {
     126       17701 :     rcn = (long)(prc210_no[rc>>1]);
     127       17701 :     if (rcn != NPRC) break;
     128        9571 :     rc += 2; /* cannot wrap since 209 is coprime and rc odd */
     129             :   }
     130        8130 :   if (rc > rc0) n = addui(rc - rc0, n);
     131             :   /* now find an actual (pseudo)prime */
     132             :   for(;;)
     133             :   {
     134       84466 :     if (BPSW_psp(n)) break;
     135       76336 :     n = addui(prc210_d1[rcn], n);
     136       76336 :     if (++rcn > 47) rcn = 0;
     137             :   }
     138        8130 :   if (avma == av) return icopy(n);
     139        8130 :   return gerepileuptoint(av, n);
     140             : }
     141             : 
     142             : ulong
     143          32 : uprecprime(ulong n)
     144             : {
     145             :   long rc, rc0, rcn;
     146             :   { /* check if n <= 10 */
     147          32 :     if (n <= 1)  return 0;
     148          25 :     if (n == 2)  return 2;
     149          18 :     if (n <= 4)  return 3;
     150          18 :     if (n <= 6)  return 5;
     151          18 :     if (n <= 10) return 7;
     152             :   }
     153          18 :   if (n <= maxprimelim())
     154             :   {
     155           0 :     long i = PRIMES_search(n);
     156           0 :     return i > 0? n: pari_PRIMES[-i-1];
     157             :   }
     158             :   /* here n >= 11 */
     159          18 :   if (!(n % 2)) n--;
     160          18 :   rc = rc0 = n % 210;
     161             :   /* find previous prime residue class mod 210 */
     162             :   for(;;)
     163             :   {
     164          36 :     rcn = (long)(prc210_no[rc>>1]);
     165          36 :     if (rcn != NPRC) break;
     166          18 :     rc -= 2; /* cannot wrap since 1 is coprime and rc odd */
     167             :   }
     168          18 :   if (rc < rc0) n += rc - rc0;
     169             :   /* now find an actual (pseudo)prime */
     170             :   for(;;)
     171             :   {
     172          36 :     if (uisprime(n)) break;
     173          18 :     if (--rcn < 0) rcn = 47;
     174          18 :     n -= prc210_d1[rcn];
     175             :   }
     176          18 :   return n;
     177             : }
     178             : 
     179             : GEN
     180          49 : precprime(GEN n)
     181             : {
     182             :   long rc, rc0, rcn;
     183          49 :   pari_sp av = avma;
     184             : 
     185          49 :   if (typ(n) != t_INT)
     186             :   {
     187          14 :     n = gfloor(n);
     188          14 :     if (typ(n) != t_INT) pari_err_TYPE("nextprime",n);
     189             :   }
     190          42 :   if (signe(n) <= 0) { set_avma(av); return gen_0; }
     191          42 :   if (lgefint(n) <= 3)
     192             :   {
     193          32 :     ulong k = uel(n,2);
     194          32 :     return gc_utoi(av, uprecprime(k));
     195             :   }
     196          10 :   if (!mod2(n)) n = subiu(n,1);
     197          10 :   rc = rc0 = umodiu(n, 210);
     198             :   /* find previous prime residue class mod 210 */
     199             :   for(;;)
     200             :   {
     201          20 :     rcn = (long)(prc210_no[rc>>1]);
     202          20 :     if (rcn != NPRC) break;
     203          10 :     rc -= 2; /* cannot wrap since 1 is coprime and rc odd */
     204             :   }
     205          10 :   if (rc0 > rc) n = subiu(n, rc0 - rc);
     206             :   /* now find an actual (pseudo)prime */
     207             :   for(;;)
     208             :   {
     209          48 :     if (BPSW_psp(n)) break;
     210          38 :     if (--rcn < 0) rcn = 47;
     211          38 :     n = subiu(n, prc210_d1[rcn]);
     212             :   }
     213          10 :   if (avma == av) return icopy(n);
     214          10 :   return gerepileuptoint(av, n);
     215             : }
     216             : 
     217             : /* Find next single-word prime strictly larger than p.
     218             :  * If *n < pari_PRIMES[0], p is *n-th prime, otherwise imitate nextprime().
     219             :  * *rcn = NPRC or the correct residue class for the current p; we'll use this
     220             :  * to track the current prime residue class mod 210 once we're out of range of
     221             :  * the prime table, and we'll update it before that if it isn't NPRC.
     222             :  *
     223             :  * *q is incremented whenever q!=NULL and we wrap from 209 mod 210 to
     224             :  * 1 mod 210 */
     225             : static ulong
     226     4535017 : snextpr(ulong p, long *n, long *rcn, long *q, int (*ispsp)(ulong))
     227             : {
     228     4535017 :   if (*n < pari_PRIMES[0])
     229             :   {
     230     4535017 :     ulong t, p1 = t = pari_PRIMES[++*n]; /* nextprime(p + 1) */
     231     4535017 :     if (*rcn != NPRC)
     232             :     {
     233    15899542 :       while (t > p)
     234             :       {
     235    11381022 :         t -= prc210_d1[*rcn];
     236    11381022 :         if (++*rcn > 47) { *rcn = 0; if (q) (*q)++; }
     237             :       }
     238             :       /* assert(d1 == p) */
     239             :     }
     240     4535017 :     return p1;
     241             :   }
     242           0 :   if (unextprime_overflow(p)) pari_err_OVERFLOW("snextpr");
     243             :   /* we are beyond the prime table, initialize if needed */
     244           0 :   if (*rcn == NPRC) *rcn = prc210_no[(p % 210) >> 1]; /* != NPRC */
     245             :   /* look for the next one */
     246             :   do {
     247           0 :     p += prc210_d1[*rcn];
     248           0 :     if (++*rcn > 47) { *rcn = 0; if (q) (*q)++; }
     249           0 :   } while (!ispsp(p));
     250           0 :   return p;
     251             : }
     252             : 
     253             : /********************************************************************/
     254             : /**                                                                **/
     255             : /**                     INTEGER FACTORIZATION                      **/
     256             : /**                                                                **/
     257             : /********************************************************************/
     258             : int factor_add_primes = 0, factor_proven = 0;
     259             : 
     260             : /***********************************************************************/
     261             : /**                                                                   **/
     262             : /**                 FACTORIZATION (ECM) -- GN Jul-Aug 1998            **/
     263             : /**   Integer factorization using the elliptic curves method (ECM).   **/
     264             : /**   ellfacteur() returns a non trivial factor of N, assuming N>0,   **/
     265             : /**   is composite, and has no prime divisor below tridiv_bound(N)    **/
     266             : /**   Thanks to Paul Zimmermann for much helpful advice and to        **/
     267             : /**   Guillaume Hanrot and Igor Schein for intensive testing          **/
     268             : /**                                                                   **/
     269             : /***********************************************************************/
     270             : #define nbcmax 64 /* max number of simultaneous curves */
     271             : 
     272             : static const ulong TB1[] = {
     273             :   142,172,208,252,305,370,450,545,661,801,972,1180,1430,
     274             :   1735,2100,2550,3090,3745,4540,5505,6675,8090,9810,11900,
     275             :   14420,17490,21200,25700,31160,37780UL,45810UL,55550UL,67350UL,
     276             :   81660UL,99010UL,120050UL,145550UL,176475UL,213970UL,259430UL,
     277             :   314550UL,381380UL,462415UL,560660UL,679780UL,824220UL,999340UL,
     278             :   1211670UL,1469110UL,1781250UL,2159700UL,2618600UL,3175000UL,
     279             :   3849600UL,4667500UL,5659200UL,6861600UL,8319500UL,10087100UL,
     280             :   12230300UL,14828900UL,17979600UL,21799700UL,26431500UL,
     281             :   32047300UL,38856400UL, /* 110 times that still fits into 32bits */
     282             : #ifdef LONG_IS_64BIT
     283             :   47112200UL,57122100UL,69258800UL,83974200UL,101816200UL,
     284             :   123449000UL,149678200UL,181480300UL,220039400UL,266791100UL,
     285             :   323476100UL,392204900UL,475536500UL,576573500UL,699077800UL,
     286             :   847610500UL,1027701900UL,1246057200UL,1510806400UL,1831806700UL,
     287             :   2221009800UL,2692906700UL,3265067200UL,3958794400UL,4799917500UL
     288             : #endif
     289             : };
     290             : static const ulong TB1_for_stage[] = {
     291             :  /* Start below the optimal B1 for finding factors which would just have been
     292             :   * missed by pollardbrent(), and escalate, changing curves to give good
     293             :   * coverage of the small factor ranges. Entries grow faster than what would
     294             :   * be optimal but a table instead of a 2D array keeps the code simple */
     295             :   500,520,560,620,700,800,900,1000,1150,1300,1450,1600,1800,2000,
     296             :   2200,2450,2700,2950,3250,3600,4000,4400,4850,5300,5800,6400,
     297             :   7100,7850,8700,9600,10600,11700,12900,14200,15700,17300,
     298             :   19000,21000,23200,25500,28000,31000,34500UL,38500UL,43000UL,
     299             :   48000UL,53800UL,60400UL,67750UL,76000UL,85300UL,95700UL,
     300             :   107400UL,120500UL,135400UL,152000UL,170800UL,191800UL,215400UL,
     301             :   241800UL,271400UL,304500UL,341500UL,383100UL,429700UL,481900UL,
     302             :   540400UL,606000UL,679500UL,761800UL,854100UL,957500UL,1073500UL
     303             : };
     304             : 
     305             : /* addition/doubling/multiplication of a point on an 'elliptic curve mod N'
     306             :  * may result in one of three things:
     307             :  * - a new bona fide point
     308             :  * - a point at infinity (denominator divisible by N)
     309             :  * - a point at infinity mod some p | N but finite mod q | N betraying itself
     310             :  *   by a denominator which has nontrivial gcd with N.
     311             :  *
     312             :  * In the second case, addition/doubling aborts, copying one of the summands
     313             :  * to the destination array of points unless they coincide.
     314             :  * Multiplication will stop at some unpredictable intermediate stage:  The
     315             :  * destination will contain _some_ multiple of the input point, but not
     316             :  * necessarily the desired one, which doesn't matter.  As long as we're
     317             :  * multiplying (B1 phase) we simply carry on with the next multiplier.
     318             :  * During the B2 phase, the only additions are the giant steps, and the
     319             :  * worst that can happen here is that we lose one residue class mod 210
     320             :  * of prime multipliers on 4 of the curves, so again, we ignore the problem
     321             :  * and just carry on.)
     322             :  *
     323             :  * Idea: select nbc curves mod N and one point P on each of them. For each
     324             :  * such P, compute [M]P = Q where M is the product of all powers <= B2 of
     325             :  * primes <= nextprime(B1). Then check whether [p]Q for p < nextprime(B2)
     326             :  * betrays a factor. This second stage looks separately at the primes in
     327             :  * each residue class mod 210, four curves at a time, and steps additively
     328             :  * to ever larger multipliers, by comparing X coordinates of points which we
     329             :  * would need to add in order to reach another prime multiplier in the same
     330             :  * residue class. 'Comparing' means that we accumulate a product of
     331             :  * differences of X coordinates, and from time to time take a gcd of this
     332             :  * product with N. Montgomery's multi-inverse trick is used heavily. */
     333             : 
     334             : /* *** auxiliary functions for ellfacteur: *** */
     335             : /* (Rx,Ry) <- (Px,Py)+(Qx,Qy) over Z/NZ, z=1/(Px-Qx). If Ry = NULL, don't set */
     336             : static void
     337     8303292 : FpE_add_i(GEN N, GEN z, GEN Px, GEN Py, GEN Qx, GEN Qy, GEN *Rx, GEN *Ry)
     338             : {
     339     8303292 :   GEN slope = modii(mulii(subii(Py, Qy), z), N);
     340     8303292 :   GEN t = subii(sqri(slope), addii(Qx, Px));
     341     8303292 :   affii(modii(t, N), *Rx);
     342     8303292 :   if (Ry) {
     343     8230924 :     t = subii(mulii(slope, subii(Px, *Rx)), Py);
     344     8230924 :     affii(modii(t, N), *Ry);
     345             :   }
     346     8303292 : }
     347             : /* X -> Z; cannot add on one of the curves: make sure Z contains
     348             :  * something useful before letting caller proceed */
     349             : static void
     350       26135 : ZV_aff(long n, GEN *X, GEN *Z)
     351             : {
     352       26135 :   if (X != Z) {
     353             :     long k;
     354     1576379 :     for (k = n; k--; ) affii(X[k],Z[k]);
     355             :   }
     356       26135 : }
     357             : 
     358             : /* Parallel addition on nbc curves, assigning the result to locations at and
     359             :  * following *X3, *Y3. (If Y-coords of result not desired, set Y=NULL.)
     360             :  * Safe even if (X3,Y3) = (X2,Y2), _not_ if (X1,Y1). It is also safe to
     361             :  * overwrite Y2 with X3. If nbc1 < nbc, the first summand is
     362             :  * assumed to hold only nbc1 distinct points, repeated as often as we need
     363             :  * them  (to add one point on each of a few curves to several other points on
     364             :  * the same curves): only used with nbc1 = nbc or nbc1 = 4 | nbc.
     365             :  *
     366             :  * Return 0 [SUCCESS], 1 [N | den], 2 [gcd(den, N) is a factor of N, preserved
     367             :  * in gl.
     368             :  * Stack space is bounded by a constant multiple of lgefint(N)*nbc:
     369             :  * - Phase 2 creates 12 items on the stack per iteration, of which 4 are twice
     370             :  *   as long and 1 is thrice as long as N, i.e. 18 units per iteration.
     371             :  * - Phase  1 creates 4 units.
     372             :  * Total can be as large as 4*nbcmax + 18*8 units; ecm_elladd2() is
     373             :  * just as bad, and elldouble() comes to 3*nbcmax + 29*8 units. */
     374             : static int
     375      241870 : ecm_elladd0(GEN N, GEN *gl, long nbc, long nbc1,
     376             :             GEN *X1, GEN *Y1, GEN *X2, GEN *Y2, GEN *X3, GEN *Y3)
     377             : {
     378      241870 :   const ulong mask = (nbc1 == 4)? 3: ~0UL; /*nbc1 = 4 or nbc*/
     379      241870 :   GEN W[2*nbcmax], *A = W+nbc; /* W[0],A[0] unused */
     380             :   long i;
     381      241870 :   pari_sp av = avma;
     382             : 
     383      241870 :   W[1] = subii(X1[0], X2[0]);
     384     7837896 :   for (i=1; i<nbc; i++)
     385             :   { /*prepare for multi-inverse*/
     386     7596026 :     A[i] = subii(X1[i&mask], X2[i]); /* don't waste time reducing mod N */
     387     7596026 :     W[i+1] = modii(mulii(A[i], W[i]), N);
     388             :   }
     389      241870 :   if (!invmod(W[nbc], N, gl))
     390             :   {
     391          75 :     if (!equalii(N,*gl)) return 2;
     392          49 :     ZV_aff(nbc, X2,X3);
     393          49 :     if (Y3) ZV_aff(nbc, Y2,Y3);
     394          49 :     return gc_int(av,1);
     395             :   }
     396             : 
     397     7836220 :   while (i--) /* nbc times */
     398             :   {
     399     7836220 :     pari_sp av2 = avma;
     400     7836220 :     GEN Px = X1[i&mask], Py = Y1[i&mask], Qx = X2[i], Qy = Y2[i];
     401     7836220 :     GEN z = i? mulii(*gl,W[i]): *gl; /*1/(Px-Qx)*/
     402     7836220 :     FpE_add_i(N,z,  Px,Py,Qx,Qy, X3+i, Y3? Y3+i: NULL);
     403     7836220 :     if (!i) break;
     404     7594425 :     set_avma(av2); *gl = modii(mulii(*gl, A[i]), N);
     405             :   }
     406      241795 :   return gc_int(av,0);
     407             : }
     408             : 
     409             : /* Shortcut, for use in cases where Y coordinates follow their corresponding
     410             :  * X coordinates, and first summand doesn't need to be repeated */
     411             : static int
     412      235914 : ecm_elladd(GEN N, GEN *gl, long nbc, GEN *X1, GEN *X2, GEN *X3) {
     413      235914 :   return ecm_elladd0(N, gl, nbc, nbc, X1, X1+nbc, X2, X2+nbc, X3, X3+nbc);
     414             : }
     415             : 
     416             : /* As ecm_elladd except it does twice as many additions (and hides even more
     417             :  * of the cost of the modular inverse); the net effect is the same as
     418             :  * ecm_elladd(nbc,X1,X2,X3) && ecm_elladd(nbc,X4,X5,X6). Safe to
     419             :  * have X2=X3, X5=X6, or X1,X2 coincide with X4,X5 in any order. */
     420             : static int
     421        7233 : ecm_elladd2(GEN N, GEN *gl, long nbc,
     422             :             GEN *X1, GEN *X2, GEN *X3, GEN *X4, GEN *X5, GEN *X6)
     423             : {
     424        7233 :   GEN *Y1 = X1+nbc, *Y2 = X2+nbc, *Y3 = X3+nbc;
     425        7233 :   GEN *Y4 = X4+nbc, *Y5 = X5+nbc, *Y6 = X6+nbc;
     426        7233 :   GEN W[4*nbcmax], *A = W+2*nbc; /* W[0],A[0] unused */
     427             :   long i, j;
     428        7233 :   pari_sp av = avma;
     429             : 
     430        7233 :   W[1] = subii(X1[0], X2[0]);
     431      233544 :   for (i=1; i<nbc; i++)
     432             :   {
     433      226311 :     A[i] = subii(X1[i], X2[i]); /* don't waste time reducing mod N here */
     434      226311 :     W[i+1] = modii(mulii(A[i], W[i]), N);
     435             :   }
     436      240777 :   for (j=0; j<nbc; i++,j++)
     437             :   {
     438      233544 :     A[i] = subii(X4[j], X5[j]);
     439      233544 :     W[i+1] = modii(mulii(A[i], W[i]), N);
     440             :   }
     441        7233 :   if (!invmod(W[2*nbc], N, gl))
     442             :   {
     443           1 :     if (!equalii(N,*gl)) return 2;
     444           1 :     ZV_aff(2*nbc, X2,X3); /* hack: 2*nbc => copy Y2->Y3 */
     445           1 :     ZV_aff(2*nbc, X5,X6); /* also copy Y5->Y6 */
     446           1 :     return gc_int(av,1);
     447             :   }
     448             : 
     449      240768 :   while (j--) /* nbc times */
     450             :   {
     451      233536 :     pari_sp av2 = avma;
     452      233536 :     GEN Px = X4[j], Py = Y4[j], Qx = X5[j], Qy = Y5[j];
     453      233536 :     GEN z = mulii(*gl,W[--i]); /*1/(Px-Qx)*/
     454      233536 :     FpE_add_i(N,z, Px,Py, Qx,Qy, X6+j,Y6+j);
     455      233536 :     set_avma(av2); *gl = modii(mulii(*gl, A[i]), N);
     456             :   }
     457      233536 :   while (i--) /* nbc times */
     458             :   {
     459      233536 :     pari_sp av2 = avma;
     460      233536 :     GEN Px = X1[i], Py = Y1[i], Qx = X2[i], Qy = Y2[i];
     461      233536 :     GEN z = i? mulii(*gl, W[i]): *gl; /*1/(Px-Qx)*/
     462      233536 :     FpE_add_i(N,z, Px,Py, Qx,Qy, X3+i,Y3+i);
     463      233536 :     if (!i) break;
     464      226304 :     set_avma(av2); *gl = modii(mulii(*gl, A[i]), N);
     465             :   }
     466        7232 :   return gc_int(av,0);
     467             : }
     468             : 
     469             : /* Parallel doubling on nbc curves, assigning the result to locations at
     470             :  * and following *X2.  Safe to be called with X2 equal to X1.  Return
     471             :  * value as for ecm_elladd.  If we find a point at infinity mod N,
     472             :  * and if X1 != X2, we copy the points at X1 to X2. */
     473             : static int
     474       40628 : elldouble(GEN N, GEN *gl, long nbc, GEN *X1, GEN *X2)
     475             : {
     476       40628 :   GEN *Y1 = X1+nbc, *Y2 = X2+nbc;
     477             :   GEN W[nbcmax+1]; /* W[0] unused */
     478             :   long i;
     479       40628 :   pari_sp av = avma;
     480       40628 :   /*W[0] = gen_1;*/ W[1] = Y1[0];
     481     1237984 :   for (i=1; i<nbc; i++) W[i+1] = modii(mulii(Y1[i], W[i]), N);
     482       40628 :   if (!invmod(W[nbc], N, gl))
     483             :   {
     484           0 :     if (!equalii(N,*gl)) return 2;
     485           0 :     ZV_aff(2*nbc,X1,X2); /* also copies Y1->Y2 */
     486           0 :     return gc_int(av,1);
     487             :   }
     488     1278612 :   while (i--) /* nbc times */
     489             :   {
     490             :     pari_sp av2;
     491     1237984 :     GEN v, w, L, z = i? mulii(*gl,W[i]): *gl;
     492     1237984 :     if (i) *gl = modii(mulii(*gl, Y1[i]), N);
     493     1237984 :     av2 = avma;
     494     1237984 :     L = modii(mulii(addui(1, mului(3, Fp_sqr(X1[i],N))), z), N);
     495     1237984 :     if (signe(L)) /* half of zero is still zero */
     496     1237984 :       L = shifti(mod2(L)? addii(L, N): L, -1);
     497     1237984 :     v = modii(subii(sqri(L), shifti(X1[i],1)), N);
     498     1237984 :     w = modii(subii(mulii(L, subii(X1[i], v)), Y1[i]), N);
     499     1237984 :     affii(v, X2[i]);
     500     1237984 :     affii(w, Y2[i]);
     501     1237984 :     set_avma(av2);
     502             :   }
     503       40628 :   return gc_int(av,0);
     504             : }
     505             : 
     506             : /* Parallel multiplication by an odd prime k on nbc curves, storing the
     507             :  * result to locations at and following *X2. Safe to be called with X2 = X1.
     508             :  * Return values as ecm_elladd. Uses (a simplified variant of) Montgomery's
     509             :  * PRAC algorithm; see ftp://ftp.cwi.nl/pub/pmontgom/Lucas.ps.gz .
     510             :  * With thanks to Paul Zimmermann for the reference.  --GN1998Aug13 */
     511             : static int
     512      209741 : get_rule(ulong d, ulong e)
     513             : {
     514      209741 :   if (d <= e + (e>>2)) /* floor(1.25*e) */
     515             :   {
     516       16710 :     if ((d+e)%3 == 0) return 0; /* rule 1 */
     517        9969 :     if ((d-e)%6 == 0) return 1;  /* rule 2 */
     518             :   }
     519             :   /* d <= 4*e but no ofl */
     520      202946 :   if ((d+3)>>2 <= e) return 2; /* rule 3, common case */
     521       12187 :   if ((d&1)==(e&1))  return 1; /* rule 4 = rule 2 */
     522        6348 :   if (!(d&1))        return 3; /* rule 5 */
     523        1770 :   if (d%3 == 0)      return 4; /* rule 6 */
     524         417 :   if ((d+e)%3 == 0)  return 5; /* rule 7 */
     525           0 :   if ((d-e)%3 == 0)  return 6; /* rule 8 */
     526             :   /* when we get here, e is even, otherwise one of rules 4,5 would apply */
     527           0 :   return 7; /* rule 9 */
     528             : }
     529             : 
     530             : /* PRAC implementation notes - main changes against the paper version:
     531             :  * (1) The general function [m+n]P = f([m]P,[n]P,[m-n]P) collapses (for m!=n)
     532             :  * to an ecm_elladd() which does not depend on the third argument; thus
     533             :  * references to the third variable (C in the paper) can be eliminated.
     534             :  * (2) Since our multipliers are prime, the outer loop of the paper
     535             :  * version executes only once, and thus is invisible above.
     536             :  * (3) The first step in the inner loop of the paper version will always be
     537             :  * rule 3, but the addition requested by this rule amounts to a doubling, and
     538             :  * will always be followed by a swap, so we have unrolled this first iteration.
     539             :  * (4) Simplifications in rules 6 and 7 are possible given the above, and we
     540             :  * save one addition in each of the two cases.  NB none of the other
     541             :  * ecm_elladd()s in the loop can ever degenerate into an elldouble.
     542             :  * (5) I tried to optimize for rule 3, which is used more frequently than all
     543             :  * others together, but it didn't improve things, so I removed the nested
     544             :  * tight loop again.  --GN */
     545             : /* The main loop body of ellfacteur() runs _slower_ under PRAC than under a
     546             :  * straightforward left-shift binary multiplication when N has <30 digits and
     547             :  * B1 is small;  PRAC wins when N and B1 get larger.  Weird. --GN */
     548             : /* k>2 assumed prime, XAUX = scratchpad */
     549             : static int
     550       26036 : ellmult(GEN N, GEN *gl, long nbc, ulong k, GEN *X1, GEN *X2, GEN *XAUX)
     551             : {
     552             :   ulong r, d, e, e1;
     553             :   int res;
     554       26036 :   GEN *A = X2, *B = XAUX, *T = XAUX + 2*nbc;
     555             : 
     556       26036 :   ZV_aff(2*nbc,X1,XAUX);
     557             :   /* first doubling picks up X1;  after this we'll be working in XAUX and
     558             :    * X2 only, mostly via A and B and T */
     559       26036 :   if ((res = elldouble(N, gl, nbc, X1, X2)) != 0) return res;
     560             : 
     561             :   /* split the work at the golden ratio */
     562       26036 :   r = (ulong)(k*0.61803398875 + .5);
     563       26036 :   d = k - r;
     564       26036 :   e = r - d; /* d+e == r, so no danger of ofl below */
     565      235756 :   while (d != e)
     566             :   { /* apply one of the nine transformations from PM's Table 4. */
     567      209741 :     switch(get_rule(d,e))
     568             :     {
     569        6741 :     case 0: /* rule 1 */
     570        6741 :       if ( (res = ecm_elladd(N, gl, nbc, A, B, T)) ) return res;
     571        6740 :       if ( (res = ecm_elladd2(N, gl, nbc, T, A, A, T, B, B)) != 0) return res;
     572        6739 :       e1 = d - e; d = (d + e1)/3; e = (e - e1)/3; break;
     573        5893 :     case 1: /* rules 2 and 4 */
     574        5893 :       if ( (res = ecm_elladd(N, gl, nbc, A, B, B)) ) return res;
     575        5891 :       if ( (res = elldouble(N, gl, nbc, A, A)) ) return res;
     576        5891 :       d = (d-e)>>1; break;
     577        4578 :     case 3: /* rule 5 */
     578        4578 :       if ( (res = elldouble(N, gl, nbc, A, A)) ) return res;
     579        4578 :       d >>= 1; break;
     580        1353 :     case 4: /* rule 6 */
     581        1353 :       if ( (res = elldouble(N, gl, nbc, A, T)) ) return res;
     582        1353 :       if ( (res = ecm_elladd(N, gl, nbc, T, A, A)) ) return res;
     583        1353 :       if ( (res = ecm_elladd(N, gl, nbc, A, B, B)) ) return res;
     584        1353 :       d = d/3 - e; break;
     585      190759 :     case 2: /* rule 3 */
     586      190759 :       if ( (res = ecm_elladd(N, gl, nbc, A, B, B)) ) return res;
     587      190742 :       d -= e; break;
     588         417 :     case 5: /* rule 7 */
     589         417 :       if ( (res = elldouble(N, gl, nbc, A, T)) ) return res;
     590         417 :       if ( (res = ecm_elladd2(N, gl, nbc, T, A, A, T, B, B)) != 0) return res;
     591         417 :       d = (d - 2*e)/3; break;
     592           0 :     case 6: /* rule 8 */
     593           0 :       if ( (res = ecm_elladd(N, gl, nbc, A, B, B)) ) return res;
     594           0 :       if ( (res = elldouble(N, gl, nbc, A, T)) ) return res;
     595           0 :       if ( (res = ecm_elladd(N, gl, nbc, T, A, A)) ) return res;
     596           0 :       d = (d - e)/3; break;
     597           0 :     case 7: /* rule 9 */
     598           0 :       if ( (res = elldouble(N, gl, nbc, B, B)) ) return res;
     599           0 :       e >>= 1; break;
     600             :     }
     601             :     /* swap d <-> e and A <-> B if necessary */
     602      209720 :     if (d < e) { lswap(d,e); pswap(A,B); }
     603             :   }
     604       26015 :   return ecm_elladd(N, gl, nbc, XAUX, X2, X2);
     605             : }
     606             : 
     607             : struct ECM {
     608             :   pari_timer T;
     609             :   long nbc, nbc2, seed;
     610             :   GEN *X, *XAUX, *XT, *XD, *XB, *XB2, *XH, *Xh, *Yh;
     611             : };
     612             : 
     613             : /* memory layout in ellfacteur():  a large array of GEN pointers, and one
     614             :  * huge chunk of memory containing all the actual GEN (t_INT) objects.
     615             :  * nbc is constant throughout the invocation:
     616             :  * - The B1 stage of each iteration through the main loop needs little
     617             :  * space:  enough for the X and Y coordinates of the current points,
     618             :  * and twice as much again as scratchpad for ellmult().
     619             :  * - The B2 stage, starting from some current set of points Q, needs, in
     620             :  * succession:
     621             :  *   + space for [2]Q, [4]Q, ..., [10]Q, and [p]Q for building the helix;
     622             :  *   + space for 48*nbc X and Y coordinates to hold the helix.  This could
     623             :  *   re-use [2]Q,...,[8]Q, but only with difficulty, since we don't
     624             :  *   know in advance which residue class mod 210 our p is going to be in.
     625             :  *   It can and should re-use [p]Q, though;
     626             :  *   + space for (temporarily [30]Q and then) [210]Q, [420]Q, and several
     627             :  *   further doublings until the giant step multiplier is reached.  This
     628             :  *   can re-use the remaining cells from above.  The computation of [210]Q
     629             :  *   will have been the last call to ellmult() within this iteration of the
     630             :  *   main loop, so the scratchpad is now also free to be re-used. We also
     631             :  *   compute [630]Q by a parallel addition;  we'll need it later to get the
     632             :  *   baby-step table bootstrapped a little faster.
     633             :  *   + Finally, for no more than 4 curves at a time, room for up to 1024 X
     634             :  *   coordinates only: the Y coordinates needed whilst setting up this baby
     635             :  *   step table are temporarily stored in the upper half, and overwritten
     636             :  *   during the last series of additions.
     637             :  *
     638             :  * Graphically:  after end of B1 stage (X,Y are the coords of Q):
     639             :  * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--
     640             :  * | X Y |  scratch  | [2]Q| [4]Q| [6]Q| [8]Q|[10]Q|    ...    | ...
     641             :  * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--
     642             :  * *X    *XAUX *XT   *XD                                       *XB
     643             :  *
     644             :  * [30]Q is computed from [10]Q.  [210]Q can go into XY, etc:
     645             :  * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--
     646             :  * |[210]|[420]|[630]|[840]|[1680,3360,6720,...,2048*210]      |bstp table...
     647             :  * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--
     648             :  * *X    *XAUX *XT   *XD      [*XG, somewhere here]            *XB .... *XH
     649             :  *
     650             :  * So we need (13 + 48) * 2 * nbc slots here + 4096 slots for the baby step
     651             :  * table (not all of which will be used when we start with a small B1, but
     652             :  * better to allocate and initialize ahead of time all the slots that might
     653             :  * be needed later).
     654             :  *
     655             :  * Note on memory locality:  During the B2 phase, accesses to the helix
     656             :  * (once it is set up) will be clustered by curves (4 out of nbc at a time).
     657             :  * Accesses to the baby steps table will wander from one end of the array to
     658             :  * the other and back, one such cycle per giant step, and during a full cycle
     659             :  * we would expect on the order of 2E4 accesses when using the largest giant
     660             :  * step size.  Thus we shouldn't be doing too bad with respect to thrashing
     661             :  * a 512KBy L2 cache.  However, we don't want the baby step table to grow
     662             :  * larger than this, even if it would reduce the number of EC operations by a
     663             :  * few more per cent for very large B2, lest cache thrashing slow down
     664             :  * everything disproportionally. --GN */
     665             : /* Auxiliary routines need < (3*nbc+240)*lN words on the PARI stack, in
     666             :  * addition to the spc*(lN+1) words occupied by our main table. */
     667             : static void
     668          65 : ECM_alloc(struct ECM *E, long lN)
     669             : {
     670          65 :   const long bstpmax = 1024; /* max number of baby step table entries */
     671          65 :   long spc = (13 + 48) * E->nbc2 + bstpmax * 4;
     672          65 :   long len = spc + 385 + spc*lN;
     673          65 :   long i, tw = _evallg(lN) | evaltyp(t_INT);
     674          65 :   GEN w, *X = (GEN*)new_chunk(len);
     675             :   /* hack for X[i] = cgeti(lN). X = current point in B1 phase */
     676          65 :   w = (GEN)(X + spc + 385);
     677      417585 :   for (i = spc-1; i >= 0; i--) { X[i] = w; *w = tw; w += lN; }
     678          65 :   E->X = X;
     679          65 :   E->XAUX = E->X    + E->nbc2; /* scratchpad for ellmult() */
     680          65 :   E->XT   = E->XAUX + E->nbc2; /* ditto, will later hold [3*210]Q */
     681          65 :   E->XD   = E->XT   + E->nbc2; /* room for various multiples */
     682          65 :   E->XB   = E->XD   + 10*E->nbc2; /* start of baby steps table */
     683          65 :   E->XB2  = E->XB   + 2 * bstpmax; /* middle of baby steps table */
     684          65 :   E->XH   = E->XB2  + 2 * bstpmax; /* end of bstps table, start of helix */
     685          65 :   E->Xh   = E->XH   + 48*E->nbc2; /* little helix, X coords */
     686          65 :   E->Yh   = E->XH   + 192;     /* ditto, Y coords */
     687             :   /* XG,YG set inside the main loop, since they depend on B2 */
     688             :   /* E.Xh range of 384 pointers not set; these will later duplicate the pointers
     689             :    * in the E.XH range, 4 curves at a time. Some of the cells reserved here for
     690             :    * the E.XB range will never be used, instead, we'll warp the pointers to
     691             :    * connect to (read-only) GENs in the X/E.XD range */
     692          65 : }
     693             : /* N.B. E->seed is not initialized here */
     694             : static void
     695          65 : ECM_init(struct ECM *E, GEN N, long nbc)
     696             : {
     697          65 :   if (nbc < 0)
     698             :   { /* choose a sensible default */
     699          57 :     const long size = expi(N) + 1;
     700          57 :     nbc = ((size >> 3) << 2) - 80;
     701          57 :     if (nbc < 8) nbc = 8;
     702             :   }
     703          65 :   if (nbc > nbcmax) nbc = nbcmax;
     704          65 :   E->nbc = nbc;
     705          65 :   E->nbc2 = nbc << 1;
     706          65 :   ECM_alloc(E, lgefint(N));
     707          65 : }
     708             : 
     709             : static GEN
     710         102 : ECM_loop(struct ECM *E, GEN N, ulong B1)
     711             : {
     712         102 :   const ulong B2 = 110 * B1, B2_rt = usqrt(B2);
     713         102 :   const ulong nbc = E->nbc, nbc2 = E->nbc2;
     714             :   pari_sp av1, avtmp;
     715             :   long i, np, np0, gse, gss, bstp, bstp0, rcn0, rcn;
     716             :   ulong B2_p, m, p, p0;
     717             :   GEN g, *XG, *YG;
     718         102 :   GEN *X = E->X, *XAUX = E->XAUX, *XT = E->XT, *XD = E->XD;
     719         102 :   GEN *XB = E->XB, *XB2 = E->XB2, *XH = E->XH, *Xh = E->Xh, *Yh = E->Yh;
     720             :   /* pick curves */
     721        4614 :   for (i = nbc2; i--; ) affui(E->seed++, X[i]);
     722             :   /* pick giant step exponent and size */
     723         102 :   gse = B1 < 656
     724             :           ? (B1 < 200? 5: 6)
     725         102 :           : (B1 < 10500
     726             :             ? (B1 < 2625? 7: 8)
     727             :             : (B1 < 42000? 9: 10));
     728         102 :   gss = 1UL << gse;
     729             :   /* With 32 baby steps, a giant step corresponds to 32*420 = 13440,
     730             :    * appropriate for the smallest B2s. With 1024, a giant step will be 430080;
     731             :    * appropriate for B1 >~ 42000, where 512 baby steps would imply roughly
     732             :    * the same number of curve additions. */
     733         102 :   XG = XT + gse*nbc2; /* will later hold [2^(gse+1)*210]Q */
     734         102 :   YG = XG + nbc;
     735             : 
     736         102 :   if (DEBUGLEVEL >= 4) {
     737           0 :     err_printf("ECM: time = %6ld ms\nECM: B1 = %4lu,", timer_delay(&E->T), B1);
     738           0 :     err_printf("\tB2 = %6lu,\tgss = %4ld*420\n", B2, gss);
     739             :   }
     740         102 :   p = 2; np = 1; /* p is np-th prime */
     741             : 
     742             :   /* ---B1 PHASE--- */
     743             :   /* treat p=2 separately */
     744         102 :   B2_p = B2 >> 1;
     745        1736 :   for (m=1; m<=B2_p; m<<=1)
     746             :   {
     747        1634 :     int fl = elldouble(N, &g, nbc, X, X);
     748        1634 :     if (fl > 1) return g; else if (fl) break;
     749             :   }
     750         102 :   rcn = NPRC; /* multipliers begin at the beginning */
     751             :   /* p=3,...,nextprime(B1) */
     752        6662 :   while (p < B1 && p <= B2_rt)
     753             :   {
     754        6568 :     pari_sp av2 = avma;
     755        6568 :     p = snextpr(p, &np, &rcn, NULL, uisprime);
     756        6568 :     B2_p = B2/p; /* beware integer overflow on 32-bit CPUs */
     757       22497 :     for (m=1; m<=B2_p; m*=p)
     758             :     {
     759       15955 :       int fl = ellmult(N, &g, nbc, p, X, X, XAUX);
     760       15955 :       if (fl > 1) return g; else if (fl) break;
     761       15929 :       set_avma(av2);
     762             :     }
     763        6560 :     set_avma(av2);
     764             :   }
     765             :   /* primes p larger than sqrt(B2) appear only to the 1st power */
     766        9929 :   while (p < B1)
     767             :   {
     768        9853 :     pari_sp av2 = avma;
     769        9853 :     p = snextpr(p, &np, &rcn, NULL, uisprime);
     770        9853 :     if (ellmult(N, &g, nbc, p, X, X, XAUX) > 1) return g;
     771        9835 :     set_avma(av2);
     772             :   }
     773          76 :   if (DEBUGLEVEL >= 4) {
     774           0 :     err_printf("ECM: time = %6ld ms, B1 phase done, ", timer_delay(&E->T));
     775           0 :     err_printf("p = %lu, setting up for B2\n", p);
     776             :   }
     777             : 
     778             :   /* ---B2 PHASE--- */
     779             :   /* compute [2]Q,...,[10]Q, needed to build the helix */
     780          76 :   if (elldouble(N, &g, nbc, X, XD) > 1) return g; /*[2]Q*/
     781          76 :   if (elldouble(N, &g, nbc, XD, XD + nbc2) > 1) return g; /*[4]Q*/
     782          76 :   if (ecm_elladd(N, &g, nbc,
     783          76 :         XD, XD + nbc2, XD + (nbc<<2)) > 1) return g; /* [6]Q */
     784          76 :   if (ecm_elladd2(N, &g, nbc,
     785             :         XD, XD + (nbc<<2), XT + (nbc<<3),
     786          76 :         XD + nbc2, XD + (nbc<<2), XD + (nbc<<3)) > 1)
     787           0 :     return g; /* [8]Q and [10]Q */
     788          76 :   if (DEBUGLEVEL >= 7) err_printf("\t(got [2]Q...[10]Q)\n");
     789             : 
     790             :   /* get next prime (still using the foolproof test) */
     791          76 :   p = snextpr(p, &np, &rcn, NULL, uisprime);
     792             :   /* make sure we have the residue class number (mod 210) */
     793          76 :   if (rcn == NPRC)
     794             :   {
     795          76 :     rcn = prc210_no[(p % 210) >> 1];
     796          76 :     if (rcn == NPRC)
     797             :     {
     798           0 :       err_printf("ECM: %lu should have been prime but isn\'t\n", p);
     799           0 :       pari_err_BUG("ellfacteur");
     800             :     }
     801             :   }
     802             : 
     803             :   /* compute [p]Q and put it into its place in the helix */
     804          76 :   if (ellmult(N, &g, nbc, p, X, XH + rcn*nbc2, XAUX) > 1)
     805           0 :     return g;
     806          76 :   if (DEBUGLEVEL >= 7)
     807           0 :     err_printf("\t(got [p]Q, p = %lu = prc210_rp[%ld] mod 210)\n", p, rcn);
     808             : 
     809             :   /* save current p, np, and rcn;  we'll need them more than once below */
     810          76 :   p0 = p; np0 = np; rcn0 = rcn;
     811          76 :   bstp0 = 0; /* p is at baby-step offset 0 from itself */
     812             : 
     813             :   /* fill up the helix, stepping forward through the prime residue classes
     814             :    * mod 210 until we're back at the r'class of p0.  Keep updating p so
     815             :    * that we can print meaningful diagnostics if a factor shows up; don't
     816             :    * bother checking which of these p's are in fact prime */
     817        3648 :   for (i = 47; i; i--) /* 47 iterations */
     818             :   {
     819        3572 :     ulong dp = (ulong)prc210_d1[rcn];
     820        3572 :     p += dp;
     821        3572 :     if (rcn == 47)
     822             :     { /* wrap mod 210 */
     823          76 :       if (ecm_elladd(N, &g, nbc, XT+dp*nbc, XH+rcn*nbc2, XH) > 1) return g;
     824          76 :       rcn = 0; continue;
     825             :     }
     826        3496 :     if (ecm_elladd(N, &g, nbc, XT+dp*nbc, XH+rcn*nbc2, XH+rcn*nbc2+nbc2) > 1)
     827           0 :       return g;
     828        3496 :     rcn++;
     829             :   }
     830          76 :   if (DEBUGLEVEL >= 7) err_printf("\t(got initial helix)\n");
     831             :   /* compute [210]Q etc, needed for the baby step table */
     832          76 :   if (ellmult(N, &g, nbc, 3, XD + (nbc<<3), X, XAUX) > 1) return g;
     833          76 :   if (ellmult(N, &g, nbc, 7, X, X, XAUX) > 1) return g; /* [210]Q */
     834             :   /* this was the last call to ellmult() in the main loop body; may now
     835             :    * overwrite XAUX and slots XD and following */
     836          76 :   if (elldouble(N, &g, nbc, X, XAUX) > 1) return g; /* [420]Q */
     837          76 :   if (ecm_elladd(N, &g, nbc, X, XAUX, XT) > 1) return g;/*[630]Q*/
     838          76 :   if (ecm_elladd(N, &g, nbc, X, XT, XD) > 1) return g;  /*[840]Q*/
     839         567 :   for (i=1; i <= gse; i++)
     840         491 :     if (elldouble(N, &g, nbc, XT + i*nbc2, XD + i*nbc2) > 1) return g;
     841             :   /* (the last iteration has initialized XG to [210*2^(gse+1)]Q) */
     842             : 
     843          76 :   if (DEBUGLEVEL >= 4)
     844           0 :     err_printf("ECM: time = %6ld ms, entering B2 phase, p = %lu\n",
     845             :                timer_delay(&E->T), p);
     846             : 
     847         394 :   for (i = nbc - 4; i >= 0; i -= 4)
     848             :   { /* loop over small sets of 4 curves at a time */
     849             :     GEN *Xb;
     850             :     long j, k;
     851         325 :     if (DEBUGLEVEL >= 6)
     852           0 :       err_printf("ECM: finishing curves %ld...%ld\n", i, i+3);
     853             :     /* Copy relevant pointers from XH to Xh. Memory layout in XH:
     854             :      * nbc X coordinates, nbc Y coordinates for residue class
     855             :      * 1 mod 210, then the same for r.c. 11 mod 210, etc. Memory layout for
     856             :      * Xh is: four X coords for 1 mod 210, four for 11 mod 210, ..., four
     857             :      * for 209 mod 210, then the corresponding Y coordinates in the same
     858             :      * order. This allows a giant step on Xh using just three calls to
     859             :      * ecm_elladd0() each acting on 64 points in parallel */
     860       15925 :     for (j = 48; j--; )
     861             :     {
     862       15600 :       k = nbc2*j + i;
     863       15600 :       m = j << 2; /* X coordinates */
     864       15600 :       Xh[m]   = XH[k];   Xh[m+1] = XH[k+1];
     865       15600 :       Xh[m+2] = XH[k+2]; Xh[m+3] = XH[k+3];
     866       15600 :       k += nbc; /* Y coordinates */
     867       15600 :       Yh[m]   = XH[k];   Yh[m+1] = XH[k+1];
     868       15600 :       Yh[m+2] = XH[k+2]; Yh[m+3] = XH[k+3];
     869             :     }
     870             :     /* Build baby step table of X coords of multiples of [210]Q.  XB[4*j]
     871             :      * will point at X coords on four curves from [(j+1)*210]Q.  Until
     872             :      * we're done, we need some Y coords as well, which we keep in the
     873             :      * second half of the table, overwriting them at the end when gse=10.
     874             :      * Multiples which we already have  (by 1,2,3,4,8,16,...,2^gse) are
     875             :      * entered simply by copying the pointers, ignoring the few slots in w
     876             :      * that were initially reserved for them. Here are the initial entries */
     877         975 :     for (Xb=XB,k=2,j=i; k--; Xb=XB2,j+=nbc) /* first X, then Y coords */
     878             :     {
     879         650 :       Xb[0]  = X[j];      Xb[1]  = X[j+1]; /* [210]Q */
     880         650 :       Xb[2]  = X[j+2];    Xb[3]  = X[j+3];
     881         650 :       Xb[4]  = XAUX[j];   Xb[5]  = XAUX[j+1]; /* [420]Q */
     882         650 :       Xb[6]  = XAUX[j+2]; Xb[7]  = XAUX[j+3];
     883         650 :       Xb[8]  = XT[j];     Xb[9]  = XT[j+1]; /* [630]Q */
     884         650 :       Xb[10] = XT[j+2];   Xb[11] = XT[j+3];
     885         650 :       Xb += 4; /* points at [420]Q */
     886             :       /* ... entries at powers of 2 times 210 .... */
     887        4075 :       for (m = 2; m < (ulong)gse+k; m++) /* omit Y coords of [2^gse*210]Q */
     888             :       {
     889        3425 :         long m2 = m*nbc2 + j;
     890        3425 :         Xb += (2UL<<m); /* points at [2^m*210]Q */
     891        3425 :         Xb[0] = XAUX[m2];   Xb[1] = XAUX[m2+1];
     892        3425 :         Xb[2] = XAUX[m2+2]; Xb[3] = XAUX[m2+3];
     893             :       }
     894             :     }
     895         325 :     if (DEBUGLEVEL >= 7)
     896           0 :       err_printf("\t(extracted precomputed helix / baby step entries)\n");
     897             :     /* ... glue in between, up to 16*210 ... */
     898         325 :     if (ecm_elladd0(N, &g, 12, 4, /* 12 pts + (4 pts replicated thrice) */
     899             :           XB + 12, XB2 + 12,
     900             :           XB,      XB2,
     901           0 :           XB + 16, XB2 + 16) > 1) return g; /*4+{1,2,3} = {5,6,7}*/
     902         325 :     if (ecm_elladd0(N, &g, 28, 4, /* 28 pts + (4 pts replicated 7fold) */
     903             :           XB + 28, XB2 + 28,
     904             :           XB,      XB2,
     905           0 :           XB + 32, XB2 + 32) > 1) return g;/*8+{1...7} = {9...15}*/
     906             :     /* ... and the remainder of the lot */
     907        1225 :     for (m = 5; m <= (ulong)gse; m++)
     908             :     { /* fill in from 2^(m-1)+1 to 2^m-1 in chunks of 64 and 60 points */
     909         900 :       ulong m2 = 2UL << m; /* will point at 2^(m-1)+1 */
     910        1979 :       for (j = 0; (ulong)j < m2-64; j+=64) /* executed 0 times when m = 5 */
     911             :       {
     912        1906 :         if (ecm_elladd0(N, &g, 64, 4,
     913        1079 :               XB + m2-4, XB2 + m2-4,
     914        1079 :               XB + j,    XB2 + j,
     915        1906 :               XB + m2+j, (m<(ulong)gse? XB2+m2+j: NULL)) > 1)
     916           0 :           return g;
     917             :       } /* j = m2-64 here, 60 points left */
     918        1225 :       if (ecm_elladd0(N, &g, 60, 4,
     919         900 :             XB + m2-4, XB2 + m2-4,
     920         900 :             XB + j,    XB2 + j,
     921        1225 :             XB + m2+j, (m<(ulong)gse? XB2+m2+j: NULL)) > 1)
     922           0 :         return g;
     923             :       /* when m=gse, drop Y coords of result, and when both equal 1024,
     924             :        * overwrite Y coords of second argument with X coords of result */
     925             :     }
     926         325 :     if (DEBUGLEVEL >= 7) err_printf("\t(baby step table complete)\n");
     927             :     /* initialize a few other things */
     928         325 :     bstp = bstp0; p = p0; np = np0; rcn = rcn0;
     929         325 :     g = gen_1; av1 = avma;
     930             :     /* scratchspace for prod (x_i-x_j) */
     931         325 :     avtmp = (pari_sp)new_chunk(8 * lgefint(N));
     932             :     /* The correct entry in XB to use depends on bstp and on where we are
     933             :      * on the helix. As we skip from prime to prime, bstp is incremented
     934             :      * by snextpr each time we wrap around through residue class number 0
     935             :      * (1 mod 210), but the baby step should not be taken until rcn>=rcn0,
     936             :      * i.e. until we pass again the residue class of p0.
     937             :      *
     938             :      * The correct signed multiplier is thus k = bstp - (rcn < rcn0),
     939             :      * and the offset from XB is four times (|k| - 1).  When k=0, we ignore
     940             :      * the current prime: if it had led to a factorization, this
     941             :      * would have been noted during the last giant step, or -- when we
     942             :      * first get here -- whilst initializing the helix.  When k > gss,
     943             :      * we must do a giant step and bump bstp back by -2*gss.
     944             :      *
     945             :      * The gcd of the product of X coord differences against N is taken just
     946             :      * before we do a giant step. */
     947     4518838 :     while (p < B2)
     948             :     {/* loop over probable primes p0 < p <= nextprime(B2), inserting giant
     949             :       * steps as necessary */
     950     4518520 :       p = snextpr(p, &np, &rcn, &bstp, uis2psp); /* next probable prime */
     951             :       /* work out the corresponding baby-step multiplier */
     952     4518520 :       k = bstp - (rcn < rcn0 ? 1 : 0);
     953     4518520 :       if (k > gss)
     954             :       { /* giant-step time, take gcd */
     955        1116 :         g = gcdii(g, N);
     956        1116 :         if (!is_pm1(g) && !equalii(g, N)) return g;
     957        1109 :         g = gen_1; set_avma(av1);
     958        2218 :         while (k > gss)
     959             :         { /* giant step */
     960        1109 :           if (DEBUGLEVEL >= 7) err_printf("\t(giant step at p = %lu)\n", p);
     961        1109 :           if (ecm_elladd0(N, &g, 64, 4, XG + i, YG + i,
     962           0 :                 Xh, Yh, Xh, Yh) > 1) return g;
     963        1109 :           if (ecm_elladd0(N, &g, 64, 4, XG + i, YG + i,
     964             :                 Xh + 64, Yh + 64, Xh + 64, Yh + 64) > 1)
     965           0 :             return g;
     966        1109 :           if (ecm_elladd0(N, &g, 64, 4, XG + i, YG + i,
     967             :                 Xh + 128, Yh + 128, Xh + 128, Yh + 128) > 1)
     968           0 :             return g;
     969        1109 :           bstp -= (gss << 1);
     970        1109 :           k = bstp - (rcn < rcn0? 1: 0); /* recompute multiplier */
     971             :         }
     972             :       }
     973     4518513 :       if (!k) continue; /* point of interest is already in Xh */
     974     4493724 :       if (k < 0) k = -k;
     975     4493724 :       m = ((ulong)k - 1) << 2;
     976             :       /* accumulate product of differences of X coordinates */
     977     4493724 :       j = rcn<<2;
     978     4493724 :       avma = avtmp; /* go to garbage zone; don't use set_avma */
     979     4493724 :       g = modii(mulii(g, subii(XB[m],   Xh[j])), N);
     980     4493724 :       g = modii(mulii(g, subii(XB[m+1], Xh[j+1])), N);
     981     4493724 :       g = modii(mulii(g, subii(XB[m+2], Xh[j+2])), N);
     982     4493724 :       g = mulii(g, subii(XB[m+3], Xh[j+3]));
     983     4493724 :       set_avma(av1);
     984     4493724 :       g = modii(g, N);
     985             :     }
     986         318 :     set_avma(av1);
     987             :   }
     988          69 :   return NULL;
     989             : }
     990             : 
     991             : /* ellfacteur() tuned to be useful as a first stage before MPQS, especially for
     992             :  * large arguments, when 'insist' is false, and now also for the case when
     993             :  * 'insist' is true, vaguely following suggestions by Paul Zimmermann
     994             :  * (http://www.loria.fr/~zimmerma/records/ecmnet.html). --GN 1998Jul,Aug */
     995             : static GEN
     996        3281 : ellfacteur(GEN N, int insist)
     997             : {
     998        3281 :   const long size = expi(N) + 1;
     999        3281 :   pari_sp av = avma;
    1000             :   struct ECM E;
    1001        3281 :   long nbc, dsn, dsnmax, rep = 0;
    1002        3281 :   if (insist)
    1003             :   {
    1004           8 :     const long DSNMAX = numberof(TB1)-1;
    1005           8 :     dsnmax = (size >> 2) - 10;
    1006           8 :     if (dsnmax < 0) dsnmax = 0;
    1007           7 :     else if (dsnmax > DSNMAX) dsnmax = DSNMAX;
    1008           8 :     E.seed = 1 + (nbcmax<<7)*(size&0xffff); /* seed for choice of curves */
    1009             : 
    1010           8 :     dsn = (size >> 3) - 5;
    1011           8 :     if (dsn < 0) dsn = 0; else if (dsn > 47) dsn = 47;
    1012             :     /* pick up the torch where noninsistent stage would have given up */
    1013           8 :     nbc = dsn + (dsn >> 2) + 9; /* 8 or more curves in parallel */
    1014           8 :     nbc &= ~3; /* 4 | nbc */
    1015             :   }
    1016             :   else
    1017             :   {
    1018        3273 :     dsn = (size - 140) >> 3;
    1019        3273 :     if (dsn < 0)
    1020             :     {
    1021             : #ifndef __EMX__ /* unless DOS/EMX: MPQS's disk access is abysmally slow */
    1022        3216 :       if (DEBUGLEVEL >= 4)
    1023           0 :         err_printf("ECM: number too small to justify this stage\n");
    1024        3216 :       return NULL; /* too small, decline the task */
    1025             : #endif
    1026             :       dsn = 0;
    1027          57 :     } else if (dsn > 12) dsn = 12;
    1028          57 :     rep = (size <= 248 ?
    1029          57 :            (size <= 176 ? (size - 124) >> 4 : (size - 148) >> 3) :
    1030          18 :            (size - 224) >> 1);
    1031             : #ifdef __EMX__ /* DOS/EMX: extra rounds (shun MPQS) */
    1032             :     rep += 20;
    1033             : #endif
    1034          57 :     dsnmax = 72;
    1035             :     /* Use disjoint sets of curves for non-insist and insist phases; moreover,
    1036             :      * repeated calls acting on factors of the same original number should try
    1037             :      * to use fresh curves. The following achieves this */
    1038          57 :     E.seed = 1 + (nbcmax<<3)*(size & 0xf);
    1039          57 :     nbc = -1;
    1040             :   }
    1041          65 :   ECM_init(&E, N, nbc);
    1042          65 :   if (DEBUGLEVEL >= 4)
    1043             :   {
    1044           0 :     timer_start(&E.T);
    1045           0 :     err_printf("ECM: working on %ld curves at a time; initializing", E.nbc);
    1046           0 :     if (!insist)
    1047             :     {
    1048           0 :       if (rep == 1) err_printf(" for one round");
    1049           0 :       else          err_printf(" for up to %ld rounds", rep);
    1050             :     }
    1051           0 :     err_printf("...\n");
    1052             :   }
    1053          65 :   if (dsn > dsnmax) dsn = dsnmax;
    1054             :   for(;;)
    1055          37 :   {
    1056         102 :     ulong B1 = insist? TB1[dsn]: TB1_for_stage[dsn];
    1057         102 :     GEN g = ECM_loop(&E, N, B1);
    1058         102 :     if (g)
    1059             :     {
    1060          33 :       if (DEBUGLEVEL >= 4)
    1061           0 :         err_printf("ECM: time = %6ld ms\n\tfound factor = %Ps\n",
    1062             :                    timer_delay(&E.T), g);
    1063          33 :       return gerepilecopy(av, g);
    1064             :     }
    1065          69 :     if (dsn < dsnmax)
    1066             :     {
    1067          68 :       if (insist) dsn++;
    1068          68 :       else { dsn += 2; if (dsn > dsnmax) dsn = dsnmax; }
    1069             :     }
    1070          69 :     if (!insist && !--rep)
    1071             :     {
    1072          32 :       if (DEBUGLEVEL >= 4)
    1073           0 :         err_printf("ECM: time = %6ld ms,\tellfacteur giving up.\n",
    1074             :                    timer_delay(&E.T));
    1075          32 :       return gc_NULL(av);
    1076             :     }
    1077             :   }
    1078             : }
    1079             : /* assume rounds >= 1, seed >= 1, B1 <= ULONG_MAX / 110 */
    1080             : GEN
    1081           0 : Z_ECM(GEN N, long rounds, long seed, ulong B1)
    1082             : {
    1083           0 :   pari_sp av = avma;
    1084             :   struct ECM E;
    1085             :   long i;
    1086           0 :   E.seed = seed;
    1087           0 :   ECM_init(&E, N, -1);
    1088           0 :   if (DEBUGLEVEL >= 4) timer_start(&E.T);
    1089           0 :   for (i = rounds; i--; )
    1090             :   {
    1091           0 :     GEN g = ECM_loop(&E, N, B1);
    1092           0 :     if (g) return gerepilecopy(av, g);
    1093             :   }
    1094           0 :   return gc_NULL(av);
    1095             : }
    1096             : 
    1097             : /***********************************************************************/
    1098             : /**                                                                   **/
    1099             : /**                FACTORIZATION (Pollard-Brent rho) --GN1998Jun18-26 **/
    1100             : /**  pollardbrent() returns a nontrivial factor of n, assuming n is   **/
    1101             : /**  composite and has no small prime divisor, or NULL if going on    **/
    1102             : /**  would take more time than we want to spend.  Sometimes it finds  **/
    1103             : /**  more than one factor, and returns a structure suitable for       **/
    1104             : /**  interpretation by ifac_crack. (Cf Algo 8.5.2 in ACiCNT)          **/
    1105             : /**                                                                   **/
    1106             : /***********************************************************************/
    1107             : #define VALUE(x) gel(x,0)
    1108             : #define EXPON(x) gel(x,1)
    1109             : #define CLASS(x) gel(x,2)
    1110             : 
    1111             : INLINE void
    1112       53786 : INIT(GEN x, GEN v, GEN e, GEN c) {
    1113       53786 :   VALUE(x) = v;
    1114       53786 :   EXPON(x) = e;
    1115       53786 :   CLASS(x) = c;
    1116       53786 : }
    1117             : static void
    1118       47566 : ifac_delete(GEN x) { INIT(x,NULL,NULL,NULL); }
    1119             : 
    1120             : static void
    1121           0 : rho_dbg(pari_timer *T, long c, long msg_mask)
    1122             : {
    1123           0 :   if (c & msg_mask) return;
    1124           0 :   err_printf("Rho: time = %6ld ms,\t%3ld round%s\n",
    1125             :              timer_delay(T), c, (c==1?"":"s"));
    1126             : }
    1127             : 
    1128             : static void
    1129    27694349 : one_iter(GEN *x, GEN *P, GEN x1, GEN n, long delta)
    1130             : {
    1131    27694349 :   *x = addis(remii(sqri(*x), n), delta);
    1132    27645476 :   *P = modii(mulii(*P, subii(x1, *x)), n);
    1133    27696840 : }
    1134             : /* Return NULL when we run out of time, or a single t_INT containing a
    1135             :  * nontrivial factor of n, or a vector of t_INTs, each triple of successive
    1136             :  * entries containing a factor, an exponent (equal to one),  and a factor
    1137             :  * class (NULL for unknown or zero for known composite),  matching the
    1138             :  * internal representation used by the ifac_*() routines below. Repeated
    1139             :  * factors may arise; the caller will sort the factors anyway. Result
    1140             :  * is not gerepile-able (contains NULL) */
    1141             : static GEN
    1142         439 : pollardbrent_i(GEN n, long size, long c0, long retries)
    1143             : {
    1144         439 :   long tf = lgefint(n), delta, msg_mask, c, k, k1, l;
    1145             :   pari_sp av;
    1146             :   GEN x, x1, y, P, g, g1, res;
    1147             :   pari_timer T;
    1148             : 
    1149         439 :   if (DEBUGLEVEL >= 4) timer_start(&T);
    1150         439 :   c = c0 << 5; /* 2^5 iterations per round */
    1151         878 :   msg_mask = (size >= 448? 0x1fff:
    1152         439 :                            (size >= 192? (256L<<((size-128)>>6))-1: 0xff));
    1153         439 :   y = cgeti(tf);
    1154         439 :   x1= cgeti(tf);
    1155         439 :   av = avma;
    1156             : 
    1157         439 : PB_RETRY:
    1158             :  /* trick to make a 'random' choice determined by n.  Don't use x^2+0 or
    1159             :   * x^2-2, ever.  Don't use x^2-3 or x^2-7 with a starting value of 2.
    1160             :   * x^2+4, x^2+9 are affine conjugate to x^2+1, so don't use them either.
    1161             :   *
    1162             :   * (the point being that when we get called again on a composite cofactor
    1163             :   * of something we've already seen, we had better avoid the same delta) */
    1164         439 :   switch ((size + retries) & 7)
    1165             :   {
    1166           7 :     case 0:  delta=  1; break;
    1167          99 :     case 1:  delta= -1; break;
    1168         109 :     case 2:  delta=  3; break;
    1169          49 :     case 3:  delta=  5; break;
    1170          98 :     case 4:  delta= -5; break;
    1171          28 :     case 5:  delta=  7; break;
    1172          21 :     case 6:  delta= 11; break;
    1173             :     /* case 7: */
    1174          28 :     default: delta=-11; break;
    1175             :   }
    1176         439 :   if (DEBUGLEVEL >= 4)
    1177             :   {
    1178           0 :     if (!retries)
    1179           0 :       err_printf("Rho: searching small factor of %ld-bit integer\n", size);
    1180             :     else
    1181           0 :       err_printf("Rho: restarting for remaining rounds...\n");
    1182           0 :     err_printf("Rho: using X^2%+1ld for up to %ld rounds of 32 iterations\n",
    1183             :                delta, c >> 5);
    1184             :   }
    1185         439 :   x = gen_2; P = gen_1; g1 = NULL; k = 1; l = 1;
    1186         439 :   affui(2, y);
    1187         439 :   affui(2, x1);
    1188             :   for (;;) /* terminated under the control of c */
    1189             :   { /* use the polynomial  x^2 + delta */
    1190    12961484 :     one_iter(&x, &P, x1, n, delta);
    1191             : 
    1192    12962846 :     if ((--c & 0x1f)==0)
    1193             :     { /* one round complete */
    1194      405405 :       g = gcdii(n, P); if (!is_pm1(g)) goto fin;
    1195      405176 :       if (c <= 0)
    1196             :       { /* getting bored */
    1197          88 :         if (DEBUGLEVEL >= 4)
    1198           0 :           err_printf("Rho: time = %6ld ms,\tPollard-Brent giving up.\n",
    1199             :                      timer_delay(&T));
    1200          88 :         return NULL;
    1201             :       }
    1202      405088 :       P = gen_1;
    1203      405088 :       if (DEBUGLEVEL >= 4) rho_dbg(&T, c0-(c>>5), msg_mask);
    1204      405088 :       affii(x,y); x = y; set_avma(av);
    1205             :     }
    1206             : 
    1207    12961253 :     if (--k) continue; /* normal end of loop body */
    1208             : 
    1209        4837 :     if (c & 0x1f) /* otherwise, we already checked */
    1210             :     {
    1211        2620 :       g = gcdii(n, P); if (!is_pm1(g)) goto fin;
    1212        2557 :       P = gen_1;
    1213             :     }
    1214             : 
    1215             :    /* Fast forward phase, doing l inner iterations without computing gcds.
    1216             :     * Check first whether it would take us beyond the alloted time.
    1217             :     * Fast forward rounds count only half (although they're taking
    1218             :     * more like 2/3 the time of normal rounds).  This to counteract the
    1219             :     * nuisance that all c0 between 4096 and 6144 would act exactly as
    1220             :     * 4096;  with the halving trick only the range 4096..5120 collapses
    1221             :     * (similarly for all other powers of two) */
    1222        4774 :     if ((c -= (l>>1)) <= 0)
    1223             :     { /* got bored */
    1224          67 :       if (DEBUGLEVEL >= 4)
    1225           0 :         err_printf("Rho: time = %6ld ms,\tPollard-Brent giving up.\n",
    1226             :                    timer_delay(&T));
    1227          67 :       return NULL;
    1228             :     }
    1229        4707 :     c &= ~0x1f; /* keep it on multiples of 32 */
    1230             : 
    1231             :     /* Fast forward loop */
    1232        4707 :     affii(x, x1); set_avma(av); x = x1;
    1233        4707 :     k = l; l <<= 1;
    1234             :     /* don't show this for the first several (short) fast forward phases. */
    1235        4707 :     if (DEBUGLEVEL >= 4 && (l>>7) > msg_mask)
    1236           0 :       err_printf("Rho: fast forward phase (%ld rounds of 64)...\n", l>>7);
    1237    14763852 :     for (k1=k; k1; k1--)
    1238             :     {
    1239    14759197 :       one_iter(&x, &P, x1, n, delta);
    1240    14757920 :       if ((k1 & 0x1f) == 0) gerepileall(av, 2, &x, &P);
    1241             :     }
    1242        4655 :     if (DEBUGLEVEL >= 4 && (l>>7) > msg_mask)
    1243           0 :       err_printf("Rho: time = %6ld ms,\t%3ld rounds, back to normal mode\n",
    1244           0 :                  timer_delay(&T), c0-(c>>5));
    1245        4655 :     affii(x,y); P = gerepileuptoint(av, P); x = y;
    1246             :   } /* forever */
    1247             : 
    1248         284 : fin:
    1249             :   /* An accumulated gcd was > 1 */
    1250         284 :   if  (!equalii(g,n))
    1251             :   { /* if it isn't n, and looks prime, return it */
    1252         256 :     if (MR_Jaeschke(g))
    1253             :     {
    1254         256 :       if (DEBUGLEVEL >= 4)
    1255             :       {
    1256           0 :         rho_dbg(&T, c0-(c>>5), 0);
    1257           0 :         err_printf("\tfound factor = %Ps\n",g);
    1258             :       }
    1259         256 :       return g;
    1260             :     }
    1261           0 :     set_avma(av); g1 = icopy(g);  /* known composite, keep it safe */
    1262           0 :     av = avma;
    1263             :   }
    1264          28 :   else g1 = n; /* and work modulo g1 for backtracking */
    1265             : 
    1266             :   /* Here g1 is known composite */
    1267          28 :   if (DEBUGLEVEL >= 4 && size > 192)
    1268           0 :     err_printf("Rho: hang on a second, we got something here...\n");
    1269          28 :   x = y;
    1270             :   for(;;)
    1271             :   { /* backtrack until period recovered. Must terminate */
    1272         252 :     x = addis(remii(sqri(x), g1), delta);
    1273         252 :     g = gcdii(subii(x1, x), g1); if (!is_pm1(g)) break;
    1274             : 
    1275         224 :     if (DEBUGLEVEL >= 4 && (--c & 0x1f) == 0) rho_dbg(&T, c0-(c>>5), msg_mask);
    1276             :   }
    1277             : 
    1278          28 :   if (g1 == n || equalii(g,g1))
    1279             :   {
    1280          28 :     if (g1 == n && equalii(g,g1))
    1281             :     { /* out of luck */
    1282           0 :       if (DEBUGLEVEL >= 4)
    1283             :       {
    1284           0 :         rho_dbg(&T, c0-(c>>5), 0);
    1285           0 :         err_printf("\tPollard-Brent failed.\n");
    1286             :       }
    1287           0 :       if (++retries >= 4) pari_err_BUG("");
    1288           0 :       goto PB_RETRY;
    1289             :     }
    1290             :     /* half lucky: we've split n, but g1 equals either g or n */
    1291          28 :     if (DEBUGLEVEL >= 4)
    1292             :     {
    1293           0 :       rho_dbg(&T, c0-(c>>5), 0);
    1294           0 :       err_printf("\tfound %sfactor = %Ps\n", (g1!=n ? "composite " : ""), g);
    1295             :     }
    1296          28 :     res = cgetg(7, t_VEC);
    1297             :     /* g^1: known composite when g1!=n */
    1298          28 :     INIT(res+1, g, gen_1, (g1!=n? gen_0: NULL));
    1299             :     /* cofactor^1: status unknown */
    1300          28 :     INIT(res+4, diviiexact(n,g), gen_1, NULL);
    1301          28 :     return res;
    1302             :   }
    1303             :   /* g < g1 < n : our lucky day -- we've split g1, too */
    1304           0 :   res = cgetg(10, t_VEC);
    1305             :   /* unknown status for all three factors */
    1306           0 :   INIT(res+1, g,                gen_1, NULL);
    1307           0 :   INIT(res+4, diviiexact(g1,g), gen_1, NULL);
    1308           0 :   INIT(res+7, diviiexact(n,g1), gen_1, NULL);
    1309           0 :   if (DEBUGLEVEL >= 4)
    1310             :   {
    1311           0 :     rho_dbg(&T, c0-(c>>5), 0);
    1312           0 :     err_printf("\tfound factors = %Ps, %Ps,\n\tand %Ps\n",
    1313           0 :                gel(res,1), gel(res,4), gel(res,7));
    1314             :   }
    1315           0 :   return res;
    1316             : }
    1317             : /* Tuning parameter:  for input up to 64 bits long, we must not spend more
    1318             :  * than a very short time, for fear of slowing things down on average.
    1319             :  * With the current tuning formula, increase our efforts somewhat at 49 bit
    1320             :  * input (an extra round for each bit at first),  and go up more and more
    1321             :  * rapidly after we pass 80 bits.-- Changed this to adjust for the presence of
    1322             :  * squfof, which will finish input up to 59 bits quickly. */
    1323             : static GEN
    1324        5258 : pollardbrent(GEN n)
    1325             : {
    1326        5258 :   const long tune_pb_min = 14; /* even 15 seems too much. */
    1327        5258 :   long c0, size = expi(n) + 1;
    1328        5258 :   if (size <= 28)
    1329         154 :     c0 = 32;/* amounts very nearly to 'insist'. Now that we have squfof(), we
    1330             :              * don't insist any more when input is 2^29 ... 2^32 */
    1331        5104 :   else if (size <= 96)
    1332        4819 :     return NULL;
    1333         285 :   else if (size <= 301)
    1334             :     /* nonlinear increase in effort, kicking in around 80 bits */
    1335             :     /* 301 gives 48121 + tune_pb_min */
    1336         278 :     c0 = tune_pb_min + size - 60 +
    1337         278 :       ((size-73)>>1)*((size-70)>>3)*((size-56)>>4);
    1338             :   else
    1339           7 :     c0 = 49152; /* ECM is faster when it'd take longer */
    1340         439 :   return pollardbrent_i(n, size, c0, 0);
    1341             : }
    1342             : GEN
    1343           0 : Z_pollardbrent(GEN n, long rounds, long seed)
    1344             : {
    1345           0 :   pari_sp av = avma;
    1346           0 :   GEN v = pollardbrent_i(n, expi(n)+1, rounds, seed);
    1347           0 :   if (!v) return NULL;
    1348           0 :   if (typ(v) == t_INT) v = mkvec2(v, diviiexact(n,v));
    1349           0 :   else if (lg(v) == 7) v = mkvec2(gel(v,1), gel(v,4));
    1350           0 :   else v = mkvec3(gel(v,1), gel(v,4), gel(v,7));
    1351           0 :   return gerepilecopy(av, v);
    1352             : }
    1353             : 
    1354             : /***********************************************************************/
    1355             : /**              FACTORIZATION (Shanks' SQUFOF) --GN2000Sep30-Oct01   **/
    1356             : /**  squfof() returns a nontrivial factor of n, assuming n is odd,    **/
    1357             : /**  composite, not a pure square, and has no small prime divisor,    **/
    1358             : /**  or NULL if it fails to find one.  It works on two discriminants  **/
    1359             : /**  simultaneously  (n and 5n for n=1(4), 3n and 4n for n=3(4)).     **/
    1360             : /**  Present implementation is limited to input <2^59, and works most **/
    1361             : /**  of the time in signed arithmetic on integers <2^31 in absolute   **/
    1362             : /**  size. (Cf. Algo 8.7.2 in ACiCNT)                                 **/
    1363             : /***********************************************************************/
    1364             : 
    1365             : /* The following is invoked to walk back along the ambiguous cycle* until we
    1366             :  * hit an ambiguous form and thus the desired factor, which it returns.  If it
    1367             :  * fails for any reason, it returns 0.  It doesn't interfere with timing and
    1368             :  * diagnostics, which it leaves to squfof().
    1369             :  *
    1370             :  * Before we invoke this, we've found a form (A, B, -C) with A = a^2, where a
    1371             :  * isn't blacklisted and where gcd(a, B) = 1.  According to ACiCANT, we should
    1372             :  * now proceed reducing the form (a, -B, -aC), but it is easy to show that the
    1373             :  * first reduction step always sends this to (-aC, B, a), and the next one,
    1374             :  * with q computed as usual from B and a (occupying the c position), gives a
    1375             :  * reduced form, whose third member is easiest to recover by going back to D.
    1376             :  * From this point onwards, we're once again working with single-word numbers.
    1377             :  * No need to track signs, just work with the abs values of the coefficients. */
    1378             : static long
    1379        2158 : squfof_ambig(long a, long B, long dd, GEN D)
    1380             : {
    1381             :   long b, c, q, qa, qc, qcb, a0, b0, b1, c0;
    1382        2158 :   long cnt = 0; /* count reduction steps on the cycle */
    1383             : 
    1384        2158 :   q = (dd + (B>>1)) / a;
    1385        2158 :   qa = q * a;
    1386        2158 :   b = (qa - B) + qa; /* avoid overflow */
    1387             :   {
    1388        2158 :     pari_sp av = avma;
    1389        2158 :     c = itos(divis(shifti(subii(D, sqrs(b)), -2), a));
    1390        2158 :     set_avma(av);
    1391             :   }
    1392             : #ifdef DEBUG_SQUFOF
    1393             :   err_printf("SQUFOF: ambigous cycle of discriminant %Ps\n", D);
    1394             :   err_printf("SQUFOF: Form on ambigous cycle (%ld, %ld, %ld)\n", a, b, c);
    1395             : #endif
    1396             : 
    1397        2158 :   a0 = a; b0 = b1 = b;        /* end of loop detection and safeguard */
    1398             : 
    1399             :   for (;;) /* reduced cycles are finite */
    1400             :   { /* reduction step */
    1401     1007688 :     c0 = c;
    1402     1007688 :     if (c0 > dd)
    1403      281271 :       q = 1;
    1404             :     else
    1405      726417 :       q = (dd + (b>>1)) / c0;
    1406     1007688 :     if (q == 1)
    1407             :     {
    1408      417320 :       qcb = c0 - b; b = c0 + qcb; c = a - qcb;
    1409             :     }
    1410             :     else
    1411             :     {
    1412      590368 :       qc = q*c0; qcb = qc - b; b = qc + qcb; c = a - q*qcb;
    1413             :     }
    1414     1007688 :     a = c0;
    1415             : 
    1416     1007688 :     cnt++; if (b == b1) break;
    1417             : 
    1418             :     /* safeguard against infinite loop: recognize when we've walked the entire
    1419             :      * cycle in vain. (I don't think this can actually happen -- exercise.) */
    1420     1005530 :     if (b == b0 && a == a0) return 0;
    1421             : 
    1422     1005530 :     b1 = b;
    1423             :   }
    1424        2158 :   q = a&1 ? a : a>>1;
    1425        2158 :   if (DEBUGLEVEL >= 4)
    1426             :   {
    1427           0 :     if (q > 1)
    1428           0 :       err_printf("SQUFOF: found factor %ld from ambiguous form\n"
    1429             :                  "\tafter %ld steps on the ambiguous cycle\n",
    1430           0 :                  q / ugcd(q,15), cnt);
    1431             :     else
    1432           0 :       err_printf("SQUFOF: ...found nothing on the ambiguous cycle\n"
    1433             :                  "\tafter %ld steps there\n", cnt);
    1434           0 :     if (DEBUGLEVEL >= 6) err_printf("SQUFOF: squfof_ambig returned %ld\n", q);
    1435             :   }
    1436        2158 :   return q;
    1437             : }
    1438             : 
    1439             : #define SQUFOF_BLACKLIST_SZ 64
    1440             : 
    1441             : /* assume 2,3,5 do not divide n */
    1442             : static GEN
    1443        4974 : squfof(GEN n)
    1444             : {
    1445             :   ulong d1, d2;
    1446        4974 :   long tf = lgefint(n), nm4, cnt = 0;
    1447             :   long a1, b1, c1, dd1, L1, a2, b2, c2, dd2, L2, a, q, c, qc, qcb;
    1448             :   GEN D1, D2;
    1449        4974 :   pari_sp av = avma;
    1450             :   long blacklist1[SQUFOF_BLACKLIST_SZ], blacklist2[SQUFOF_BLACKLIST_SZ];
    1451        4974 :   long blp1 = 0, blp2 = 0;
    1452        4974 :   int act1 = 1, act2 = 1;
    1453             : 
    1454             : #ifdef LONG_IS_64BIT
    1455        4206 :   if (tf > 3 || (tf == 3 && uel(n,2)             >= (1UL << 46)))
    1456             : #else  /* 32 bits */
    1457         768 :   if (tf > 4 || (tf == 4 && (ulong)(*int_MSW(n)) >= (1UL << 17))) /* 49 */
    1458             : #endif
    1459        3280 :     return NULL; /* n too large */
    1460             : 
    1461             :   /* now we have 5 < n < 2^59 */
    1462        1694 :   nm4 = mod4(n);
    1463        1694 :   if (nm4 == 1)
    1464             :   { /* n = 1 (mod4):  run one iteration on D1 = n, another on D2 = 5n */
    1465         791 :     D1 = n;
    1466         791 :     D2 = mului(5,n); d2 = itou(sqrti(D2)); dd2 = (long)((d2>>1) + (d2&1));
    1467         791 :     b2 = (long)((d2-1) | 1);        /* b1, b2 will always stay odd */
    1468             :   }
    1469             :   else
    1470             :   { /* n = 3 (mod4):  run one iteration on D1 = 3n, another on D2 = 4n */
    1471         903 :     D1 = mului(3,n);
    1472         903 :     D2 = shifti(n,2); dd2 = itou(sqrti(n)); d2 =  dd2 << 1;
    1473         903 :     b2 = (long)(d2 & (~1UL)); /* largest even below d2, will stay even */
    1474             :   }
    1475        1694 :   d1 = itou(sqrti(D1));
    1476        1694 :   b1 = (long)((d1-1) | 1); /* largest odd number not exceeding d1 */
    1477        1694 :   c1 = itos(shifti(subii(D1, sqru((ulong)b1)), -2));
    1478        1694 :   if (!c1) pari_err_BUG("squfof [caller of] (n or 3n is a square)");
    1479        1694 :   c2 = itos(shifti(subii(D2, sqru((ulong)b2)), -2));
    1480        1694 :   if (!c2) pari_err_BUG("squfof [caller of] (5n is a square)");
    1481        1694 :   L1 = (long)usqrt(d1);
    1482        1694 :   L2 = (long)usqrt(d2);
    1483             :   /* dd1 used to compute floor((d1+b1)/2) as dd1+floor(b1/2), without
    1484             :    * overflowing the 31bit signed integer size limit. Same for dd2. */
    1485        1694 :   dd1 = (long) ((d1>>1) + (d1&1));
    1486        1694 :   a1 = a2 = 1;
    1487             : 
    1488             :   /* The two (identity) forms (a1,b1,-c1) and (a2,b2,-c2) are now set up.
    1489             :    *
    1490             :    * a1 and c1 represent the absolute values of the a,c coefficients; we keep
    1491             :    * track of the sign separately, via the iteration counter cnt: when cnt is
    1492             :    * even, c is understood to be negative, else c is positive and a < 0.
    1493             :    *
    1494             :    * L1, L2 are the limits for blacklisting small leading coefficients
    1495             :    * on the principal cycle, to guarantee that when we find a square form,
    1496             :    * its square root will belong to an ambiguous cycle  (i.e. won't be an
    1497             :    * earlier form on the principal cycle).
    1498             :    *
    1499             :    * When n = 3(mod 4), D2 = 12(mod 16), and b^2 is always 0 or 4 mod 16.
    1500             :    * It follows that 4*a*c must be 4 or 8 mod 16, respectively, so at most
    1501             :    * one of a,c can be divisible by 2 at most to the first power.  This fact
    1502             :    * is used a couple of times below.
    1503             :    *
    1504             :    * The flags act1, act2 remain true while the respective cycle is still
    1505             :    * active;  we drop them to false when we return to the identity form with-
    1506             :    * out having found a square form  (or when the blacklist overflows, which
    1507             :    * shouldn't happen). */
    1508        1694 :   if (DEBUGLEVEL >= 4)
    1509           0 :     err_printf("SQUFOF: entering main loop with forms\n"
    1510             :                "\t(1, %ld, %ld) and (1, %ld, %ld)\n\tof discriminants\n"
    1511             :                "\t%Ps and %Ps, respectively\n", b1, -c1, b2, -c2, D1, D2);
    1512             : 
    1513             :   /* MAIN LOOP: walk around the principal cycle looking for a square form.
    1514             :    * Blacklist small leading coefficients.
    1515             :    *
    1516             :    * The reduction operator can be computed entirely in 32-bit arithmetic:
    1517             :    * Let q = floor(floor((d1+b1)/2)/c1)  (when c1>dd1, q=1, which happens
    1518             :    * often enough to special-case it).  Then the new b1 = (q*c1-b1) + q*c1,
    1519             :    * which does not overflow, and the new c1 = a1 - q*(q*c1-b1), which is
    1520             :    * bounded by d1 in abs size since both the old and the new a1 are positive
    1521             :    * and bounded by d1. */
    1522     1459669 :   while (act1 || act2)
    1523             :   {
    1524     1459668 :     if (act1)
    1525             :     { /* send first form through reduction operator if active */
    1526     1459656 :       c = c1;
    1527     1459656 :       q = (c > dd1)? 1: (dd1 + (b1>>1)) / c;
    1528     1459656 :       if (q == 1)
    1529      604307 :       { qcb = c - b1; b1 = c + qcb; c1 = a1 - qcb; }
    1530             :       else
    1531      855349 :       { qc = q*c; qcb = qc - b1; b1 = qc + qcb; c1 = a1 - q*qcb; }
    1532     1459656 :       a1 = c;
    1533             : 
    1534     1459656 :       if (a1 <= L1)
    1535             :       { /* blacklist this */
    1536        1196 :         if (blp1 >= SQUFOF_BLACKLIST_SZ) /* overflows: shouldn't happen */
    1537           0 :           act1 = 0; /* silently */
    1538             :         else
    1539             :         {
    1540        1196 :           if (DEBUGLEVEL >= 6)
    1541           0 :             err_printf("SQUFOF: blacklisting a = %ld on first cycle\n", a1);
    1542        1196 :           blacklist1[blp1++] = a1;
    1543             :         }
    1544             :       }
    1545             :     }
    1546     1459668 :     if (act2)
    1547             :     { /* send second form through reduction operator if active */
    1548     1455178 :       c = c2;
    1549     1455178 :       q = (c > dd2)? 1: (dd2 + (b2>>1)) / c;
    1550     1455178 :       if (q == 1)
    1551      603667 :       { qcb = c - b2; b2 = c + qcb; c2 = a2 - qcb; }
    1552             :       else
    1553      851511 :       { qc = q*c; qcb = qc - b2; b2 = qc + qcb; c2 = a2 - q*qcb; }
    1554     1455178 :       a2 = c;
    1555             : 
    1556     1455178 :       if (a2 <= L2)
    1557             :       { /* blacklist this */
    1558        1096 :         if (blp2 >= SQUFOF_BLACKLIST_SZ) /* overflows: shouldn't happen */
    1559           0 :           act2 = 0; /* silently */
    1560             :         else
    1561             :         {
    1562        1096 :           if (DEBUGLEVEL >= 6)
    1563           0 :             err_printf("SQUFOF: blacklisting a = %ld on second cycle\n", a2);
    1564        1096 :           blacklist2[blp2++] = a2;
    1565             :         }
    1566             :       }
    1567             :     }
    1568             : 
    1569             :     /* bump counter, loop if this is an odd iteration (i.e. if the real
    1570             :      * leading coefficients are negative) */
    1571     1459668 :     if (++cnt & 1) continue;
    1572             : 
    1573             :     /* second half of main loop entered only when the leading coefficients
    1574             :      * are positive (i.e., during even-numbered iterations) */
    1575             : 
    1576             :     /* examine first form if active */
    1577      729834 :     if (act1 && a1 == 1) /* back to identity */
    1578             :     { /* drop this discriminant */
    1579           1 :       act1 = 0;
    1580           1 :       if (DEBUGLEVEL >= 4)
    1581           0 :         err_printf("SQUFOF: first cycle exhausted after %ld iterations,\n"
    1582             :                    "\tdropping it\n", cnt);
    1583             :     }
    1584      729834 :     if (act1)
    1585             :     {
    1586      729827 :       if (uissquareall((ulong)a1, (ulong*)&a))
    1587             :       { /* square form */
    1588        1404 :         if (DEBUGLEVEL >= 4)
    1589           0 :           err_printf("SQUFOF: square form (%ld^2, %ld, %ld) on first cycle\n"
    1590             :                      "\tafter %ld iterations\n", a, b1, -c1, cnt);
    1591        1404 :         if (a <= L1)
    1592             :         { /* blacklisted? */
    1593             :           long j;
    1594        2714 :           for (j = 0; j < blp1; j++)
    1595        1863 :             if (a == blacklist1[j]) { a = 0; break; }
    1596             :         }
    1597        1404 :         if (a > 0)
    1598             :         { /* not blacklisted */
    1599         851 :           q = ugcd(a, b1); /* imprimitive form? */
    1600         851 :           if (q > 1)
    1601             :           { /* q^2 divides D1 hence n [ assuming n % 3 != 0 ] */
    1602           0 :             set_avma(av);
    1603           0 :             if (DEBUGLEVEL >= 4) err_printf("SQUFOF: found factor %ld^2\n", q);
    1604           0 :             return mkvec3(utoipos(q), gen_2, NULL);/* exponent 2, unknown status */
    1605             :           }
    1606             :           /* chase the inverse root form back along the ambiguous cycle */
    1607         851 :           q = squfof_ambig(a, b1, dd1, D1);
    1608         851 :           if (nm4 == 3 && q % 3 == 0) q /= 3;
    1609         851 :           if (q > 1) return gc_utoipos(av, q); /* SUCCESS! */
    1610             :         }
    1611         553 :         else if (DEBUGLEVEL >= 4) /* blacklisted */
    1612           0 :           err_printf("SQUFOF: ...but the root form seems to be on the "
    1613             :                      "principal cycle\n");
    1614             :       }
    1615             :     }
    1616             : 
    1617             :     /* examine second form if active */
    1618      729148 :     if (act2 && a2 == 1) /* back to identity form */
    1619             :     { /* drop this discriminant */
    1620          10 :       act2 = 0;
    1621          10 :       if (DEBUGLEVEL >= 4)
    1622           0 :         err_printf("SQUFOF: second cycle exhausted after %ld iterations,\n"
    1623             :                    "\tdropping it\n", cnt);
    1624             :     }
    1625      729148 :     if (act2)
    1626             :     {
    1627      726902 :       if (uissquareall((ulong)a2, (ulong*)&a))
    1628             :       { /* square form */
    1629        1576 :         if (DEBUGLEVEL >= 4)
    1630           0 :           err_printf("SQUFOF: square form (%ld^2, %ld, %ld) on second cycle\n"
    1631             :                      "\tafter %ld iterations\n", a, b2, -c2, cnt);
    1632        1576 :         if (a <= L2)
    1633             :         { /* blacklisted? */
    1634             :           long j;
    1635        2728 :           for (j = 0; j < blp2; j++)
    1636        1421 :             if (a == blacklist2[j]) { a = 0; break; }
    1637             :         }
    1638        1576 :         if (a > 0)
    1639             :         { /* not blacklisted */
    1640        1307 :           q = ugcd(a, b2); /* imprimitive form? */
    1641             :           /* NB if b2 is even, a is odd, so the gcd is always odd */
    1642        1307 :           if (q > 1)
    1643             :           { /* q^2 divides D2 hence n [ assuming n % 5 != 0 ] */
    1644           0 :             set_avma(av);
    1645           0 :             if (DEBUGLEVEL >= 4) err_printf("SQUFOF: found factor %ld^2\n", q);
    1646           0 :             return mkvec3(utoipos(q), gen_2, NULL);/* exponent 2, unknown status */
    1647             :           }
    1648             :           /* chase the inverse root form along the ambiguous cycle */
    1649        1307 :           q = squfof_ambig(a, b2, dd2, D2);
    1650        1307 :           if (nm4 == 1 && q % 5 == 0) q /= 5;
    1651        1307 :           if (q > 1) return gc_utoipos(av, q); /* SUCCESS! */
    1652             :         }
    1653         269 :         else if (DEBUGLEVEL >= 4)        /* blacklisted */
    1654           0 :           err_printf("SQUFOF: ...but the root form seems to be on the "
    1655             :                      "principal cycle\n");
    1656             :       }
    1657             :     }
    1658             :   } /* end main loop */
    1659             : 
    1660             :   /* both discriminants turned out to be useless. */
    1661           1 :   if (DEBUGLEVEL>=4) err_printf("SQUFOF: giving up\n");
    1662           1 :   return gc_NULL(av);
    1663             : }
    1664             : 
    1665             : /***********************************************************************/
    1666             : /*                    DETECTING ODD POWERS  --GN1998Jun28              */
    1667             : /*   Factoring engines like MPQS which ultimately rely on computing    */
    1668             : /*   gcd(N, x^2-y^2) to find a nontrivial factor of N can't split      */
    1669             : /*   N = p^k for an odd prime p, since (Z/p^k)^* is then cyclic. Here  */
    1670             : /*   is an analogue of Z_issquareall() for 3rd, 5th and 7th powers.    */
    1671             : /*   The general case is handled by is_kth_power                       */
    1672             : /***********************************************************************/
    1673             : 
    1674             : /* Multistage sieve. First stages work mod 211, 209, 61, 203 in this order
    1675             :  * (first reduce mod the product of these and then take the remainder apart).
    1676             :  * Second stages use 117, 31, 43, 71. Moduli which are no longer interesting
    1677             :  * are skipped. Everything is encoded in a table of 106 24-bit masks. We only
    1678             :  * need the first half of the residues.  Three bits per modulus indicate which
    1679             :  * residues are 7th (bit 2), 5th (bit 1) or 3rd (bit 0) powers; the eight
    1680             :  * moduli above are assigned right-to-left. The table was generated using: */
    1681             : 
    1682             : #if 0
    1683             : L = [71, 43, 31, [O(3^2),O(13)], [O(7),O(29)], 61, [O(11),O(19)], 211];
    1684             : ispow(x, N, k)=
    1685             : {
    1686             :   if (type(N) == "t_INT", return (ispower(Mod(x,N), k)));
    1687             :   for (i = 1, #N, if (!ispower(x + N[i], k), return (0))); 1
    1688             : }
    1689             : check(r) =
    1690             : {
    1691             :   print1("  0");
    1692             :   for (i=1,#L,
    1693             :     N = 0;
    1694             :     if (ispow(r, L[i], 3), N += 1);
    1695             :     if (ispow(r, L[i], 5), N += 2);
    1696             :     if (ispow(r, L[i], 7), N += 4);
    1697             :     print1(N);
    1698             :   ); print("ul,  /* ", r, " */")
    1699             : }
    1700             : for (r = 0, 105, check(r))
    1701             : #endif
    1702             : static ulong powersmod[106] = {
    1703             :   077777777ul,  /* 0 */
    1704             :   077777777ul,  /* 1 */
    1705             :   013562440ul,  /* 2 */
    1706             :   012402540ul,  /* 3 */
    1707             :   013562440ul,  /* 4 */
    1708             :   052662441ul,  /* 5 */
    1709             :   016603440ul,  /* 6 */
    1710             :   016463450ul,  /* 7 */
    1711             :   013573551ul,  /* 8 */
    1712             :   012462540ul,  /* 9 */
    1713             :   012462464ul,  /* 10 */
    1714             :   013462771ul,  /* 11 */
    1715             :   012406473ul,  /* 12 */
    1716             :   012463641ul,  /* 13 */
    1717             :   052463646ul,  /* 14 */
    1718             :   012503446ul,  /* 15 */
    1719             :   013562440ul,  /* 16 */
    1720             :   052466440ul,  /* 17 */
    1721             :   012472451ul,  /* 18 */
    1722             :   012462454ul,  /* 19 */
    1723             :   032463550ul,  /* 20 */
    1724             :   013403664ul,  /* 21 */
    1725             :   013463460ul,  /* 22 */
    1726             :   032562565ul,  /* 23 */
    1727             :   012402540ul,  /* 24 */
    1728             :   052662441ul,  /* 25 */
    1729             :   032672452ul,  /* 26 */
    1730             :   013573551ul,  /* 27 */
    1731             :   012467541ul,  /* 28 */
    1732             :   012567640ul,  /* 29 */
    1733             :   032706450ul,  /* 30 */
    1734             :   012762452ul,  /* 31 */
    1735             :   033762662ul,  /* 32 */
    1736             :   012502562ul,  /* 33 */
    1737             :   032463562ul,  /* 34 */
    1738             :   013563440ul,  /* 35 */
    1739             :   016663440ul,  /* 36 */
    1740             :   036662550ul,  /* 37 */
    1741             :   012462552ul,  /* 38 */
    1742             :   033502450ul,  /* 39 */
    1743             :   012462643ul,  /* 40 */
    1744             :   033467540ul,  /* 41 */
    1745             :   017403441ul,  /* 42 */
    1746             :   017463462ul,  /* 43 */
    1747             :   017472460ul,  /* 44 */
    1748             :   033462470ul,  /* 45 */
    1749             :   052566450ul,  /* 46 */
    1750             :   013562640ul,  /* 47 */
    1751             :   032403640ul,  /* 48 */
    1752             :   016463450ul,  /* 49 */
    1753             :   016463752ul,  /* 50 */
    1754             :   033402440ul,  /* 51 */
    1755             :   012462540ul,  /* 52 */
    1756             :   012472540ul,  /* 53 */
    1757             :   053562462ul,  /* 54 */
    1758             :   012463465ul,  /* 55 */
    1759             :   012663470ul,  /* 56 */
    1760             :   052607450ul,  /* 57 */
    1761             :   012566553ul,  /* 58 */
    1762             :   013466440ul,  /* 59 */
    1763             :   012502741ul,  /* 60 */
    1764             :   012762744ul,  /* 61 */
    1765             :   012763740ul,  /* 62 */
    1766             :   012763443ul,  /* 63 */
    1767             :   013573551ul,  /* 64 */
    1768             :   013462471ul,  /* 65 */
    1769             :   052502460ul,  /* 66 */
    1770             :   012662463ul,  /* 67 */
    1771             :   012662451ul,  /* 68 */
    1772             :   012403550ul,  /* 69 */
    1773             :   073567540ul,  /* 70 */
    1774             :   072463445ul,  /* 71 */
    1775             :   072462740ul,  /* 72 */
    1776             :   012472442ul,  /* 73 */
    1777             :   012462644ul,  /* 74 */
    1778             :   013406650ul,  /* 75 */
    1779             :   052463471ul,  /* 76 */
    1780             :   012563474ul,  /* 77 */
    1781             :   013503460ul,  /* 78 */
    1782             :   016462441ul,  /* 79 */
    1783             :   016462440ul,  /* 80 */
    1784             :   012462540ul,  /* 81 */
    1785             :   013462641ul,  /* 82 */
    1786             :   012463454ul,  /* 83 */
    1787             :   013403550ul,  /* 84 */
    1788             :   057563540ul,  /* 85 */
    1789             :   017466441ul,  /* 86 */
    1790             :   017606471ul,  /* 87 */
    1791             :   053666573ul,  /* 88 */
    1792             :   012562561ul,  /* 89 */
    1793             :   013473641ul,  /* 90 */
    1794             :   032573440ul,  /* 91 */
    1795             :   016763440ul,  /* 92 */
    1796             :   016702640ul,  /* 93 */
    1797             :   033762552ul,  /* 94 */
    1798             :   012562550ul,  /* 95 */
    1799             :   052402451ul,  /* 96 */
    1800             :   033563441ul,  /* 97 */
    1801             :   012663561ul,  /* 98 */
    1802             :   012677560ul,  /* 99 */
    1803             :   012462464ul,  /* 100 */
    1804             :   032562642ul,  /* 101 */
    1805             :   013402551ul,  /* 102 */
    1806             :   032462450ul,  /* 103 */
    1807             :   012467445ul,  /* 104 */
    1808             :   032403440ul,  /* 105 */
    1809             : };
    1810             : 
    1811             : static int
    1812     3929025 : check_res(ulong x, ulong N, int shift, ulong *mask)
    1813             : {
    1814     3929025 :   long r = x%N; if ((ulong)r> (N>>1)) r = N - r;
    1815     3929025 :   *mask &= (powersmod[r] >> shift);
    1816     3929025 :   return *mask;
    1817             : }
    1818             : 
    1819             : /* is x mod 211*209*61*203*117*31*43*71 a 3rd, 5th or 7th power ? */
    1820             : int
    1821     2422206 : uis_357_powermod(ulong x, ulong *mask)
    1822             : {
    1823     2422206 :   if (             !check_res(x, 211UL, 0, mask)) return 0;
    1824      978721 :   if (*mask & 3 && !check_res(x, 209UL, 3, mask)) return 0;
    1825      399710 :   if (*mask & 3 && !check_res(x,  61UL, 6, mask)) return 0;
    1826      222372 :   if (*mask & 5 && !check_res(x, 203UL, 9, mask)) return 0;
    1827       56865 :   if (*mask & 1 && !check_res(x, 117UL,12, mask)) return 0;
    1828       32869 :   if (*mask & 3 && !check_res(x,  31UL,15, mask)) return 0;
    1829       24680 :   if (*mask & 5 && !check_res(x,  43UL,18, mask)) return 0;
    1830        7448 :   if (*mask & 6 && !check_res(x,  71UL,21, mask)) return 0;
    1831        3777 :   return 1;
    1832             : }
    1833             : /* asume x > 0 and pt != NULL */
    1834             : int
    1835     2367408 : uis_357_power(ulong x, ulong *pt, ulong *mask)
    1836             : {
    1837             :   double logx;
    1838     2367408 :   if (!odd(x))
    1839             :   {
    1840        9081 :     long v = vals(x);
    1841        9081 :     if (v % 7) *mask &= ~4;
    1842        9081 :     if (v % 5) *mask &= ~2;
    1843        9081 :     if (v % 3) *mask &= ~1;
    1844        9081 :     if (!*mask) return 0;
    1845             :   }
    1846     2359815 :   if (!uis_357_powermod(x, mask)) return 0;
    1847        2974 :   logx = log((double)x);
    1848        3846 :   while (*mask)
    1849             :   {
    1850             :     long e, b;
    1851             :     ulong y, ye;
    1852        2974 :     if (*mask & 1)      { b = 1; e = 3; }
    1853         873 :     else if (*mask & 2) { b = 2; e = 5; }
    1854         355 :     else                { b = 4; e = 7; }
    1855        2974 :     y = (ulong)(exp(logx / e) + 0.5);
    1856        2974 :     ye = upowuu(y,e);
    1857        2974 :     if (ye == x) { *pt = y; return e; }
    1858             : #ifdef LONG_IS_64BIT
    1859         750 :     if (ye > x) y--; else y++;
    1860         750 :     ye = upowuu(y,e);
    1861         750 :     if (ye == x) { *pt = y; return e; }
    1862             : #endif
    1863         872 :     *mask &= ~b; /* turn the bit off */
    1864             :   }
    1865         872 :   return 0;
    1866             : }
    1867             : 
    1868             : #ifndef LONG_IS_64BIT
    1869             : /* as above, split in two functions */
    1870             : /* is x mod 211*209*61*203 a 3rd, 5th or 7th power ? */
    1871             : static int
    1872       14416 : uis_357_powermod_32bit_1(ulong x, ulong *mask)
    1873             : {
    1874       14416 :   if (             !check_res(x, 211UL, 0, mask)) return 0;
    1875        8002 :   if (*mask & 3 && !check_res(x, 209UL, 3, mask)) return 0;
    1876        4125 :   if (*mask & 3 && !check_res(x,  61UL, 6, mask)) return 0;
    1877        2917 :   if (*mask & 5 && !check_res(x, 203UL, 9, mask)) return 0;
    1878         828 :   return 1;
    1879             : }
    1880             : /* is x mod 117*31*43*71 a 3rd, 5th or 7th power ? */
    1881             : static int
    1882         828 : uis_357_powermod_32bit_2(ulong x, ulong *mask)
    1883             : {
    1884         828 :   if (*mask & 1 && !check_res(x, 117UL,12, mask)) return 0;
    1885         656 :   if (*mask & 3 && !check_res(x,  31UL,15, mask)) return 0;
    1886         538 :   if (*mask & 5 && !check_res(x,  43UL,18, mask)) return 0;
    1887         267 :   if (*mask & 6 && !check_res(x,  71UL,21, mask)) return 0;
    1888         176 :   return 1;
    1889             : }
    1890             : #endif
    1891             : 
    1892             : /* Returns 3, 5, or 7 if x is a cube (but not a 5th or 7th power),  a 5th
    1893             :  * power (but not a 7th),  or a 7th power, and in this case creates the
    1894             :  * base on the stack and assigns its address to *pt.  Otherwise returns 0.
    1895             :  * x must be of type t_INT and positive;  this is not checked.  The *mask
    1896             :  * argument tells us which things to check -- bit 0: 3rd, bit 1: 5th,
    1897             :  * bit 2: 7th pwr;  set a bit to have the corresponding power examined --
    1898             :  * and is updated appropriately for a possible follow-up call */
    1899             : int
    1900     2801636 : is_357_power(GEN x, GEN *pt, ulong *mask)
    1901             : {
    1902     2801636 :   long lx = lgefint(x);
    1903             :   ulong r;
    1904             :   pari_sp av;
    1905             :   GEN y;
    1906             : 
    1907     2801636 :   if (!*mask) return 0; /* useful when running in a loop */
    1908     2430249 :   if (DEBUGLEVEL>4)
    1909           0 :     err_printf("OddPwrs: examining %ld-bit integer\n", expi(x)+1);
    1910     2430249 :   if (lgefint(x) == 3) {
    1911             :     ulong t;
    1912     2353443 :     long e = uis_357_power(x[2], &t, mask);
    1913     2353443 :     if (e)
    1914             :     {
    1915        2076 :       if (pt) *pt = utoi(t);
    1916        2076 :       return e;
    1917             :     }
    1918     2351367 :     return 0;
    1919             :   }
    1920             : #ifdef LONG_IS_64BIT
    1921       62390 :   r = (lx == 3)? uel(x,2): umodiu(x, 6046846918939827UL);
    1922       62390 :   if (!uis_357_powermod(r, mask)) return 0;
    1923             : #else
    1924       14416 :   r = (lx == 3)? uel(x,2): umodiu(x, 211*209*61*203);
    1925       14416 :   if (!uis_357_powermod_32bit_1(r, mask)) return 0;
    1926         828 :   r = (lx == 3)? uel(x,2): umodiu(x, 117*31*43*71);
    1927         828 :   if (!uis_357_powermod_32bit_2(r, mask)) return 0;
    1928             : #endif
    1929         981 :   av = avma;
    1930        1602 :   while (*mask)
    1931             :   {
    1932             :     long e, b;
    1933             :     /* priority to higher powers: if we have a 21st, it is easier to rediscover
    1934             :      * that its 7th root is a cube than that its cube root is a 7th power */
    1935        1303 :          if (*mask & 4) { b = 4; e = 7; }
    1936         963 :     else if (*mask & 2) { b = 2; e = 5; }
    1937         366 :     else                { b = 1; e = 3; }
    1938        1303 :     y = mpround( sqrtnr(itor(x, nbits2prec(64 + bit_accuracy(lx) / e)), e) );
    1939        1303 :     if (equalii(powiu(y,e), x))
    1940             :     {
    1941         682 :       if (!pt) return gc_int(av,e);
    1942         668 :       set_avma((pari_sp)y); *pt = gerepileuptoint(av, y);
    1943         668 :       return e;
    1944             :     }
    1945         621 :     *mask &= ~b; /* turn the bit off */
    1946         621 :     set_avma(av);
    1947             :   }
    1948         299 :   return 0;
    1949             : }
    1950             : 
    1951             : /* Is x a n-th power ? If pt != NULL, it receives the n-th root */
    1952             : ulong
    1953      470073 : is_kth_power(GEN x, ulong n, GEN *pt)
    1954             : {
    1955             :   forprime_t T;
    1956             :   long j;
    1957             :   ulong q, residue;
    1958             :   GEN y;
    1959      470073 :   pari_sp av = avma;
    1960             : 
    1961      470073 :   (void)u_forprime_arith_init(&T, odd(n)? 2*n+1: n+1, ULONG_MAX, 1,n);
    1962             :   /* we'll start at q, smallest prime >= n */
    1963             : 
    1964             :   /* Modular checks, use small primes q congruent 1 mod n */
    1965             :   /* A non n-th power nevertheless passes the test with proba n^(-#checks),
    1966             :    * We'd like this < 1e-6 but let j = floor(log(1e-6) / log(n)) which
    1967             :    * ensures much less. */
    1968      470009 :   if (n < 16)
    1969      117785 :     j = 5;
    1970      352224 :   else if (n < 32)
    1971      154258 :     j = 4;
    1972      197966 :   else if (n < 101)
    1973      176100 :     j = 3;
    1974       21866 :   else if (n < 1001)
    1975        5305 :     j = 2;
    1976       16561 :   else if (n < 17886697) /* smallest such that smallest suitable q is > 2^32 */
    1977       16303 :     j = 1;
    1978             :   else
    1979         275 :     j = 0;
    1980      513437 :   for (; j > 0; j--)
    1981             :   {
    1982      510817 :     if (!(q = u_forprime_next(&T))) break;
    1983             :     /* q a prime = 1 mod n */
    1984      510907 :     residue = umodiu(x, q);
    1985      510907 :     if (residue == 0)
    1986             :     {
    1987         483 :       if (Z_lval(x,q) % n) return gc_ulong(av,0);
    1988          49 :       continue;
    1989             :     }
    1990             :     /* n-th power mod q ? */
    1991      510424 :     if (Fl_powu(residue, (q-1)/n, q) != 1) return gc_ulong(av,0);
    1992             :   }
    1993        2620 :   set_avma(av);
    1994             : 
    1995        2611 :   if (DEBUGLEVEL>4) err_printf("\nOddPwrs: [%lu] passed modular checks\n",n);
    1996             :   /* go to the horse's mouth... */
    1997        2611 :   y = roundr( sqrtnr(itor(x, nbits2prec(expi(x)/n + 16)), n) );
    1998        2611 :   if (!equalii(powiu(y, n), x)) {
    1999        1662 :     if (DEBUGLEVEL>4) err_printf("\tBut it wasn't a pure power.\n");
    2000        1662 :     return gc_ulong(av,0);
    2001             :   }
    2002         949 :   if (!pt) set_avma(av); else { set_avma((pari_sp)y); *pt = gerepileuptoint(av,y); }
    2003         949 :   return 1;
    2004             : }
    2005             : 
    2006             : /* is x a p^i-th power, p >= 11 prime ? Similar to is_357_power(), but instead
    2007             :  * of the mask, we keep the current test exponent around. Cut off when
    2008             :  * log_2 x^(1/k) < cutoffbits since we would have found it by trial division.
    2009             :  * Everything needed here (primitive roots etc.) is computed from scratch on
    2010             :  * the fly; compared to the size of numbers under consideration, these
    2011             :  * word-sized computations take negligible time.
    2012             :  * Any cutoffbits > 0 is safe, but direct root extraction attempts are faster
    2013             :  * when trial division has been used to discover very small bases. We become
    2014             :  * competitive at cutoffbits ~ 10 */
    2015             : int
    2016       69323 : is_pth_power(GEN x, GEN *pt, forprime_t *T, ulong cutoffbits)
    2017             : {
    2018       69323 :   long cnt=0, size = expi(x) /* not +1 */;
    2019             :   ulong p;
    2020       69323 :   pari_sp av = avma;
    2021      485093 :   while ((p = u_forprime_next(T)) && size/p >= cutoffbits) {
    2022      415807 :     long v = 1;
    2023      415807 :     if (DEBUGLEVEL>5 && cnt++==2000)
    2024           0 :       { cnt=0; err_printf("%lu%% ", 100*p*cutoffbits/size); }
    2025      415861 :     while (is_kth_power(x, p, pt)) {
    2026          56 :       v *= p; x = *pt;
    2027          56 :       size = expi(x);
    2028             :     }
    2029      415812 :     if (v > 1)
    2030             :     {
    2031          42 :       if (DEBUGLEVEL>5) err_printf("\nOddPwrs: is a %ld power\n",v);
    2032          42 :       return v;
    2033             :     }
    2034             :   }
    2035       69267 :   if (DEBUGLEVEL>5) err_printf("\nOddPwrs: not a power\n",p);
    2036       69267 :   return gc_int(av,0); /* give up */
    2037             : }
    2038             : 
    2039             : /***********************************************************************/
    2040             : /**                FACTORIZATION  (master iteration)                  **/
    2041             : /**      Driver for the various methods of finding large factors      **/
    2042             : /**      (after trial division has cast out the very small ones).     **/
    2043             : /**                        GN1998Jun24--30                            **/
    2044             : /***********************************************************************/
    2045             : 
    2046             : /* Direct use:
    2047             :  *  ifac_start_hint(n,moebius,hint) registers with the iterative factorizer
    2048             :  *  - an integer n (without prime factors  < tridiv_bound(n))
    2049             :  *  - registers whether or not we should terminate early if we find a square
    2050             :  *    factor,
    2051             :  *  - a hint about which method(s) to use.
    2052             :  *  This must always be called first. If input is not composite, oo loop.
    2053             :  *  The routine decomposes n nontrivially into a product of two factors except
    2054             :  *  in squarefreeness ('Moebius') mode.
    2055             :  *
    2056             :  *  ifac_start(n,moebius) same using default hint.
    2057             :  *
    2058             :  *  ifac_primary_factor()  returns a prime divisor (not necessarily the
    2059             :  *    smallest) and the corresponding exponent.
    2060             :  *
    2061             :  * Encapsulated user interface: Many arithmetic functions have a 'contributor'
    2062             :  * ifac_xxx, to be called on any large composite cofactor left over after trial
    2063             :  * division by small primes: xxx is one of moebius, issquarefree, totient, etc.
    2064             :  *
    2065             :  * We never test whether the input number is prime or composite, since
    2066             :  * presumably it will have come out of the small factors finder stage
    2067             :  * (which doesn't really exist yet but which will test the left-over
    2068             :  * cofactor for primality once it does). */
    2069             : 
    2070             : /* The data structure in which we preserve whatever we know about our number N
    2071             :  * is kept on the PARI stack, and updated as needed.
    2072             :  * This makes the machinery re-entrant, and avoids memory leaks when a lengthy
    2073             :  * factorization is interrupted. We try to keep the whole affair connected,
    2074             :  * and the parent object is always older than its children.  This may in
    2075             :  * rare cases lead to some extra copying around, and knowing what is garbage
    2076             :  * at any given time is not trivial. See below for examples how to do it right.
    2077             :  * (Connectedness is destroyed if callers of ifac_main() create stuff on the
    2078             :  * stack in between calls. This is harmless as long as ifac_realloc() is used
    2079             :  * to re-create a connected object at the head of the stack just before
    2080             :  * collecting garbage.)
    2081             :  * A t_INT may well have > 10^6 distinct prime factors larger than 2^16. Since
    2082             :  * we need not find factors in order of increasing size, we must be prepared to
    2083             :  * drag a very large amount of data around.  We start with a small structure
    2084             :  * and extend it when necessary. */
    2085             : 
    2086             : /* The idea of the algorithm is:
    2087             :  * Let N0 be whatever is currently left of N after dividing off all the
    2088             :  * prime powers we have already returned to the caller.  Then we maintain
    2089             :  * N0 as a product
    2090             :  * (1) N0 = \prod_i P_i^{e_i} * \prod_j Q_j^{f_j} * \prod_k C_k^{g_k}
    2091             :  * where the P_i and Q_j are distinct primes, each C_k is known composite,
    2092             :  * none of the P_i divides any C_k, and we also know the total ordering
    2093             :  * of all the P_i, Q_j and C_k; in particular, we will never try to divide
    2094             :  * a C_k by a larger Q_j.  Some of the C_k may have common factors.
    2095             :  *
    2096             :  * Caveat implementor:  Taking gcds among C_k's is very likely to cost at
    2097             :  * least as much time as dividing off any primes as we find them, and book-
    2098             :  * keeping would be tough (since D=gcd(C_1,C_2) can still have common factors
    2099             :  * with both C_1/D and C_2/D, and so on...).
    2100             :  *
    2101             :  * At startup, we just initialize the structure to
    2102             :  * (2) N = C_1^1   (composite).
    2103             :  *
    2104             :  * Whenever ifac_primary_factor() or one of the arithmetic user interface
    2105             :  * routines needs a primary factor, and the smallest thing in our list is P_1,
    2106             :  * we return that and its exponent, and remove it from our list. (When nothing
    2107             :  * is left, we return a sentinel value -- gen_1.  And in Moebius mode, when we
    2108             :  * see something with exponent > 1, whether prime or composite, we return gen_0
    2109             :  * or 0, depending on the function). In all other cases, ifac_main() iterates
    2110             :  * the following steps until we have a P_1 in the smallest position.
    2111             :  *
    2112             :  * When the smallest item is C_1, as it is initially:
    2113             :  * (3.1) Crack C_1 into a nontrivial product  U_1 * U_2  by whatever method
    2114             :  * comes to mind for this size. (U for 'unknown'.)  Cracking will detect
    2115             :  * perfect powers, so we may instead see a power of some U_1 here, or even
    2116             :  * something of the form U_1^k*U_2^k; of course the exponent already attached
    2117             :  * to C_1 is taken into account in the following.
    2118             :  * (3.2) If we have U_1*U_2, sort the two factors (distinct: squares are caught
    2119             :  * in stage 3.1). N.B. U_1 and U_2 are smaller than anything else in our list.
    2120             :  * (3.3) Check U_1 and U_2 for primality, and flag them accordingly.
    2121             :  * (3.4) Iterate.
    2122             :  *
    2123             :  * When the smallest item is Q_1:
    2124             :  * This is the unpleasant case.  We go through the entire list and try to
    2125             :  * divide Q_1 off each of the current C_k's, which usually fails, but may
    2126             :  * succeed several times. When a division was successful, the corresponding
    2127             :  * C_k is removed from our list, and the cofactor becomes a U_l for the moment
    2128             :  * unless it is 1 (which happens when C_k was a power of Q_1).  When we're
    2129             :  * through we upgrade Q_1 to P_1 status, then do a primality check on each U_l
    2130             :  * and sort it back into the list either as a Q_j or as a C_k.  If during the
    2131             :  * insertion sort we discover that some U_l equals some P_i or Q_j or C_k we
    2132             :  * already have, we just add U_l's exponent to that of its twin. (The sorting
    2133             :  * therefore happens before the primality test). Since this may produce one or
    2134             :  * more elements smaller than the P_1 we just confirmed, we may have to repeat
    2135             :  * the iteration.
    2136             :  * A trick avoids some Q_1 instances: just after the sweep classifying
    2137             :  * all current unknowns as either composites or primes, we do another downward
    2138             :  * sweep beginning with the largest current factor and stopping just above the
    2139             :  * largest current composite.  Every Q_j we pass is turned into a P_i.
    2140             :  * (Different primes are automatically coprime among each other, and primes do
    2141             :  * not divide smaller composites.)
    2142             :  * NB: We have no use for comparing the square of a prime to N0.  Normally
    2143             :  * we will get called after casting out only the smallest primes, and
    2144             :  * since we cannot guarantee that we see the large prime factors in as-
    2145             :  * cending order, we cannot stop when we find one larger than sqrt(N0). */
    2146             : 
    2147             : /* Data structure: We keep everything in a single t_VEC of t_INTs.  The
    2148             :  * first 2 components are read-only:
    2149             :  * 1) the first records whether we're doing full (NULL) or Moebius (gen_1)
    2150             :  * factorization; in the latter case subroutines return a sentinel value as
    2151             :  * soon as they spot an exponent > 1.
    2152             :  * 2) the second records the hint from factorint()'s optional flag, for use by
    2153             :  * ifac_crack().
    2154             :  *
    2155             :  * The remaining components (initially 15) are used in groups of three:
    2156             :  * [ factor (t_INT), exponent (t_INT), factor class ], where factor class is
    2157             :  *  NULL : unknown
    2158             :  *  gen_0: known composite C_k
    2159             :  *  gen_1: known prime Q_j awaiting trial division
    2160             :  *  gen_2: finished prime P_i.
    2161             :  * When during the division stage we re-sort a C_k-turned-U_l to a lower
    2162             :  * position, we rotate any intervening material upward towards its old
    2163             :  * slot.  When a C_k was divided down to 1, its slot is left empty at
    2164             :  * first; similarly when the re-sorting detects a repeated factor.
    2165             :  * After the sorting phase, we de-fragment the list and squeeze all the
    2166             :  * occupied slots together to the high end, so that ifac_crack() has room
    2167             :  * for new factors.  When this doesn't suffice, we abandon the current vector
    2168             :  * and allocate a somewhat larger one, defragmenting again while copying.
    2169             :  *
    2170             :  * For internal use: note that all exponents will fit into C longs, given
    2171             :  * PARI's lgefint field size.  When we work with them, we sometimes read
    2172             :  * out the GEN pointer, and sometimes do an itos, whatever is more con-
    2173             :  * venient for the task at hand. */
    2174             : 
    2175             : /*** Overview ***/
    2176             : 
    2177             : /* The '*where' argument in the following points into *partial at the first of
    2178             :  * the three fields of the first occupied slot.  It's there because the caller
    2179             :  * would already know where 'here' is, so we don't want to search for it again.
    2180             :  * We do not preserve this from one user-interface call to the next. */
    2181             : 
    2182             : /* In the most cases, control flows from the user interface to ifac_main() and
    2183             :  * then to a succession of ifac_crack()s and ifac_divide()s, with (typically)
    2184             :  * none of the latter finding anything. */
    2185             : 
    2186             : #define LAST(x) x+lg(x)-3
    2187             : #define FIRST(x) x+3
    2188             : 
    2189             : #define MOEBIUS(x) gel(x,1)
    2190             : #define HINT(x) gel(x,2)
    2191             : 
    2192             : /* y <- x */
    2193             : INLINE void
    2194           0 : SHALLOWCOPY(GEN x, GEN y) {
    2195           0 :   VALUE(y) = VALUE(x);
    2196           0 :   EXPON(y) = EXPON(x);
    2197           0 :   CLASS(y) = CLASS(x);
    2198           0 : }
    2199             : /* y <- x */
    2200             : INLINE void
    2201           0 : COPY(GEN x, GEN y) {
    2202           0 :   icopyifstack(VALUE(x), VALUE(y));
    2203           0 :   icopyifstack(EXPON(x), EXPON(y));
    2204           0 :   CLASS(y) = CLASS(x);
    2205           0 : }
    2206             : 
    2207             : /* Diagnostics */
    2208             : static void
    2209           0 : ifac_factor_dbg(GEN x)
    2210             : {
    2211           0 :   GEN c = CLASS(x), v = VALUE(x);
    2212           0 :   if (c == gen_2) err_printf("IFAC: factor %Ps\n\tis prime (finished)\n", v);
    2213           0 :   else if (c == gen_1) err_printf("IFAC: factor %Ps\n\tis prime\n", v);
    2214           0 :   else if (c == gen_0) err_printf("IFAC: factor %Ps\n\tis composite\n", v);
    2215           0 : }
    2216             : static void
    2217           0 : ifac_check(GEN partial, GEN where)
    2218             : {
    2219           0 :   if (!where || where < FIRST(partial) || where > LAST(partial))
    2220           0 :     pari_err_BUG("ifac_check ['where' out of bounds]");
    2221           0 : }
    2222             : static void
    2223           0 : ifac_print(GEN part, GEN where)
    2224             : {
    2225           0 :   long l = lg(part);
    2226             :   GEN p;
    2227             : 
    2228           0 :   err_printf("ifac partial factorization structure: %ld slots, ", (l-3)/3);
    2229           0 :   if (MOEBIUS(part)) err_printf("Moebius mode, ");
    2230           0 :   err_printf("hint = %ld\n", itos(HINT(part)));
    2231           0 :   ifac_check(part, where);
    2232           0 :   for (p = part+3; p < part + l; p += 3)
    2233             :   {
    2234           0 :     GEN v = VALUE(p), e = EXPON(p), c = CLASS(p);
    2235           0 :     const char *s = "";
    2236           0 :     if (!v) { err_printf("[empty slot]\n"); continue; }
    2237           0 :     if (c == NULL) s = "unknown";
    2238           0 :     else if (c == gen_0) s = "composite";
    2239           0 :     else if (c == gen_1) s = "unfinished prime";
    2240           0 :     else if (c == gen_2) s = "prime";
    2241           0 :     else pari_err_BUG("unknown factor class");
    2242           0 :     err_printf("[%Ps, %Ps, %s]\n", v, e, s);
    2243             :   }
    2244           0 :   err_printf("Done.\n");
    2245           0 : }
    2246             : 
    2247             : static const long decomp_default_hint = 0;
    2248             : /* assume n > 0, which we can assign to */
    2249             : /* return initial data structure, see ifac_crack() for the hint argument */
    2250             : static GEN
    2251        6157 : ifac_start_hint(GEN n, int moebius, long hint)
    2252             : {
    2253        6157 :   const long ifac_initial_length = 3 + 7*3;
    2254             :   /* codeword, moebius, hint, 7 slots -- a 512-bit product of distinct 8-bit
    2255             :    * primes needs at most 7 slots at a time) */
    2256        6157 :   GEN here, part = cgetg(ifac_initial_length, t_VEC);
    2257             : 
    2258        6157 :   MOEBIUS(part) = moebius? gen_1 : NULL;
    2259        6157 :   HINT(part) = stoi(hint);
    2260             :   /* fill first slot at the top end */
    2261        6157 :   here = part + ifac_initial_length - 3; /* LAST(part) */
    2262        6157 :   INIT(here, n,gen_1,gen_0); /* n^1: composite */
    2263       43099 :   while ((here -= 3) > part) ifac_delete(here);
    2264        6157 :   return part;
    2265             : }
    2266             : GEN
    2267        2535 : ifac_start(GEN n, int moebius)
    2268        2535 : { return ifac_start_hint(n,moebius,decomp_default_hint); }
    2269             : 
    2270             : /* Return next nonempty slot after 'here', NULL if none exist */
    2271             : static GEN
    2272       15837 : ifac_find(GEN partial)
    2273             : {
    2274       15837 :   GEN scan, end = partial + lg(partial);
    2275             : 
    2276             : #ifdef IFAC_DEBUG
    2277             :   ifac_check(partial, partial);
    2278             : #endif
    2279      115439 :   for (scan = partial+3; scan < end; scan += 3)
    2280      110522 :     if (VALUE(scan)) return scan;
    2281        4917 :   return NULL;
    2282             : }
    2283             : 
    2284             : /* Defragment: squeeze out unoccupied slots above *where. Unoccupied slots
    2285             :  * arise when a composite factor dissolves completely whilst dividing off a
    2286             :  * prime, or when ifac_resort() spots a coincidence and merges two factors.
    2287             :  * Update *where */
    2288             : static void
    2289          14 : ifac_defrag(GEN *partial, GEN *where)
    2290             : {
    2291          14 :   GEN scan_new = LAST(*partial), scan_old;
    2292             : 
    2293          42 :   for (scan_old = scan_new; scan_old >= *where; scan_old -= 3)
    2294             :   {
    2295          28 :     if (!VALUE(scan_old)) continue; /* empty slot */
    2296          28 :     if (scan_old < scan_new) SHALLOWCOPY(scan_old, scan_new);
    2297          28 :     scan_new -= 3; /* point at next slot to be written */
    2298             :   }
    2299          14 :   scan_new += 3; /* back up to last slot written */
    2300          14 :   *where = scan_new;
    2301          84 :   while ((scan_new -= 3) > *partial) ifac_delete(scan_new); /* erase junk */
    2302          14 : }
    2303             : 
    2304             : /* Move to a larger main vector, updating *where if it points into it, and
    2305             :  * *partial in any case. Can be used as a specialized gcopy before
    2306             :  * a gerepileupto() (pass 0 as the new length). Normally, one would pass
    2307             :  * new_lg=1 to let this function guess the new size.  To be used sparingly.
    2308             :  * Complex version of ifac_defrag(), combined with reallocation.  If new_lg
    2309             :  * is 0, use the old length, so this acts just like gcopy except that the
    2310             :  * 'where' pointer is carried along; if it is 1, we make an educated guess.
    2311             :  * Exception:  If new_lg is 0, the vector is full to the brim, and the first
    2312             :  * entry is composite, we make it longer to avoid being called again a
    2313             :  * microsecond later. It is safe to call this with *where = NULL:
    2314             :  * if it doesn't point anywhere within the old structure, it is left alone */
    2315             : static void
    2316           0 : ifac_realloc(GEN *partial, GEN *where, long new_lg)
    2317             : {
    2318           0 :   long old_lg = lg(*partial);
    2319             :   GEN newpart, scan_new, scan_old;
    2320             : 
    2321           0 :   if (new_lg == 1)
    2322           0 :     new_lg = 2*old_lg - 6;        /* from 7 slots to 13 to 25... */
    2323           0 :   else if (new_lg <= old_lg)        /* includes case new_lg == 0 */
    2324             :   {
    2325           0 :     GEN first = *partial + 3;
    2326           0 :     new_lg = old_lg;
    2327             :     /* structure full and first entry composite or unknown */
    2328           0 :     if (VALUE(first) && (CLASS(first) == gen_0 || CLASS(first)==NULL))
    2329           0 :       new_lg += 6; /* give it a little more breathing space */
    2330             :   }
    2331           0 :   newpart = cgetg(new_lg, t_VEC);
    2332           0 :   if (DEBUGMEM >= 3)
    2333           0 :     err_printf("IFAC: new partial factorization structure (%ld slots)\n",
    2334           0 :                (new_lg - 3)/3);
    2335           0 :   MOEBIUS(newpart) = MOEBIUS(*partial);
    2336           0 :   icopyifstack(HINT(*partial), HINT(newpart));
    2337             :   /* Downward sweep through the old *partial. Pick up 'where' and carry it
    2338             :    * over if we pass it. (Only useful if it pointed at a nonempty slot.)
    2339             :    * Factors are COPY'd so that we again have a nice object (parent older
    2340             :    * than children, connected), except the one factor that may still be living
    2341             :    * in a clone where n originally was; exponents are similarly copied if they
    2342             :    * aren't global constants; class-of-factor fields are global constants so we
    2343             :    * need only copy them as pointers. Caller may then do a gerepileupto() */
    2344           0 :   scan_new = newpart + new_lg - 3; /* LAST(newpart) */
    2345           0 :   scan_old = *partial + old_lg - 3; /* LAST(*partial) */
    2346           0 :   for (; scan_old > *partial + 2; scan_old -= 3)
    2347             :   {
    2348           0 :     if (*where == scan_old) *where = scan_new;
    2349           0 :     if (!VALUE(scan_old)) continue; /* skip empty slots */
    2350           0 :     COPY(scan_old, scan_new); scan_new -= 3;
    2351             :   }
    2352           0 :   scan_new += 3; /* back up to last slot written */
    2353           0 :   while ((scan_new -= 3) > newpart) ifac_delete(scan_new);
    2354           0 :   *partial = newpart;
    2355           0 : }
    2356             : 
    2357             : /* Re-sort one (typically unknown) entry from washere to a new position,
    2358             :  * rotating intervening entries upward to fill the vacant space. If the new
    2359             :  * position is the same as the old one, or the new value of the entry coincides
    2360             :  * with a value already occupying a lower slot, then we just add exponents (and
    2361             :  * use the 'more known' class, and return 1 immediately when in Moebius mode).
    2362             :  * Slots between *where and washere must be in sorted order, so a sweep using
    2363             :  * this to re-sort several unknowns must proceed upward, see ifac_resort().
    2364             :  * Bubble-sort-of-thing sort. Won't be exercised frequently, so this is ok */
    2365             : static void
    2366           7 : ifac_sort_one(GEN *where, GEN washere)
    2367             : {
    2368           7 :   GEN old, scan = washere - 3;
    2369             :   GEN value, exponent, class0, class1;
    2370             :   long cmp_res;
    2371             : 
    2372           7 :   if (scan < *where) return; /* nothing to do, washere==*where */
    2373           7 :   value    = VALUE(washere);
    2374           7 :   exponent = EXPON(washere);
    2375           7 :   class0 = CLASS(washere);
    2376           7 :   cmp_res = -1; /* sentinel */
    2377           7 :   while (scan >= *where) /* at least once */
    2378             :   {
    2379           7 :     if (VALUE(scan))
    2380             :     { /* current slot nonempty, check against where */
    2381           7 :       cmp_res = cmpii(value, VALUE(scan));
    2382           7 :       if (cmp_res >= 0) break; /* have found where to stop */
    2383             :     }
    2384             :     /* copy current slot upward by one position and move pointers down */
    2385           0 :     SHALLOWCOPY(scan, scan+3);
    2386           0 :     scan -= 3;
    2387             :   }
    2388           7 :   scan += 3;
    2389             :   /* At this point there are the following possibilities:
    2390             :    * 1) cmp_res == -1. Either value is less than that at *where, or *where was
    2391             :    * pointing at vacant slots and any factors we saw en route were larger than
    2392             :    * value. At any rate, scan == *where now, and scan is pointing at an empty
    2393             :    * slot, into which we'll stash our entry.
    2394             :    * 2) cmp_res == 0. The entry at scan-3 is the one, we compare class0
    2395             :    * fields and add exponents, and put it all into the vacated scan slot,
    2396             :    * NULLing the one at scan-3 (and possibly updating *where).
    2397             :    * 3) cmp_res == 1. The slot at scan is the one to store our entry into. */
    2398           7 :   if (cmp_res)
    2399             :   {
    2400           7 :     if (cmp_res < 0 && scan != *where)
    2401           0 :       pari_err_BUG("ifact_sort_one [misaligned partial]");
    2402           7 :     INIT(scan, value, exponent, class0); return;
    2403             :   }
    2404             :   /* case cmp_res == 0: repeated factor detected */
    2405           0 :   if (DEBUGLEVEL >= 4)
    2406           0 :     err_printf("IFAC: repeated factor %Ps\n\tin ifac_sort_one\n", value);
    2407           0 :   old = scan - 3;
    2408             :   /* if old class0 was composite and new is prime, or vice versa, complain
    2409             :    * (and if one class0 was unknown and the other wasn't, use the known one) */
    2410           0 :   class1 = CLASS(old);
    2411           0 :   if (class0) /* should never be used */
    2412             :   {
    2413           0 :     if (class1)
    2414             :     {
    2415           0 :       if (class0 == gen_0 && class1 != gen_0)
    2416           0 :         pari_err_BUG("ifac_sort_one (composite = prime)");
    2417           0 :       else if (class0 != gen_0 && class1 == gen_0)
    2418           0 :         pari_err_BUG("ifac_sort_one (prime = composite)");
    2419           0 :       else if (class0 == gen_2)
    2420           0 :         CLASS(scan) = class0;
    2421             :     }
    2422             :     else
    2423           0 :       CLASS(scan) = class0;
    2424             :   }
    2425             :   /* else stay with the existing known class0 */
    2426           0 :   CLASS(scan) = class1;
    2427             :   /* in any case, add exponents */
    2428           0 :   if (EXPON(old) == gen_1 && exponent == gen_1)
    2429           0 :     EXPON(scan) = gen_2;
    2430             :   else
    2431           0 :     EXPON(scan) = addii(EXPON(old), exponent);
    2432             :   /* move the value over and null out the vacated slot below */
    2433           0 :   old = scan - 3;
    2434           0 :   *scan = *old;
    2435           0 :   ifac_delete(old);
    2436             :   /* finally, see whether *where should be pulled in */
    2437           0 :   if (old == *where) *where += 3;
    2438             : }
    2439             : 
    2440             : /* Sort all current unknowns downward to where they belong. Sweeps in the
    2441             :  * upward direction. Not needed after ifac_crack(), only when ifac_divide()
    2442             :  * returned true. Update *where. */
    2443             : static void
    2444           7 : ifac_resort(GEN *partial, GEN *where)
    2445             : {
    2446             :   GEN scan, end;
    2447           7 :   ifac_defrag(partial, where); end = LAST(*partial);
    2448          21 :   for (scan = *where; scan <= end; scan += 3)
    2449          14 :     if (VALUE(scan) && !CLASS(scan)) ifac_sort_one(where, scan); /*unknown*/
    2450           7 :   ifac_defrag(partial, where); /* remove newly created gaps */
    2451           7 : }
    2452             : 
    2453             : /* Let x be a t_INT known not to have small divisors (< 661, and < 2^14 for huge
    2454             :  * x > 2^512). Return 0 if x is a proven composite. Return 1 if we believe it
    2455             :  * to be prime (fully proven prime if factor_proven is set).  */
    2456             : int
    2457       31813 : ifac_isprime(GEN x)
    2458             : {
    2459       31813 :   if (!BPSW_psp_nosmalldiv(x)) return 0; /* composite */
    2460       20227 :   if (factor_proven && ! BPSW_isprime(x))
    2461             :   {
    2462           0 :     pari_warn(warner,
    2463             :               "IFAC: pseudo-prime %Ps\n\tis not prime. PLEASE REPORT!\n", x);
    2464           0 :     return 0;
    2465             :   }
    2466       20227 :   return 1;
    2467             : }
    2468             : 
    2469             : static int
    2470       11678 : ifac_checkprime(GEN x)
    2471             : {
    2472       11678 :   int res = ifac_isprime(VALUE(x));
    2473       11678 :   CLASS(x) = res? gen_1: gen_0;
    2474       11678 :   if (DEBUGLEVEL>2) ifac_factor_dbg(x);
    2475       11678 :   return res;
    2476             : }
    2477             : 
    2478             : /* Determine primality or compositeness of all current unknowns, and set
    2479             :  * class Q primes to finished (class P) if everything larger is already
    2480             :  * known to be prime.  When after_crack >= 0, only look at the
    2481             :  * first after_crack things in the list (do nothing when it's 0) */
    2482             : static void
    2483        5958 : ifac_whoiswho(GEN *partial, GEN *where, long after_crack)
    2484             : {
    2485        5958 :   GEN scan, scan_end = LAST(*partial);
    2486             : 
    2487             : #ifdef IFAC_DEBUG
    2488             :   ifac_check(*partial, *where);
    2489             : #endif
    2490        5958 :   if (after_crack == 0) return;
    2491        5307 :   if (after_crack > 0) /* check at most after_crack entries */
    2492        5300 :     scan = *where + 3*(after_crack - 1); /* assert(scan <= scan_end) */
    2493             :   else
    2494           7 :     for (scan = scan_end; scan >= *where; scan -= 3)
    2495             :     {
    2496           7 :       if (CLASS(scan))
    2497             :       { /* known class of factor */
    2498           0 :         if (CLASS(scan) == gen_0) break;
    2499           0 :         if (CLASS(scan) == gen_1)
    2500             :         {
    2501           0 :           if (DEBUGLEVEL>=3)
    2502             :           {
    2503           0 :             err_printf("IFAC: factor %Ps\n\tis prime (no larger composite)\n",
    2504           0 :                        VALUE(*where));
    2505           0 :             err_printf("IFAC: prime %Ps\n\tappears with exponent = %ld\n",
    2506           0 :                        VALUE(*where), itos(EXPON(*where)));
    2507             :           }
    2508           0 :           CLASS(scan) = gen_2;
    2509             :         }
    2510           0 :         continue;
    2511             :       }
    2512           7 :       if (!ifac_checkprime(scan)) break; /* must disable Q-to-P */
    2513           0 :       CLASS(scan) = gen_2; /* P_i, finished prime */
    2514           0 :       if (DEBUGLEVEL>2) ifac_factor_dbg(scan);
    2515             :     }
    2516             :   /* go on, Q-to-P trick now disabled */
    2517       16265 :   for (; scan >= *where; scan -= 3)
    2518             :   {
    2519       10958 :     if (CLASS(scan)) continue;
    2520       10923 :     (void)ifac_checkprime(scan); /* Qj | Ck */
    2521             :   }
    2522             : }
    2523             : 
    2524             : /* Divide all current composites by first (prime, class Q) entry, updating its
    2525             :  * exponent, and turning it into a finished prime (class P).  Return 1 if any
    2526             :  * such divisions succeeded  (in Moebius mode, the update may then not have
    2527             :  * been completed), or 0 if none of them succeeded.  Doesn't modify *where.
    2528             :  * Here we normally do not check that the first entry is a not-finished
    2529             :  * prime.  Stack management: we may allocate a new exponent */
    2530             : static long
    2531       10246 : ifac_divide(GEN *partial, GEN *where, long moebius_mode)
    2532             : {
    2533       10246 :   GEN scan, scan_end = LAST(*partial);
    2534       10246 :   long res = 0, exponent, newexp, otherexp;
    2535             : 
    2536             : #ifdef IFAC_DEBUG
    2537             :   ifac_check(*partial, *where);
    2538             :   if (CLASS(*where) != gen_1)
    2539             :     pari_err_BUG("ifac_divide [division by composite or finished prime]");
    2540             :   if (!VALUE(*where)) pari_err_BUG("ifac_divide [division by nothing]");
    2541             : #endif
    2542       10246 :   newexp = exponent = itos(EXPON(*where));
    2543       10246 :   if (exponent > 1 && moebius_mode) return 1;
    2544             :   /* should've been caught by caller */
    2545             : 
    2546       16227 :   for (scan = *where+3; scan <= scan_end; scan += 3)
    2547             :   {
    2548        5981 :     if (CLASS(scan) != gen_0) continue; /* the other thing ain't composite */
    2549         144 :     otherexp = 0;
    2550             :     /* divide in place to keep stack clutter minimal */
    2551         158 :     while (dvdiiz(VALUE(scan), VALUE(*where), VALUE(scan)))
    2552             :     {
    2553          14 :       if (moebius_mode) return 1; /* immediately */
    2554          14 :       if (!otherexp) otherexp = itos(EXPON(scan));
    2555          14 :       newexp += otherexp;
    2556             :     }
    2557         144 :     if (newexp > exponent)        /* did anything happen? */
    2558             :     {
    2559           7 :       EXPON(*where) = (newexp == 2 ? gen_2 : utoipos(newexp));
    2560           7 :       exponent = newexp;
    2561           7 :       if (is_pm1((GEN)*scan)) /* factor dissolved completely */
    2562             :       {
    2563           0 :         ifac_delete(scan);
    2564           0 :         if (DEBUGLEVEL >= 4)
    2565           0 :           err_printf("IFAC: a factor was a power of another prime factor\n");
    2566             :       } else {
    2567           7 :         CLASS(scan) = NULL;        /* at any rate it's Unknown now */
    2568           7 :         if (DEBUGLEVEL >= 4)
    2569           0 :           err_printf("IFAC: a factor was divisible by another prime factor,\n"
    2570             :                      "\tleaving a cofactor = %Ps\n", VALUE(scan));
    2571             :       }
    2572           7 :       res = 1;
    2573           7 :       if (DEBUGLEVEL >= 5)
    2574           0 :         err_printf("IFAC: prime %Ps\n\tappears at least to the power %ld\n",
    2575           0 :                    VALUE(*where), newexp);
    2576             :     }
    2577             :   } /* for */
    2578       10246 :   CLASS(*where) = gen_2; /* make it a finished prime */
    2579       10246 :   if (DEBUGLEVEL >= 3)
    2580           0 :     err_printf("IFAC: prime %Ps\n\tappears with exponent = %ld\n",
    2581           0 :                VALUE(*where), newexp);
    2582       10246 :   return res;
    2583             : }
    2584             : 
    2585             : /* found out our integer was factor^exp. Update */
    2586             : static void
    2587         944 : update_pow(GEN where, GEN factor, long exp, pari_sp *av)
    2588             : {
    2589         944 :   GEN ex = EXPON(where);
    2590         944 :   if (DEBUGLEVEL>3)
    2591           0 :     err_printf("IFAC: found %Ps =\n\t%Ps ^%ld\n", *where, factor, exp);
    2592         944 :   affii(factor, VALUE(where)); set_avma(*av);
    2593         944 :   if (ex == gen_1)
    2594         741 :   { EXPON(where) = exp == 2? gen_2: utoipos(exp); *av = avma; }
    2595         203 :   else if (ex == gen_2)
    2596         182 :   { EXPON(where) = utoipos(exp<<1); *av = avma; }
    2597             :   else
    2598          21 :     affsi(exp * itos(ex), EXPON(where));
    2599         944 : }
    2600             : /* hint = 0 : Use a default strategy
    2601             :  * hint & 1 : avoid MPQS
    2602             :  * hint & 2 : avoid first-stage ECM (may fall back to ECM if MPQS gives up)
    2603             :  * hint & 4 : avoid Pollard and SQUFOF stages.
    2604             :  * hint & 8 : avoid final ECM; may flag a composite as prime. */
    2605             : #define get_hint(partial) (itos(HINT(*partial)) & 15)
    2606             : 
    2607             : /* Complete ifac_crack's job when a factoring engine splits the current factor
    2608             :  * into a product of three or more new factors. Makes room for them if
    2609             :  * necessary, sorts them, gives them the right exponents and class. Returns the
    2610             :  * number of factors actually written, which may be less than #facvec if there
    2611             :  * are duplicates. Vectors of factors (cf pollardbrent() or mpqs()) contain
    2612             :  * 'slots' of 3 GENs per factor, interpreted as in our partial factorization
    2613             :  * data structure. Thus engines can tell us what they already know about
    2614             :  * factors being prime/composite or appearing to a power larger than thefirst.
    2615             :  * Don't collect garbage.  No diagnostics: engine has printed what it found.
    2616             :  * facvec contains slots of three components per factor; repeated factors are
    2617             :  * allowed (their classes shouldn't contradict each other whereas their
    2618             :  * exponents will be added up) */
    2619             : static long
    2620        3318 : ifac_insert_multiplet(GEN *partial, GEN *where, GEN facvec, long moebius_mode)
    2621             : {
    2622        3318 :   long j,k=1, lfv=lg(facvec)-1, nf=lfv/3, room=(long)(*where-*partial);
    2623             :   /* one of the factors will go into the *where slot, so room is now 3 times
    2624             :    * the number of slots we can use */
    2625        3318 :   long needroom = lfv - room;
    2626        3318 :   GEN newexp, cur, sorted, auxvec = cgetg(nf+1, t_VEC), factor;
    2627        3318 :   long E = itos(EXPON(*where)); /* the old exponent */
    2628             : 
    2629        3318 :   if (DEBUGLEVEL >= 5) /* squfof may return a single squared factor as a set */
    2630           0 :     err_printf("IFAC: incorporating set of %ld factor(s)\n", nf);
    2631        3318 :   if (needroom > 0) ifac_realloc(partial, where, lg(*partial) + needroom);
    2632             : 
    2633             :   /* create sort permutation from the values of the factors */
    2634       10305 :   for (j=nf; j; j--) gel(auxvec,j) = gel(facvec,3*j-2);
    2635        3318 :   sorted = ZV_indexsort(auxvec);
    2636             :   /* store factors, beginning at *where, and catching any duplicates */
    2637        3318 :   cur = facvec + 3*sorted[nf]-2; /* adjust for triple spacing */
    2638        3318 :   VALUE(*where) = VALUE(cur);
    2639        3318 :   newexp = EXPON(cur);
    2640             :   /* if new exponent is 1, the old exponent already in place will do */
    2641        3318 :   if (newexp != gen_1) EXPON(*where) = mului(E,newexp);
    2642        3318 :   CLASS(*where) = CLASS(cur);
    2643        3318 :   if (DEBUGLEVEL >= 6) err_printf("\tstored (largest) factor no. %ld...\n", nf);
    2644             : 
    2645        6987 :   for (j=nf-1; j; j--)
    2646             :   {
    2647             :     GEN e;
    2648        3669 :     cur = facvec + 3*sorted[j]-2;
    2649        3669 :     factor = VALUE(cur);
    2650        3669 :     if (equalii(factor, VALUE(*where)))
    2651             :     {
    2652           0 :       if (DEBUGLEVEL >= 6)
    2653           0 :         err_printf("\tfactor no. %ld is a duplicate%s\n", j, (j>1? "...": ""));
    2654             :       /* update exponent, ignore class which would already have been set,
    2655             :        * then forget current factor */
    2656           0 :       newexp = EXPON(cur);
    2657           0 :       if (newexp != gen_1) /* new exp > 1 */
    2658           0 :         e = addiu(EXPON(*where), E * itou(newexp));
    2659           0 :       else if (EXPON(*where) == gen_1 && E == 1)
    2660           0 :         e = gen_2;
    2661             :       else
    2662           0 :         e = addiu(EXPON(*where), E);
    2663           0 :       EXPON(*where) = e;
    2664             : 
    2665           0 :       if (moebius_mode) return 0; /* stop now, with exponent updated */
    2666           0 :       continue;
    2667             :     }
    2668             : 
    2669        3669 :     *where -= 3;
    2670        3669 :     CLASS(*where) = CLASS(cur); /* class as given */
    2671        3669 :     newexp = EXPON(cur);
    2672        3669 :     if (newexp != gen_1) /* new exp > 1 */
    2673         147 :       e = (E == 1 && newexp == gen_2)? gen_2: mului(E, newexp);
    2674             :     else /* inherit parent's exponent */
    2675        3522 :       e = (E == 1 ? gen_1 : (E == 2 ? gen_2 : utoipos(E)));
    2676        3669 :     EXPON(*where) = e;
    2677             :     /* keep components younger than *partial */
    2678        3669 :     icopyifstack(factor, VALUE(*where));
    2679        3669 :     k++;
    2680        3669 :     if (DEBUGLEVEL >= 6)
    2681           0 :       err_printf("\tfactor no. %ld was unique%s\n", j, j>1? " (so far)...": "");
    2682             :   }
    2683        3318 :   return k;
    2684             : }
    2685             : 
    2686             : /* Split the first (composite) entry.  There _must_ already be room for another
    2687             :  * factor below *where, and *where is updated. Two cases:
    2688             :  * - entry = factor^k is a pure power: factor^k is inserted, leaving *where
    2689             :  *   unchanged;
    2690             :  * - entry = factor * cofactor (not necessarily coprime): both factors are
    2691             :  *   inserted in the correct order, updating *where
    2692             :  * The inserted factors class is set to unknown, they inherit the exponent
    2693             :  * (or a multiple thereof) of their ancestor.
    2694             :  *
    2695             :  * Returns number of factors written into the structure, normally 2 (1 if pure
    2696             :  * power, maybe > 2 if a factoring engine returned a vector of factors instead
    2697             :  * of a single factor). Can reallocate the data structure in the
    2698             :  * vector-of-factors case, not in the most common single-factor case.
    2699             :  * Stack housekeeping:  this routine may create one or more objects  (a new
    2700             :  * factor, or possibly several, and perhaps one or more new exponents > 2) */
    2701             : static long
    2702        5965 : ifac_crack(GEN *partial, GEN *where, long moebius_mode)
    2703             : {
    2704        5965 :   long cmp_res, hint = get_hint(partial);
    2705             :   GEN factor, exponent;
    2706             : 
    2707             : #ifdef IFAC_DEBUG
    2708             :   ifac_check(*partial, *where);
    2709             :   if (*where < *partial + 6)
    2710             :     pari_err_BUG("ifac_crack ['*where' out of bounds]");
    2711             :   if (!(VALUE(*where)) || typ(VALUE(*where)) != t_INT)
    2712             :     pari_err_BUG("ifac_crack [incorrect VALUE(*where)]");
    2713             :   if (CLASS(*where) != gen_0)
    2714             :     pari_err_BUG("ifac_crack [operand not known composite]");
    2715             : #endif
    2716             : 
    2717        5965 :   if (DEBUGLEVEL>2) {
    2718           0 :     err_printf("IFAC: cracking composite\n\t%Ps\n", **where);
    2719           0 :     if (DEBUGLEVEL>3) err_printf("IFAC: checking for pure square\n");
    2720             :   }
    2721             :   /* MPQS cannot factor prime powers. Look for pure powers even if MPQS is
    2722             :    * blocked by hint: fast and useful in bounded factorization */
    2723             :   {
    2724             :     forprime_t T;
    2725        5965 :     ulong exp = 1, mask = 7;
    2726        5965 :     long good = 0;
    2727        5965 :     pari_sp av = avma;
    2728        5965 :     (void)u_forprime_init(&T, 11, ULONG_MAX);
    2729             :     /* crack squares */
    2730        6860 :     while (Z_issquareall(VALUE(*where), &factor))
    2731             :     {
    2732         902 :       good = 1; /* remember we succeeded once */
    2733         902 :       update_pow(*where, factor, 2, &av);
    2734        1553 :       if (moebius_mode) return 0; /* no need to carry on */
    2735             :     }
    2736        6000 :     while ( (exp = is_357_power(VALUE(*where), &factor, &mask)) )
    2737             :     {
    2738          42 :       good = 1; /* remember we succeeded once */
    2739          42 :       update_pow(*where, factor, exp, &av);
    2740          42 :       if (moebius_mode) return 0; /* no need to carry on */
    2741             :     }
    2742             :     /* cutoff at 14 bits: OK if tridiv_bound >= 2^14 OR if >= 661 for
    2743             :      * an integer < 701^11 (103 bits). */
    2744        5958 :     while ( (exp = is_pth_power(VALUE(*where), &factor, &T, 15)) )
    2745             :     {
    2746           0 :       good = 1; /* remember we succeeded once */
    2747           0 :       update_pow(*where, factor, exp, &av);
    2748           0 :       if (moebius_mode) return 0; /* no need to carry on */
    2749             :     }
    2750             : 
    2751        5958 :     if (good && hint != 15 && ifac_checkprime(*where))
    2752             :     { /* our composite was a prime power */
    2753         651 :       if (DEBUGLEVEL>3)
    2754           0 :         err_printf("IFAC: factor %Ps\n\tis prime\n", VALUE(*where));
    2755         651 :       return 0; /* bypass subsequent ifac_whoiswho() call */
    2756             :     }
    2757             :   } /* pure power stage */
    2758             : 
    2759        5307 :   factor = NULL;
    2760        5307 :   if (!(hint & 4))
    2761             :   { /* pollardbrent() Rho usually gets a first chance */
    2762        5258 :     if (DEBUGLEVEL >= 4) err_printf("IFAC: trying Pollard-Brent rho method\n");
    2763        5258 :     factor = pollardbrent(VALUE(*where));
    2764        5258 :     if (!factor)
    2765             :     { /* Shanks' squfof() */
    2766        4974 :       if (DEBUGLEVEL >= 4)
    2767           0 :         err_printf("IFAC: trying Shanks' SQUFOF, will fail silently if input\n"
    2768             :                    "      is too large for it.\n");
    2769        4974 :       factor = squfof(VALUE(*where));
    2770             :     }
    2771             :   }
    2772        5307 :   if (!factor && !(hint & 2))
    2773             :   { /* First ECM stage */
    2774        3273 :     if (DEBUGLEVEL >= 4) err_printf("IFAC: trying Lenstra-Montgomery ECM\n");
    2775        3273 :     factor = ellfacteur(VALUE(*where), 0); /* do not insist */
    2776             :   }
    2777        5307 :   if (!factor && !(hint & 1))
    2778             :   { /* MPQS stage */
    2779        3297 :     if (DEBUGLEVEL >= 4) err_printf("IFAC: trying MPQS\n");
    2780        3297 :     factor = mpqs(VALUE(*where));
    2781             :   }
    2782        5307 :   if (!factor)
    2783             :   {
    2784          15 :     if (!(hint & 8))
    2785             :     { /* still no luck? Final ECM stage, guaranteed to succeed */
    2786           8 :       if (DEBUGLEVEL >= 4)
    2787           0 :         err_printf("IFAC: forcing ECM, may take some time\n");
    2788           8 :       factor = ellfacteur(VALUE(*where), 1);
    2789             :     }
    2790             :     else
    2791             :     { /* limited factorization */
    2792           7 :       if (DEBUGLEVEL >= 2)
    2793             :       {
    2794           0 :         if (hint != 15)
    2795           0 :           pari_warn(warner, "IFAC: unfactored composite declared prime");
    2796             :         else
    2797           0 :           pari_warn(warner, "IFAC: untested integer declared prime");
    2798             : 
    2799             :         /* don't print it out at level 3 or above, where it would appear
    2800             :          * several times before and after this message already */
    2801           0 :         if (DEBUGLEVEL == 2) err_printf("\t%Ps\n", VALUE(*where));
    2802             :       }
    2803           7 :       CLASS(*where) = gen_1; /* might as well trial-divide by it... */
    2804           7 :       return 1;
    2805             :     }
    2806             :   }
    2807        5300 :   if (typ(factor) == t_VEC) /* delegate this case */
    2808        3318 :     return ifac_insert_multiplet(partial, where, factor, moebius_mode);
    2809             :   /* typ(factor) == t_INT */
    2810             :   /* got single integer back:  work out the cofactor (in place) */
    2811        1982 :   if (!dvdiiz(VALUE(*where), factor, VALUE(*where)))
    2812             :   {
    2813           0 :     err_printf("IFAC: factoring %Ps\n", VALUE(*where));
    2814           0 :     err_printf("\tyielded 'factor' %Ps\n\twhich isn't!\n", factor);
    2815           0 :     pari_err_BUG("factoring");
    2816             :   }
    2817             :   /* factoring engines report the factor found; tell about the cofactor */
    2818        1982 :   if (DEBUGLEVEL >= 4) err_printf("IFAC: cofactor = %Ps\n", VALUE(*where));
    2819             : 
    2820             :   /* The two factors are 'factor' and VALUE(*where), find out which is larger */
    2821        1982 :   cmp_res = cmpii(factor, VALUE(*where));
    2822        1982 :   CLASS(*where) = NULL; /* mark factor /cofactor 'unknown' */
    2823        1982 :   exponent = EXPON(*where);
    2824        1982 :   *where -= 3;
    2825        1982 :   CLASS(*where) = NULL; /* mark factor /cofactor 'unknown' */
    2826        1982 :   icopyifstack(exponent, EXPON(*where));
    2827        1982 :   if (cmp_res < 0)
    2828        1773 :     VALUE(*where) = factor; /* common case */
    2829         209 :   else if (cmp_res > 0)
    2830             :   { /* factor > cofactor, rearrange */
    2831         209 :     GEN old = *where + 3;
    2832         209 :     VALUE(*where) = VALUE(old); /* move cofactor pointer to lowest slot */
    2833         209 :     VALUE(old) = factor; /* save factor */
    2834             :   }
    2835           0 :   else pari_err_BUG("ifac_crack [Z_issquareall miss]");
    2836        1982 :   return 2;
    2837             : }
    2838             : 
    2839             : /* main loop:  iterate until smallest entry is a finished prime;  returns
    2840             :  * a 'where' pointer, or NULL if nothing left, or gen_0 in Moebius mode if
    2841             :  * we aren't squarefree */
    2842             : static GEN
    2843       14847 : ifac_main(GEN *partial)
    2844             : {
    2845       14847 :   const long moebius_mode = !!MOEBIUS(*partial);
    2846       14847 :   GEN here = ifac_find(*partial);
    2847             :   long nf;
    2848             : 
    2849       14847 :   if (!here) return NULL; /* nothing left */
    2850             :   /* loop until first entry is a finished prime.  May involve reallocations,
    2851             :    * thus updates of *partial */
    2852       26457 :   while (CLASS(here) != gen_2)
    2853             :   {
    2854       16211 :     if (CLASS(here) == gen_0) /* composite: crack it */
    2855             :     { /* make sure there's room for another factor */
    2856        5965 :       if (here < *partial + 6)
    2857             :       {
    2858           0 :         ifac_defrag(partial, &here);
    2859           0 :         if (here < *partial + 6) ifac_realloc(partial, &here, 1); /* no luck */
    2860             :       }
    2861        5965 :       nf = ifac_crack(partial, &here, moebius_mode);
    2862        5965 :       if (moebius_mode && EXPON(here) != gen_1) /* that was a power */
    2863             :       {
    2864          14 :         if (DEBUGLEVEL >= 3)
    2865           0 :           err_printf("IFAC: main loop: repeated new factor\n\t%Ps\n", *here);
    2866          14 :         return gen_0;
    2867             :       }
    2868             :       /* deal with the new unknowns.  No sort: ifac_crack did it */
    2869        5951 :       ifac_whoiswho(partial, &here, nf);
    2870        5951 :       continue;
    2871             :     }
    2872       10246 :     if (CLASS(here) == gen_1) /* prime but not yet finished: finish it */
    2873             :     {
    2874       10246 :       if (ifac_divide(partial, &here, moebius_mode))
    2875             :       {
    2876           7 :         if (moebius_mode)
    2877             :         {
    2878           0 :           if (DEBUGLEVEL >= 3)
    2879           0 :             err_printf("IFAC: main loop: another factor was divisible by\n"
    2880             :                        "\t%Ps\n", *here);
    2881           0 :           return gen_0;
    2882             :         }
    2883           7 :         ifac_resort(partial, &here); /* sort new cofactors down */
    2884           7 :         ifac_whoiswho(partial, &here, -1);
    2885             :       }
    2886       10246 :       continue;
    2887             :     }
    2888           0 :     pari_err_BUG("ifac_main [nonexistent factor class]");
    2889             :   } /* while */
    2890       10246 :   if (moebius_mode && EXPON(here) != gen_1)
    2891             :   {
    2892           0 :     if (DEBUGLEVEL >= 3)
    2893           0 :       err_printf("IFAC: after main loop: repeated old factor\n\t%Ps\n", *here);
    2894           0 :     return gen_0;
    2895             :   }
    2896       10246 :   if (DEBUGLEVEL >= 4)
    2897             :   {
    2898           0 :     nf = (*partial + lg(*partial) - here - 3)/3;
    2899           0 :     if (nf)
    2900           0 :       err_printf("IFAC: main loop: %ld factor%s left\n", nf, (nf>1)? "s": "");
    2901             :     else
    2902           0 :       err_printf("IFAC: main loop: this was the last factor\n");
    2903             :   }
    2904       10246 :   if (factor_add_primes && !(get_hint(partial) & 8))
    2905             :   {
    2906           0 :     GEN p = VALUE(here);
    2907           0 :     if (lgefint(p)>3 || uel(p,2) > 0x1000000UL) (void)addprimes(p);
    2908             :   }
    2909       10246 :   return here;
    2910             : }
    2911             : 
    2912             : /* Encapsulated routines */
    2913             : 
    2914             : /* prime/exponent pairs need to appear contiguously on the stack, but we also
    2915             :  * need our data structure somewhere, and we don't know in advance how many
    2916             :  * primes will turn up.  The following discipline achieves this:  When
    2917             :  * ifac_decomp() is called, n should point at an object older than the oldest
    2918             :  * small prime/exponent pair  (ifactor() guarantees this).
    2919             :  * We allocate sufficient space to accommodate several pairs -- eleven pairs
    2920             :  * ought to fit in a space not much larger than n itself -- before calling
    2921             :  * ifac_start().  If we manage to complete the factorization before we run out
    2922             :  * of space, we free the data structure and cull the excess reserved space
    2923             :  * before returning.  When we do run out, we have to leapfrog to generate more
    2924             :  * (guesstimating the requirements from what is left in the partial
    2925             :  * factorization structure);  room for fresh pairs is allocated at the head of
    2926             :  * the stack, followed by an ifac_realloc() to reconnect the data structure and
    2927             :  * move it out of the way, followed by a few pointer tweaks to connect the new
    2928             :  * pairs space to the old one. This whole affair translates into a surprisingly
    2929             :  * compact routine. */
    2930             : 
    2931             : /* find primary factors of n; destroy n */
    2932             : static long
    2933        2634 : ifac_decomp(GEN n, long hint)
    2934             : {
    2935        2634 :   pari_sp av = avma;
    2936        2634 :   long nb = 0;
    2937        2634 :   GEN part, here, workspc, pairs = (GEN)av;
    2938             : 
    2939             :   /* workspc will be doled out in pairs of smaller t_INTs. For n = prod p^{e_p}
    2940             :    * (p not necessarily prime), need room to store all p and e_p [ cgeti(3) ],
    2941             :    * bounded by
    2942             :    *    sum_{p | n} ( log_{2^BIL} (p) + 6 ) <= log_{2^BIL} n + 6 log_2 n */
    2943        2634 :   workspc = new_chunk((expi(n) + 1) * 7);
    2944        2634 :   part = ifac_start_hint(n, 0, hint);
    2945             :   for (;;)
    2946             :   {
    2947        7753 :     here = ifac_main(&part);
    2948        7753 :     if (!here) break;
    2949        5119 :     if (gc_needed(av,1))
    2950             :     {
    2951             :       long offset;
    2952           0 :       if(DEBUGMEM>1)
    2953             :       {
    2954           0 :         pari_warn(warnmem,"[2] ifac_decomp");
    2955           0 :         ifac_print(part, here);
    2956             :       }
    2957           0 :       ifac_realloc(&part, &here, 0);
    2958           0 :       offset = here - part;
    2959           0 :       part = gerepileupto((pari_sp)workspc, part);
    2960           0 :       here = part + offset;
    2961             :     }
    2962        5119 :     nb++;
    2963        5119 :     pairs = icopy_avma(VALUE(here), (pari_sp)pairs);
    2964        5119 :     pairs = icopy_avma(EXPON(here), (pari_sp)pairs);
    2965        5119 :     ifac_delete(here);
    2966             :   }
    2967        2634 :   set_avma((pari_sp)pairs);
    2968        2634 :   if (DEBUGLEVEL >= 3)
    2969           0 :     err_printf("IFAC: found %ld large prime (power) factor%s.\n",
    2970             :                nb, (nb>1? "s": ""));
    2971        2634 :   return nb;
    2972             : }
    2973             : 
    2974             : /***********************************************************************/
    2975             : /**            ARITHMETIC FUNCTIONS WITH EARLY-ABORT                  **/
    2976             : /**  needing direct access to the factoring machinery to avoid work:  **/
    2977             : /**  e.g. if we find a square factor, moebius returns 0, core doesn't **/
    2978             : /**  need to factor it, etc.                                          **/
    2979             : /***********************************************************************/
    2980             : /* memory management */
    2981             : static void
    2982           0 : ifac_GC(pari_sp av, GEN *part)
    2983             : {
    2984           0 :   GEN here = NULL;
    2985           0 :   if(DEBUGMEM>1) pari_warn(warnmem,"ifac_xxx");
    2986           0 :   ifac_realloc(part, &here, 0);
    2987           0 :   *part = gerepileupto(av, *part);
    2988           0 : }
    2989             : 
    2990             : /* destroys n */
    2991             : static long
    2992         211 : ifac_moebius(GEN n)
    2993             : {
    2994         211 :   long mu = 1;
    2995         211 :   pari_sp av = avma;
    2996         211 :   GEN part = ifac_start(n, 1);
    2997             :   for(;;)
    2998         394 :   {
    2999             :     long v;
    3000             :     GEN p;
    3001         605 :     if (!ifac_next(&part,&p,&v)) return v? 0: mu;
    3002         394 :     mu = -mu;
    3003         394 :     if (gc_needed(av,1)) ifac_GC(av,&part);
    3004             :   }
    3005             : }
    3006             : 
    3007             : int
    3008         682 : ifac_read(GEN part, GEN *p, long *e)
    3009             : {
    3010         682 :   GEN here = ifac_find(part);
    3011         682 :   if (!here) return 0;
    3012         352 :   *p = VALUE(here);
    3013         352 :   *e = EXPON(here)[2];
    3014         352 :   return 1;
    3015             : }
    3016             : void
    3017         308 : ifac_skip(GEN part)
    3018             : {
    3019         308 :   GEN here = ifac_find(part);
    3020         308 :   if (here) ifac_delete(here);
    3021         308 : }
    3022             : 
    3023             : /* destroys n */
    3024             : static int
    3025           7 : ifac_ispowerful(GEN n)
    3026             : {
    3027           7 :   pari_sp av = avma;
    3028           7 :   GEN part = ifac_start(n, 0);
    3029             :   for(;;)
    3030           7 :   {
    3031             :     long e;
    3032             :     GEN p;
    3033          14 :     if (!ifac_read(part,&p,&e)) return 1;
    3034             :     /* power: skip */
    3035           7 :     if (e != 1 || Z_isanypower(p,NULL)) { ifac_skip(part); continue; }
    3036           0 :     if (!ifac_next(&part,&p,&e)) return 1;
    3037           0 :     if (e == 1) return 0;
    3038           0 :     if (gc_needed(av,1)) ifac_GC(av,&part);
    3039             :   }
    3040             : }
    3041             : /* destroys n */
    3042             : static GEN
    3043         323 : ifac_core(GEN n)
    3044             : {
    3045         323 :   GEN m = gen_1, c = cgeti(lgefint(n));
    3046         323 :   pari_sp av = avma;
    3047         323 :   GEN part = ifac_start(n, 0);
    3048             :   for(;;)
    3049         345 :   {
    3050             :     long e;
    3051             :     GEN p;
    3052         668 :     if (!ifac_read(part,&p,&e)) return m;
    3053             :     /* square: skip */
    3054         345 :     if (!odd(e) || Z_issquare(p)) { ifac_skip(part); continue; }
    3055          44 :     if (!ifac_next(&part,&p,&e)) return m;
    3056          44 :     if (odd(e)) m = mulii(m, p);
    3057          44 :     if (gc_needed(av,1)) { affii(m,c); m=c; ifac_GC(av,&part); }
    3058             :   }
    3059             : }
    3060             : 
    3061             : /* must be >= 661 (various functions assume it in order to call uisprime_661
    3062             :  * instead of uisprime, and Z_isanypower_nosmalldiv instead of Z_isanypower) */
    3063             : ulong
    3064    11832749 : tridiv_boundu(ulong n)
    3065             : {
    3066    11832749 :   long e = expu(n);
    3067    11831319 :   if(e<30) return 1UL<<12;
    3068             : #ifdef LONG_IS_64BIT
    3069      403570 :   if(e<34) return 1UL<<13;
    3070      241329 :   if(e<37) return 1UL<<14;
    3071      146707 :   if(e<42) return 1UL<<15;
    3072       61504 :   if(e<47) return 1UL<<16;
    3073       33628 :   if(e<56) return 1UL<<17;
    3074        8516 :   if(e<56) return 1UL<<18;
    3075        8516 :   if(e<62) return 1UL<<19;
    3076        1801 :   return 1UL<<18;
    3077             : #else
    3078       14354 :   return 1UL<<13;
    3079             : #endif
    3080             : }
    3081             : 
    3082             : /* Where to stop trial dividing in factorization. Must be >= 661.
    3083             :  * If further n > 2^512, must be >= 2^14 */
    3084             : ulong
    3085      882044 : tridiv_bound(GEN n)
    3086             : {
    3087      882044 :   if (lgefint(n)==3) return tridiv_boundu(n[2]);
    3088             :   else
    3089             :   {
    3090       88517 :     ulong l = (ulong)expi(n) + 1;
    3091       88518 :     if (l <= 512) return (l-16) << 10;
    3092        1196 :     return 1UL<<19; /* Rho is generally faster above this */
    3093             :   }
    3094             : }
    3095             : 
    3096             : /* destroys n */
    3097             : static void
    3098         988 : ifac_factoru(GEN n, long hint, GEN P, GEN E, long *pi)
    3099             : {
    3100         988 :   GEN part = ifac_start_hint(n, 0, hint);
    3101             :   for(;;)
    3102        1892 :   {
    3103             :     long v;
    3104             :     GEN p;
    3105        2880 :     if (!ifac_next(&part,&p,&v)) return;
    3106        1892 :     P[*pi] = itou(p);
    3107        1892 :     E[*pi] = v;
    3108        1892 :     (*pi)++;
    3109             :   }
    3110             : }
    3111             : /* destroys n */
    3112             : static long
    3113         684 : ifac_moebiusu(GEN n)
    3114             : {
    3115         684 :   GEN part = ifac_start(n, 1);
    3116         684 :   long s = 1;
    3117             :   for(;;)
    3118        1368 :   {
    3119             :     long v;
    3120             :     GEN p;
    3121        2052 :     if (!ifac_next(&part,&p,&v)) return v? 0: s;
    3122        1368 :     s = -s;
    3123             :   }
    3124             : }
    3125             : 
    3126             : INLINE ulong
    3127   198428874 : u_forprime_next_fast(forprime_t *T)
    3128             : {
    3129   198428874 :   if (++T->n <= pari_PRIMES[0])
    3130             :   {
    3131   198428608 :     T->p = pari_PRIMES[T->n];
    3132   198428608 :     return T->p > T->b ? 0: T->p;
    3133             :   }
    3134         266 :   return u_forprime_next(T);
    3135             : }
    3136             : 
    3137             : /* uisprime(n) knowing n has no prime divisor <= lim */
    3138             : static int
    3139       18763 : uisprime_nosmall(ulong n, ulong lim)
    3140       18763 : { return (lim >= 661)? uisprime_661(n): uisprime(n); }
    3141             : 
    3142             : /* Factor n and output [p,e] where
    3143             :  * p, e are vecsmall with n = prod{p[i]^e[i]}. If all != 0:
    3144             :  * if pU1 is not NULL, set *pU1 and *pU2 so that unfactored composite is
    3145             :  * U1^U2 with U1 not a pure power; else include it in factorization */
    3146             : static GEN
    3147    20337517 : factoru_sign(ulong n, ulong all, long hint, ulong *pU1, ulong *pU2)
    3148             : {
    3149             :   GEN f, E, E2, P, P2;
    3150             :   pari_sp av;
    3151    20337517 :   ulong p, lim = 0;
    3152    20337517 :   long i, oldi = -1;
    3153             :   forprime_t S;
    3154             : 
    3155    20337517 :   if (pU1) *pU1 = *pU2 = 1;
    3156    20337517 :   if (n == 0) retmkvec2(mkvecsmall(0), mkvecsmall(1));
    3157    20337517 :   if (n == 1) retmkvec2(cgetg(1,t_VECSMALL), cgetg(1,t_VECSMALL));
    3158             : 
    3159    19887417 :   f = cgetg(3,t_VEC); av = avma;
    3160             :   /* enough room to store <= 15 primes and exponents (OK if n < 2^64) */
    3161    19887380 :   (void)new_chunk(16*2);
    3162    19887159 :   P = cgetg(16, t_VECSMALL); i = 1;
    3163    19886661 :   E = cgetg(16, t_VECSMALL);
    3164    19886446 :   if (!all || all > 2)
    3165             :   {
    3166             :     ulong maxp;
    3167    19886371 :     long v = vals(n);
    3168    19886510 :     if (v)
    3169             :     {
    3170    11641772 :       P[1] = 2; E[1] = v; i = 2;
    3171    11641772 :       n >>= v; if (n == 1) goto END;
    3172             :     }
    3173    16758752 :     maxp = maxprime();
    3174    16759291 :     if (n <= maxp && PRIMES_search(n) > 0) { P[i] = n; E[i] = 1; i++; goto END; }
    3175    10320135 :     lim = minss(usqrt(n), all? all-1: tridiv_boundu(n));
    3176    10320068 :     if (!(hint & 16) && lim >= 128) /* expu(lim) >= 7 */
    3177       18762 :     { /* fast trial division */
    3178     2564337 :       GEN PR = prodprimes();
    3179     2564336 :       long nPR = lg(PR)-1, b = minss(nPR, expu(lim)-6);
    3180     2564333 :       ulong nr = ugcd(n, umodiu(gel(PR,b), n));
    3181     2564342 :       if (nr != 1)
    3182             :       {
    3183     2557893 :         GEN F = factoru_sign(nr, all, 1 + 2 + 16, NULL, NULL), Q = gel(F,1);
    3184     2557889 :         long j, l = lg(Q);
    3185     8346009 :         for (j = 1; j < l; j++)
    3186             :         {
    3187     5788124 :           ulong p = uel(Q,j);
    3188     5788124 :           if (all && p >= all) break; /* may occur for last p */
    3189     5788118 :           E[i] = u_lvalrem(n, p, &n); /* > 0 */
    3190     5788120 :           P[i] = p; i++;
    3191             :         }
    3192     2557891 :         if (n == 1) goto END;
    3193      783570 :         if (n <= maxp
    3194      771257 :             && PRIMES_search(n) > 0) { P[i] = n; E[i] = 1; i++; goto END; }
    3195             :       }
    3196       18762 :       maxp = GP_DATA->factorlimit;
    3197             :     }
    3198             :     else
    3199             :     {
    3200     7755731 :       maxp = lim;
    3201     7755731 :       u_forprime_init(&S, 3, lim);
    3202    67640737 :       while ( (p = u_forprime_next_fast(&S)) )
    3203             :       {
    3204             :         int stop;
    3205             :         /* tiny integers without small factors are often primes */
    3206    67640362 :         if (p == 673)
    3207             :         {
    3208     7808222 :           if (uisprime_661(n)) { P[i] = n; E[i] = 1; i++; goto END; }
    3209       52837 :           oldi = i;
    3210             :         }
    3211    67640016 :         v = u_lvalrem_stop(&n, p, &stop);
    3212    67640134 :         if (v) {
    3213    10547966 :           P[i] = p;
    3214    10547966 :           E[i] = v; i++;
    3215             :         }
    3216    67640134 :         if (stop) {
    3217     7755039 :           if (n != 1) { P[i] = n; E[i] = 1; i++; }
    3218     7755039 :           goto END;
    3219             :         }
    3220             :       }
    3221             :     }
    3222       19270 :     if (lim > maxp)
    3223             :     { /* second pass usually empty, outside fast trial division range */
    3224             :       long v;
    3225           6 :       u_forprime_init(&S, maxp+1, lim);
    3226     5296866 :       while ((p = u_forprime_next(&S)))
    3227             :       {
    3228             :         int stop;
    3229     5296866 :         v = u_lvalrem_stop(&n, p, &stop);
    3230     5296866 :         if (v) {
    3231           6 :           P[i] = p;
    3232           6 :           E[i] = v; i++;
    3233             :         }
    3234     5296866 :         if (stop) {
    3235           6 :           if (n != 1) { P[i] = n; E[i] = 1; i++; }
    3236           6 :           goto END;
    3237             :         }
    3238             :       }
    3239             :     }
    3240             :   }
    3241             :   /* if i > oldi (includes oldi = -1) we don't know that n is composite */
    3242       19339 :   if (all)
    3243             :   { /* smallfact: look for easy pure powers then stop */
    3244             : #ifdef LONG_IS_64BIT
    3245        1206 :     ulong mask = all > 563 ? (all > 7129 ? 1: 3): 7;
    3246             : #else
    3247          25 :     ulong mask = all > 22 ? (all > 83 ? 1: 3): 7;
    3248             : #endif
    3249        1231 :     long k = 1, ex;
    3250        1724 :     while (uissquareall(n, &n)) k <<= 1;
    3251        1244 :     while ( (ex = uis_357_power(n, &n, &mask)) ) k *= ex;
    3252        1231 :     if (pU1 && (i == oldi || !uisprime_nosmall(n, lim)))
    3253         254 :     { *pU1 = n; *pU2 = (ulong)k; }
    3254             :     else
    3255         977 :     { P[i] = n; E[i] = k; i++; }
    3256        1231 :     goto END;
    3257             :   }
    3258             :   /* we don't known that n is composite ? */
    3259       18108 :   if (oldi != i && uisprime_nosmall(n, lim)) { P[i]=n; E[i]=1; i++; goto END; }
    3260             : 
    3261             :   {
    3262             :     GEN perm;
    3263         988 :     ifac_factoru(utoipos(n), hint, P, E, &i);
    3264         988 :     setlg(P, i);
    3265         988 :     perm = vecsmall_indexsort(P);
    3266         988 :     P = vecsmallpermute(P, perm);
    3267         988 :     E = vecsmallpermute(E, perm);
    3268             :   }
    3269    19888331 : END:
    3270    19888331 :   set_avma(av);
    3271    19887755 :   P2 = cgetg(i, t_VECSMALL); gel(f,1) = P2;
    3272    19887458 :   E2 = cgetg(i, t_VECSMALL); gel(f,2) = E2;
    3273    61383692 :   while (--i >= 1) { P2[i] = P[i]; E2[i] = E[i]; }
    3274    19887049 :   return f;
    3275             : }
    3276             : GEN
    3277     3803401 : factoru(ulong n)
    3278     3803401 : { return factoru_sign(n, 0, decomp_default_hint, NULL, NULL); }
    3279             : 
    3280             : ulong
    3281           0 : radicalu(ulong n)
    3282             : {
    3283           0 :   pari_sp av = avma;
    3284           0 :   return gc_long(av, zv_prod(gel(factoru(n),1)));
    3285             : }
    3286             : 
    3287             : long
    3288       54194 : moebiusu_fact(GEN f)
    3289             : {
    3290       54194 :   GEN E = gel(f,2);
    3291       54194 :   long i, l = lg(E);
    3292       93569 :   for (i = 1; i < l; i++)
    3293       57834 :     if (E[i] > 1) return 0;
    3294       35735 :   return odd(l)? 1: -1;
    3295             : }
    3296             : 
    3297             : long
    3298     2515041 : moebiusu(ulong n)
    3299             : {
    3300             :   pari_sp av;
    3301             :   ulong p;
    3302             :   long s, v, test_prime;
    3303             :   forprime_t S;
    3304             : 
    3305     2515041 :   switch(n)
    3306             :   {
    3307           0 :     case 0: (void)check_arith_non0(gen_0,"moebius");/*error*/
    3308      571777 :     case 1: return  1;
    3309      106809 :     case 2: return -1;
    3310             :   }
    3311     1850834 :   v = vals(n);
    3312     1849212 :   if (v == 0)
    3313     1737027 :     s = 1;
    3314             :   else
    3315             :   {
    3316      112185 :     if (v > 1) return 0;
    3317       23772 :     n >>= 1;
    3318       23772 :     s = -1;
    3319             :   }
    3320     1760799 :   av = avma;
    3321     1760799 :   u_forprime_init(&S, 3, tridiv_boundu(n));
    3322     1768548 :   test_prime = 0;
    3323    40544809 :   while ((p = u_forprime_next_fast(&S)))
    3324             :   {
    3325             :     int stop;
    3326             :     /* tiny integers without small factors are often primes */
    3327    40548051 :     if (p == 673)
    3328             :     {
    3329        3752 :       test_prime = 0;
    3330     1773874 :       if (uisprime_661(n)) return gc_long(av,-s);
    3331             :     }
    3332    40546603 :     v = u_lvalrem_stop(&n, p, &stop);
    3333    40543237 :     if (v) {
    3334     1319597 :       if (v > 1) return gc_long(av,0);
    3335     1137948 :       test_prime = 1;
    3336     1137948 :       s = -s;
    3337             :     }
    3338    40361588 :     if (stop) return gc_long(av, n==1? s: -s);
    3339             :   }
    3340         940 :   set_avma(av);
    3341        1020 :   if (test_prime && uisprime_661(n)) return -s;
    3342             :   else
    3343             :   {
    3344         684 :     long t = ifac_moebiusu(utoipos(n));
    3345         684 :     set_avma(av);
    3346         684 :     if (t == 0) return 0;
    3347         684 :     return (s == t)? 1: -1;
    3348             :   }
    3349             : }
    3350             : 
    3351             : long
    3352       55982 : moebius(GEN n)
    3353             : {
    3354       55982 :   pari_sp av = avma;
    3355             :   GEN F;
    3356             :   ulong p;
    3357             :   long i, l, s, v;
    3358             :   forprime_t S;
    3359             : 
    3360       55982 :   if ((F = check_arith_non0(n,"moebius")))
    3361             :   {
    3362             :     GEN E;
    3363         730 :     F = clean_Z_factor(F);
    3364         728 :     E = gel(F,2);
    3365         728 :     l = lg(E);
    3366        1428 :     for(i = 1; i < l; i++)
    3367         980 :       if (!equali1(gel(E,i))) return gc_long(av,0);
    3368         448 :     return gc_long(av, odd(l)? 1: -1);
    3369             :   }
    3370       55167 :   if (lgefint(n) == 3) return moebiusu(uel(n,2));
    3371         808 :   p = mod4(n); if (!p) return 0;
    3372         808 :   if (p == 2) { s = -1; n = shifti(n, -1); } else { s = 1; n = icopy(n); }
    3373         808 :   setabssign(n);
    3374             : 
    3375         808 :   u_forprime_init(&S, 3, tridiv_bound(n));
    3376     2322026 :   while ((p = u_forprime_next_fast(&S)))
    3377             :   {
    3378             :     int stop;
    3379     2321446 :     v = Z_lvalrem_stop(&n, p, &stop);
    3380     2321446 :     if (v)
    3381             :     {
    3382        1540 :       if (v > 1) return gc_long(av,0);
    3383        1312 :       s = -s;
    3384        1312 :       if (stop) return gc_long(av, is_pm1(n)? s: -s);
    3385             :     }
    3386             :   }
    3387         580 :   l = lg(primetab);
    3388         590 :   for (i = 1; i < l; i++)
    3389             :   {
    3390          25 :     v = Z_pvalrem(n, gel(primetab,i), &n);
    3391          25 :     if (v)
    3392             :     {
    3393          25 :       if (v > 1) return gc_long(av,0);
    3394          11 :       s = -s;
    3395          11 :       if (is_pm1(n)) return gc_long(av,s);
    3396             :     }
    3397             :   }
    3398         565 :   if (ifac_isprime(n)) return gc_long(av,-s);
    3399             :   /* large composite without small factors */
    3400         211 :   v = ifac_moebius(n);
    3401         211 :   return gc_long(av, s < 0? -v: v); /* correct also if v==0 */
    3402             : }
    3403             : 
    3404             : long
    3405        1708 : ispowerful(GEN n)
    3406             : {
    3407        1708 :   pari_sp av = avma;
    3408             :   GEN F;
    3409             :   ulong p, bound;
    3410             :   long i, l, v;
    3411             :   forprime_t S;
    3412             : 
    3413        1708 :   if ((F = check_arith_all(n, "ispowerful")))
    3414             :   {
    3415         742 :     GEN p, P = gel(F,1), E = gel(F,2);
    3416         742 :     if (lg(P) == 1) return 1; /* 1 */
    3417         728 :     p = gel(P,1);
    3418         728 :     if (!signe(p)) return 1; /* 0 */
    3419         707 :     i = is_pm1(p)? 2: 1; /* skip -1 */
    3420         707 :     l = lg(E);
    3421         980 :     for (; i < l; i++)
    3422         847 :       if (equali1(gel(E,i))) return 0;
    3423         133 :     return 1;
    3424             :   }
    3425         966 :   if (!signe(n)) return 1;
    3426             : 
    3427         952 :   if (mod4(n) == 2) return 0;
    3428         623 :   n = shifti(n, -vali(n));
    3429         623 :   if (is_pm1(n)) return 1;
    3430         546 :   setabssign(n);
    3431         546 :   bound = tridiv_bound(n);
    3432         546 :   u_forprime_init(&S, 3, bound);
    3433      307797 :   while ((p = u_forprime_next_fast(&S)))
    3434             :   {
    3435             :     int stop;
    3436      307790 :     v = Z_lvalrem_stop(&n, p, &stop);
    3437      307790 :     if (v)
    3438             :     {
    3439         742 :       if (v == 1) return gc_long(av,0);
    3440         203 :       if (stop) return gc_long(av, is_pm1(n));
    3441             :     }
    3442             :   }
    3443           7 :   l = lg(primetab);
    3444           7 :   for (i = 1; i < l; i++)
    3445             :   {
    3446           0 :     v = Z_pvalrem(n, gel(primetab,i), &n);
    3447           0 :     if (v)
    3448             :     {
    3449           0 :       if (v == 1) return gc_long(av,0);
    3450           0 :       if (is_pm1(n)) return gc_long(av,1);
    3451             :     }
    3452             :   }
    3453             :   /* no need to factor: must be p^2 or not powerful */
    3454           7 :   if (cmpii(powuu(bound+1, 3), n) > 0) return gc_long(av,  Z_issquare(n));
    3455             : 
    3456           7 :   if (ifac_isprime(n)) return gc_long(av,0);
    3457             :   /* large composite without small factors */
    3458           7 :   return gc_long(av, ifac_ispowerful(n));
    3459             : }
    3460             : 
    3461             : ulong
    3462       62031 : coreu_fact(GEN f)
    3463             : {
    3464       62031 :   GEN P = gel(f,1), E = gel(f,2);
    3465       62031 :   long i, l = lg(P), m = 1;
    3466      112281 :   for (i = 1; i < l; i++)
    3467             :   {
    3468       50250 :     ulong p = P[i], e = E[i];
    3469       50250 :     if (e & 1) m *= p;
    3470             :   }
    3471       62031 :   return m;
    3472             : }
    3473             : ulong
    3474       62031 : coreu(ulong n)
    3475             : {
    3476             :   pari_sp av;
    3477       62031 :   if (n == 0) return 0;
    3478       62031 :   av = avma; return gc_ulong(av, coreu_fact(factoru(n)));
    3479             : }
    3480             : GEN
    3481      708662 : core(GEN n)
    3482             : {
    3483      708662 :   pari_sp av = avma;
    3484             :   GEN m, F;
    3485             :   ulong p;
    3486             :   long i, l, v;
    3487             :   forprime_t S;
    3488             : 
    3489      708662 :   if ((F = check_arith_all(n, "core")))
    3490             :   {
    3491      646242 :     GEN p, x, P = gel(F,1), E = gel(F,2);
    3492      646242 :     long j = 1;
    3493      646242 :     if (lg(P) == 1) return gen_1;
    3494      646214 :     p = gel(P,1);
    3495      646214 :     if (!signe(p)) return gen_0;
    3496      646172 :     l = lg(P); x = cgetg(l, t_VEC);
    3497     2283026 :     for (i = 1; i < l; i++)
    3498     1636863 :       if (mpodd(gel(E,i))) gel(x,j++) = gel(P,i);
    3499      646163 :     setlg(x, j); return ZV_prod(x);
    3500             :   }
    3501       62411 :   switch(lgefint(n))
    3502             :   {
    3503          28 :     case 2: return gen_0;
    3504       61975 :     case 3:
    3505       61975 :       p = coreu(uel(n,2));
    3506       61975 :       return signe(n) > 0? utoipos(p): utoineg(p);
    3507             :   }
    3508             : 
    3509         408 :   m = signe(n) < 0? gen_m1: gen_1;
    3510         408 :   n = absi_shallow(n);
    3511         408 :   u_forprime_init(&S, 2, tridiv_bound(n));
    3512     5081673 :   while ((p = u_forprime_next_fast(&S)))
    3513             :   {
    3514             :     int stop;
    3515     5081332 :     v = Z_lvalrem_stop(&n, p, &stop);
    3516     5081332 :     if (v)
    3517             :     {
    3518        1577 :       if (v & 1) m = muliu(m, p);
    3519        1577 :       if (stop)
    3520             :       {
    3521          67 :         if (!is_pm1(n)) m = mulii(m, n);
    3522          67 :         return gerepileuptoint(av, m);
    3523             :       }
    3524             :     }
    3525             :   }
    3526         341 :   l = lg(primetab);
    3527         835 :   for (i = 1; i < l; i++)
    3528             :   {
    3529         502 :     GEN q = gel(primetab,i);
    3530         502 :     v = Z_pvalrem(n, q, &n);
    3531         502 :     if (v)
    3532             :     {
    3533          32 :       if (v & 1) m = mulii(m, q);
    3534          32 :       if (is_pm1(n)) return gerepileuptoint(av, m);
    3535             :     }
    3536             :   }
    3537         333 :   if (ifac_isprime(n)) { m = mulii(m, n); return gerepileuptoint(av, m); }
    3538         323 :   if (m == gen_1) n = icopy(n); /* ifac_core destroys n */
    3539             :   /* large composite without small factors */
    3540         323 :   return gerepileuptoint(av, mulii(m, ifac_core(n)));
    3541             : }
    3542             : 
    3543             : long
    3544           0 : Z_issmooth(GEN m, ulong lim)
    3545             : {
    3546           0 :   pari_sp av = avma;
    3547           0 :   ulong p = 2;
    3548             :   forprime_t S;
    3549           0 :   u_forprime_init(&S, 2, lim);
    3550           0 :   while ((p = u_forprime_next_fast(&S)))
    3551             :   {
    3552             :     int stop;
    3553           0 :     (void)Z_lvalrem_stop(&m, p, &stop);
    3554           0 :     if (stop) return gc_long(av, abscmpiu(m,lim) <= 0);
    3555             :   }
    3556           0 :   return gc_long(av,0);
    3557             : }
    3558             : 
    3559             : GEN
    3560      178865 : Z_issmooth_fact(GEN m, ulong lim)
    3561             : {
    3562      178865 :   pari_sp av = avma;
    3563             :   GEN F, P, E;
    3564             :   ulong p;
    3565      178865 :   long i = 1, l = expi(m)+1;
    3566             :   forprime_t S;
    3567      178860 :   P = cgetg(l, t_VECSMALL);
    3568      178828 :   E = cgetg(l, t_VECSMALL); F = mkmat2(P,E);
    3569      178768 :   if (l == 1) return F; /* m == 1 */
    3570      178726 :   u_forprime_init(&S, 2, lim);
    3571    47578126 :   while ((p = u_forprime_next_fast(&S)))
    3572             :   {
    3573             :     long v;
    3574             :     int stop;
    3575    47524175 :     if ((v = Z_lvalrem_stop(&m, p, &stop)))
    3576             :     {
    3577      654228 :       P[i] = p;
    3578      654228 :       E[i] = v; i++;
    3579      654228 :       if (stop)
    3580             :       {
    3581      124198 :         if (abscmpiu(m,lim) > 0) break;
    3582      111745 :         if (m[2] > 1) { P[i] = m[2]; E[i] = 1; i++; }
    3583      111745 :         setlg(P, i);
    3584      111789 :         setlg(E, i); return gc_const((pari_sp)F, F);
    3585             :       }
    3586             :     }
    3587             :   }
    3588       65689 :   return gc_NULL(av);
    3589             : }
    3590             : 
    3591             : /***********************************************************************/
    3592             : /**                                                                   **/
    3593             : /**       COMPUTING THE MATRIX OF PRIME DIVISORS AND EXPONENTS        **/
    3594             : /**                                                                   **/
    3595             : /***********************************************************************/
    3596             : static GEN
    3597      147333 : aux_end(GEN M, GEN n, long nb)
    3598             : {
    3599      147333 :   GEN P,E, z = (GEN)avma;
    3600             :   long i;
    3601             : 
    3602      147333 :   guncloneNULL(n);
    3603      147333 :   P = cgetg(nb+1,t_COL);
    3604      147333 :   E = cgetg(nb+1,t_COL);
    3605     1118573 :   for (i=nb; i; i--)
    3606             :   { /* allow a stackdummy in the middle */
    3607     1046427 :     while (typ(z) != t_INT) z += lg(z);
    3608      971240 :     gel(E,i) = z; z += lg(z);
    3609      971240 :     gel(P,i) = z; z += lg(z);
    3610             :   }
    3611      147333 :   gel(M,1) = P;
    3612      147333 :   gel(M,2) = E;
    3613      147333 :   return sort_factor(M, (void*)&abscmpii, cmp_nodata);
    3614             : }
    3615             : 
    3616             : static void
    3617      966121 : STORE(long *nb, GEN x, long e) { (*nb)++; (void)x; (void)utoipos(e); }
    3618             : static void
    3619      915811 : STOREu(long *nb, ulong x, long e) { STORE(nb, utoipos(x), e); }
    3620             : static void
    3621       50158 : STOREi(long *nb, GEN x, long e) { STORE(nb, icopy(x), e); }
    3622             : /* no prime less than p divides n; return 1 if factored completely */
    3623             : static int
    3624       39458 : special_primes(GEN n, ulong p, long *nb, GEN T)
    3625             : {
    3626       39458 :   long i, l = lg(T);
    3627       39458 :   if (l > 1)
    3628             :   { /* pp = square of biggest p tried so far */
    3629         540 :     long pp[] = { evaltyp(t_INT)|_evallg(4), 0,0,0 };
    3630         540 :     pari_sp av = avma; affii(sqru(p), pp); set_avma(av);
    3631             : 
    3632        1184 :     for (i = 1; i < l; i++)
    3633         777 :       if (dvdiiz(n, gel(T,i), n))
    3634             :       {
    3635         329 :         long k = 1; while (dvdiiz(n, gel(T,i), n)) k++;
    3636         231 :         STOREi(nb, gel(T,i), k);
    3637         231 :         if (abscmpii(pp, n) > 0)
    3638             :         {
    3639         133 :           if (!is_pm1(n)) STOREi(nb, n, 1);
    3640         133 :           return 1;
    3641             :         }
    3642             :       }
    3643             :   }
    3644       39325 :   return 0;
    3645             : }
    3646             : 
    3647             : /* factor(sn*|n|), where sn = -1 or 1.
    3648             :  * all != 0 : only look for prime divisors < all. If pU is not NULL,
    3649             :  * set it to unfactored composite */
    3650             : static GEN
    3651    14122974 : ifactor_sign(GEN n, ulong all, long hint, long sn, GEN *pU)
    3652             : {
    3653             :   GEN M, N;
    3654             :   pari_sp av;
    3655    14122974 :   long nb = 0, nb0 = -1, i;
    3656             :   ulong lim;
    3657             :   forprime_t T;
    3658             : 
    3659    14122974 :   if (lgefint(n) == 3)
    3660             :   { /* small integer */
    3661    13975675 :     GEN f, Pf, Ef, P, E, F = cgetg(3, t_MAT);
    3662             :     ulong U1, U2;
    3663             :     long l;
    3664    13976141 :     av = avma;
    3665             :     /* enough room to store <= 15 primes and exponents (OK if n < 2^64) */
    3666    13976141 :     (void)new_chunk((15*3 + 15 + 1) * 2);
    3667    13976131 :     f = factoru_sign(uel(n,2), all, hint, pU? &U1: NULL, pU? &U2: NULL);
    3668    13976415 :     set_avma(av);
    3669    13976408 :     Pf = gel(f,1);
    3670    13976408 :     Ef = gel(f,2);
    3671    13976408 :     l = lg(Pf);
    3672    13976408 :     if (sn < 0)
    3673             :     { /* add sign */
    3674        6519 :       long L = l+1;
    3675        6519 :       gel(F,1) = P = cgetg(L, t_COL);
    3676        6519 :       gel(F,2) = E = cgetg(L, t_COL);
    3677        6519 :       gel(P,1) = gen_m1; P++;
    3678        6519 :       gel(E,1) = gen_1;  E++;
    3679             :     }
    3680             :     else
    3681             :     {
    3682    13969889 :       gel(F,1) = P = cgetg(l, t_COL);
    3683    13969872 :       gel(F,2) = E = cgetg(l, t_COL);
    3684             :     }
    3685    43201477 :     for (i = 1; i < l; i++)
    3686             :     {
    3687    29225135 :       gel(P,i) = utoipos(Pf[i]);
    3688    29225166 :       gel(E,i) = utoipos(Ef[i]);
    3689             :     }
    3690    13976342 :     if (pU) *pU = U1 == 1? NULL: mkvec2(utoipos(U1), utoipos(U2));
    3691    13976343 :     return F;
    3692             :   }
    3693      147299 :   if (pU) *pU = NULL;
    3694      147299 :   M = cgetg(3,t_MAT);
    3695      147333 :   if (sn < 0) STORE(&nb, utoineg(1), 1);
    3696      147333 :   if (is_pm1(n)) return aux_end(M,NULL,nb);
    3697             : 
    3698      147333 :   n = N = gclone(n); setabssign(n);
    3699             :   /* trial division bound; look for primes <= lim; nb is the number of
    3700             :    * distinct prime factors so far; if nb0 >= 0, it records the value of nb
    3701             :    * for which we made a successful compositeness test: if later nb = nb0,
    3702             :    * we know that n is composite */
    3703      147333 :   lim = 1;
    3704      147333 :   if (!all || all > 2)
    3705             :   { /* trial divide p < all if all != 0, else p <= tridiv_bound() */
    3706             :     ulong maxp, p;
    3707             :     pari_sp av2;
    3708      147319 :     i = vali(n);
    3709      147319 :     if (i)
    3710             :     {
    3711       76671 :       STOREu(&nb, 2, i);
    3712       76671 :       av = avma; affii(shifti(n,-i), n); set_avma(av);
    3713             :     }
    3714      147319 :     if (is_pm1(n)) return aux_end(M,n,nb);
    3715      147184 :     lim = all? all-1: tridiv_bound(n);
    3716      147184 :     if (!(hint & 16) && lim >= 128) /* expu(lim) >= 7 */
    3717       38303 :     { /* fast trial division */
    3718      126918 :       GEN nr, PR = prodprimes();
    3719      126918 :       long nPR = lg(PR)-1, b = minss(nPR, expu(lim)-6);
    3720      126918 :       av = avma; maxp = GP_DATA->factorlimit;
    3721      126918 :       nr = gcdii(gel(PR,b), n);
    3722      126918 :       if (is_pm1(nr)) { set_avma(av); av2 = av; }
    3723             :       else
    3724             :       {
    3725      124123 :         GEN F = ifactor_sign(nr, all, 1 + 2 + 16, 1, NULL), P = gel(F,1);
    3726      124123 :         long l = lg(P);
    3727      124123 :         av2 = avma;
    3728      724973 :         for (i = 1; i < l; i++)
    3729             :         {
    3730      601838 :           pari_sp av3 = avma;
    3731      601838 :           GEN gp = gel(P,i);
    3732      601838 :           ulong p = gp[2];
    3733             :           long k;
    3734      601838 :           if (lgefint(gp)>3 || (all && p>=all)) break; /* may occur for last p */
    3735      600850 :           k = Z_lvalrem(n, p, &n); /* > 0 */
    3736      600850 :           affii(n, N); n = N; set_avma(av3);
    3737      600850 :           STOREu(&nb, p, k);
    3738             :         }
    3739      124123 :         if (is_pm1(n))
    3740             :         {
    3741       88615 :           stackdummy(av, av2);
    3742       88615 :           return aux_end(M,n,nb);
    3743             :         }
    3744             :       }
    3745             :     }
    3746             :     else
    3747             :     { /* naive trial division */
    3748       20266 :       av = avma; maxp = maxprime();
    3749       20266 :       u_forprime_init(&T, 3, minss(lim, maxp)); av2 = avma;
    3750             :       /* first pass: known to fit in private prime table */
    3751    34946338 :       while ((p = u_forprime_next_fast(&T)))
    3752             :       {
    3753    34945771 :         pari_sp av3 = avma;
    3754             :         int stop;
    3755    34945771 :         long k = Z_lvalrem_stop(&n, p, &stop);
    3756    34945164 :         if (k)
    3757             :         {
    3758      238289 :           affii(n, N); n = N; set_avma(av3);
    3759      238289 :           STOREu(&nb, p, k);
    3760             :         }
    3761             :         /* prodeuler(p=2,16381,1-1/p) ~ 0.0578; if probability of being prime
    3762             :          * knowing P^-(n) > 16381 is at least 10%, try BPSW */
    3763    34945196 :         if (!stop && p == 16381)
    3764             :         {
    3765        3165 :           if (bit_accuracy_mul(lgefint(n), 0.0578 * M_LN2) < 10)
    3766        3165 :           { nb0 = nb; stop = ifac_isprime(n); }
    3767             :         }
    3768    34945196 :         if (stop)
    3769             :         {
    3770       19124 :           if (!is_pm1(n)) STOREi(&nb, n, 1);
    3771       19124 :           stackdummy(av, av2);
    3772       19124 :           return aux_end(M,n,nb);
    3773             :         }
    3774             :       }
    3775             :     }
    3776       39445 :     stackdummy(av, av2);
    3777       39445 :     if (lim > maxp)
    3778             :     { /* second pass usually empty, outside fast trial division range */
    3779           1 :       av = avma; u_forprime_init(&T, maxp+1, lim); av2 = avma;
    3780      882811 :       while ((p = u_forprime_next(&T)))
    3781             :       {
    3782      882811 :         pari_sp av3 = avma;
    3783             :         int stop;
    3784      882811 :         long k = Z_lvalrem_stop(&n, p, &stop);
    3785      882811 :         if (k)
    3786             :         {
    3787           1 :           affii(n, N); n = N; set_avma(av3);
    3788           1 :           STOREu(&nb, p, k);
    3789             :         }
    3790      882811 :         if (stop)
    3791             :         {
    3792           1 :           if (!is_pm1(n)) STOREi(&nb, n, 1);
    3793           1 :           stackdummy(av, av2);
    3794           1 :           return aux_end(M,n,nb);
    3795             :         }
    3796             :       }
    3797           0 :       stackdummy(av, av2);
    3798             :     }
    3799             :   }
    3800       39458 :   if (special_primes(n, lim, &nb, primetab)) return aux_end(M,n, nb);
    3801             :   /* if nb > nb0 (includes nb0 = -1) we don't know that n is composite */
    3802       39325 :   if (all)
    3803             :   { /* smallfact: look for easy pure powers then stop. Cf Z_isanypower */
    3804             :     GEN x;
    3805       31257 :     long k, e = expu(lim);
    3806       31257 :     av = avma;
    3807       30149 :     k = e >= 10? Z_isanypower_nosmalldiv(n, e, &x)
    3808       31257 :                : Z_isanypower(n, &x);
    3809       31257 :     if (k > 1) { affii(x, n); nb0 = -1; } else if (k < 1) k = 1;
    3810       31257 :     if (pU)
    3811             :     {
    3812             :       GEN F;
    3813       12941 :       if (abscmpiu(n, lim) <= 0
    3814       12941 :           || cmpii(n, sqru(lim)) <= 0
    3815        8634 :           || ((e >= 14) &&
    3816        7873 :               (nb>nb0 && bit_accuracy(lgefint(n))<2048 && ifac_isprime(n))))
    3817       12941 :       { set_avma(av); STOREi(&nb, n, k); return aux_end(M,n, nb); }
    3818        5747 :       set_avma(av); F = aux_end(M, NULL, nb); /* don't destroy n */
    3819        5747 :       *pU = mkvec2(icopy(n), utoipos(k)); /* composite cofactor */
    3820        5747 :       gunclone(n); return F;
    3821             :     }
    3822       18316 :     set_avma(av); STOREi(&nb, n, k);
    3823       18316 :     if (DEBUGLEVEL >= 2) {
    3824           0 :       pari_warn(warner,
    3825           0 :         "IFAC: untested %ld-bit integer declared prime", expi(n)+1);
    3826           0 :       if (expi(n) <= 256) err_printf("\t%Ps\n", n);
    3827             :     }
    3828             :   }
    3829        8068 :   else if (nb > nb0 && ifac_isprime(n)) STOREi(&nb, n, 1);
    3830        2634 :   else nb += ifac_decomp(n, hint);
    3831       26384 :   return aux_end(M,n, nb);
    3832             : }
    3833             : 
    3834             : static GEN
    3835     9542164 : ifactor(GEN n, ulong all, long hint)
    3836             : {
    3837     9542164 :   long s = signe(n);
    3838     9542164 :   if (!s) retmkmat2(mkcol(gen_0), mkcol(gen_1));
    3839     9542115 :   return ifactor_sign(n, all, hint, s, NULL);
    3840             : }
    3841             : 
    3842             : int
    3843        7094 : ifac_next(GEN *part, GEN *p, long *e)
    3844             : {
    3845        7094 :   GEN here = ifac_main(part);
    3846        7094 :   if (here == gen_0) { *p = NULL; *e = 1; return 0; }
    3847        7080 :   if (!here) { *p = NULL; *e = 0; return 0; }
    3848        5127 :   *p = VALUE(here);
    3849        5127 :   *e = EXPON(here)[2];
    3850        5127 :   ifac_delete(here); return 1;
    3851             : }
    3852             : 
    3853             : /* see before ifac_crack for current semantics of 'hint' (factorint's 'flag') */
    3854             : GEN
    3855       10290 : factorint(GEN n, long flag)
    3856             : {
    3857             :   GEN F;
    3858       10290 :   if ((F = check_arith_all(n,"factorint"))) return gcopy(F);
    3859       10276 :   return ifactor(n,0,flag);
    3860             : }
    3861             : 
    3862             : GEN
    3863       49681 : Z_factor_limit(GEN n, ulong all)
    3864             : {
    3865       49681 :   if (!all) all = GP_DATA->factorlimit + 1;
    3866       49681 :   return ifactor(n, all, decomp_default_hint);
    3867             : }
    3868             : GEN
    3869      886460 : absZ_factor_limit_strict(GEN n, ulong all, GEN *pU)
    3870             : {
    3871             :   GEN F, U;
    3872      886460 :   if (!signe(n))
    3873             :   {
    3874           0 :     if (pU) *pU = NULL;
    3875           0 :     retmkmat2(mkcol(gen_0), mkcol(gen_1));
    3876             :   }
    3877      886460 :   if (!all) all = GP_DATA->factorlimit + 1;
    3878      886460 :   F = ifactor_sign(n, all, decomp_default_hint, 1, &U);
    3879      886483 :   if (pU) *pU = U;
    3880      886483 :   return F;
    3881             : }
    3882             : GEN
    3883      290512 : absZ_factor_limit(GEN n, ulong all)
    3884             : {
    3885      290512 :   if (!signe(n)) retmkmat2(mkcol(gen_0), mkcol(gen_1));
    3886      290512 :   if (!all) all = GP_DATA->factorlimit + 1;
    3887      290512 :   return ifactor_sign(n, all, decomp_default_hint, 1, NULL);
    3888             : }
    3889             : GEN
    3890     9482158 : Z_factor(GEN n)
    3891     9482158 : { return ifactor(n,0,decomp_default_hint); }
    3892             : GEN
    3893     3276883 : absZ_factor(GEN n)
    3894             : {
    3895     3276883 :   if (!signe(n)) retmkmat2(mkcol(gen_0), mkcol(gen_1));
    3896     3276869 :   return ifactor_sign(n, 0, decomp_default_hint, 1, NULL);
    3897             : }
    3898             : /* Factor until the unfactored part is smaller than limit. Return the
    3899             :  * factored part. Hence factorback(output) may be smaller than n */
    3900             : GEN
    3901        3045 : Z_factor_until(GEN n, GEN limit)
    3902             : {
    3903        3045 :   pari_sp av = avma;
    3904        3045 :   long s = signe(n), eq;
    3905             :   GEN q, F, U;
    3906             : 
    3907        3045 :   if (!s) retmkmat2(mkcol(gen_0), mkcol(gen_1));
    3908        3045 :   F = ifactor_sign(n, tridiv_bound(n), decomp_default_hint, s, &U);
    3909        3045 :   if (!U) return F;
    3910        1155 :   q = gel(U,1); /* composite, q^eq = unfactored part */
    3911        1155 :   eq = itou(gel(U,2));
    3912        1155 :   if (cmpii(eq == 1? q: powiu(q, eq), limit) > 0)
    3913             :   { /* factor further */
    3914        1022 :     long l2 = expi(q)+1;
    3915             :     GEN P2, E2, F2, part;
    3916        1022 :     if (eq > 1) limit = sqrtnint(limit, eq);
    3917        1022 :     P2 = coltrunc_init(l2);
    3918        1022 :     E2 = coltrunc_init(l2); F2 = mkmat2(P2,E2);
    3919        1022 :     part = ifac_start(icopy(q), 0); /* ifac_next would destroy q */
    3920             :     for(;;)
    3921          70 :     {
    3922             :       long e;
    3923             :       GEN p;
    3924        1092 :       if (!ifac_next(&part,&p,&e)) break;
    3925        1092 :       vectrunc_append(P2, p);
    3926        1092 :       vectrunc_append(E2, utoipos(e * eq));
    3927        1092 :       q = diviiexact(q, powiu(p, e));
    3928        1092 :       if (cmpii(q, limit) <= 0) break;
    3929             :     }
    3930        1022 :     F2 = sort_factor(F2, (void*)&abscmpii, cmp_nodata);
    3931        1022 :     F = merge_factor(F, F2, (void*)&abscmpii, cmp_nodata);
    3932             :   }
    3933        1155 :   return gerepilecopy(av, F);
    3934             : }
    3935             : 
    3936             : static void
    3937   101005070 : matsmalltrunc_append(GEN m, ulong p, ulong e)
    3938             : {
    3939   101005070 :   GEN P = gel(m,1), E = gel(m,2);
    3940   101005070 :   long l = lg(P);
    3941   101005070 :   P[l] = p; lg_increase(P);
    3942   101002306 :   E[l] = e; lg_increase(E);
    3943   101003332 : }
    3944             : static GEN
    3945    39263451 : matsmalltrunc_init(long l)
    3946             : {
    3947    39263451 :   GEN P = vecsmalltrunc_init(l);
    3948    39241030 :   GEN E = vecsmalltrunc_init(l); return mkvec2(P,E);
    3949             : }
    3950             : 
    3951             : /* return optimal N s.t. omega(b) <= N for all b <= x */
    3952             : long
    3953       71605 : maxomegau(ulong x)
    3954             : { /* P=primes(15); for(i=1,15, print([i, vecprod(P[1..i])])) */
    3955       71605 :   if (x < 30030UL)/* rare trivial cases */
    3956             :   {
    3957       37455 :     if (x < 2UL) return 0;
    3958       19200 :     if (x < 6UL) return 1;
    3959       13600 :     if (x < 30UL) return 2;
    3960       12893 :     if (x < 210UL) return 3;
    3961       12634 :     if (x < 2310UL) return 4;
    3962       11605 :     return 5;
    3963             :   }
    3964       34150 :   if (x < 510510UL) return 6; /* most frequent case */
    3965       18752 :   if (x < 9699690UL) return 7;
    3966           6 :   if (x < 223092870UL) return 8;
    3967             : #ifdef LONG_IS_64BIT
    3968           5 :   if (x < 6469693230UL) return 9;
    3969           0 :   if (x < 200560490130UL) return 10;
    3970           0 :   if (x < 7420738134810UL) return 11;
    3971           0 :   if (x < 304250263527210UL) return 12;
    3972           0 :   if (x < 13082761331670030UL) return 13;
    3973           0 :   if (x < 614889782588491410UL) return 14;
    3974           0 :   return 15;
    3975             : #else
    3976           1 :   return 9;
    3977             : #endif
    3978             : }
    3979             : /* return optimal N s.t. omega(b) <= N for all odd b <= x */
    3980             : long
    3981        2319 : maxomegaoddu(ulong x)
    3982             : { /* P=primes(15+1); for(i=1,15, print([i, vecprod(P[2..i+1])])) */
    3983        2319 :   if (x < 255255UL)/* rare trivial cases */
    3984             :   {
    3985        1400 :     if (x < 3UL) return 0;
    3986        1400 :     if (x < 15UL) return 1;
    3987        1400 :     if (x < 105UL) return 2;
    3988        1400 :     if (x < 1155UL) return 3;
    3989        1372 :     if (x < 15015UL) return 4;
    3990        1372 :     return 5;
    3991             :   }
    3992         919 :   if (x < 4849845UL) return 6; /* most frequent case */
    3993           0 :   if (x < 111546435UL) return 7;
    3994           0 :   if (x < 3234846615UL) return 8;
    3995             : #ifdef LONG_IS_64BIT
    3996           0 :   if (x < 100280245065UL) return 9;
    3997           0 :   if (x < 3710369067405UL) return 10;
    3998           0 :   if (x < 152125131763605UL) return 11;
    3999           0 :   if (x < 6541380665835015UL) return 12;
    4000           0 :   if (x < 307444891294245705UL) return 13;
    4001           0 :   if (x < 16294579238595022365UL) return 14;
    4002           0 :   return 15;
    4003             : #else
    4004           0 :   return 9;
    4005             : #endif
    4006             : }
    4007             : 
    4008             : /* If a <= c <= b , factoru(c) = L[c-a+1] */
    4009             : GEN
    4010       31924 : vecfactoru_i(ulong a, ulong b)
    4011             : {
    4012       31924 :   ulong k, p, n = b-a+1, N = maxomegau(b) + 1;
    4013       31924 :   GEN v = const_vecsmall(n, 1);
    4014       31925 :   GEN L = cgetg(n+1, t_VEC);
    4015             :   forprime_t T;
    4016    21046341 :   for (k = 1; k <= n; k++) gel(L,k) = matsmalltrunc_init(N);
    4017       31925 :   u_forprime_init(&T, 2, usqrt(b));
    4018      885286 :   while ((p = u_forprime_next(&T)))
    4019             :   { /* p <= sqrt(b) */
    4020      853173 :     ulong pk = p, K = ulogint(b, p);
    4021     2969507 :     for (k = 1; k <= K; k++)
    4022             :     {
    4023     2116146 :       ulong j, t = a / pk, ap = t * pk;
    4024     2116146 :       if (ap < a) { ap += pk; t++; }
    4025             :       /* t = (j+a-1) \ pk */
    4026     2116146 :       t %= p;
    4027    61941874 :       for (j = ap-a+1; j <= n; j += pk)
    4028             :       {
    4029    59825543 :         if (t) { v[j] *= pk; matsmalltrunc_append(gel(L,j), p,k); }
    4030    59825728 :         if (++t == p) t = 0;
    4031             :       }
    4032     2116331 :       pk *= p;
    4033             :     }
    4034             :   }
    4035             :   /* complete factorisation of non-sqrt(b)-smooth numbers */
    4036    21221228 :   for (k = 1, N = a; k <= n; k++, N++)
    4037    21189551 :     if (uel(v,k) != N) matsmalltrunc_append(gel(L,k), N/uel(v,k),1UL);
    4038       31677 :   return L;
    4039             : }
    4040             : GEN
    4041           0 : vecfactoru(ulong a, ulong b)
    4042             : {
    4043           0 :   pari_sp av = avma;
    4044           0 :   return gerepilecopy(av, vecfactoru_i(a,b));
    4045             : }
    4046             : 
    4047             : /* Assume a and b odd, return L s.t. L[k] = factoru(a + 2*(k-1))
    4048             :  * If a <= c <= b odd, factoru(c) = L[(c-a)>>1 + 1] */
    4049             : GEN
    4050        2319 : vecfactoroddu_i(ulong a, ulong b)
    4051             : {
    4052        2319 :   ulong k, p, n = ((b-a)>>1) + 1, N = maxomegaoddu(b) + 1;
    4053        2319 :   GEN v = const_vecsmall(n, 1);
    4054        2319 :   GEN L = cgetg(n+1, t_VEC);
    4055             :   forprime_t T;
    4056             : 
    4057    18407664 :   for (k = 1; k <= n; k++) gel(L,k) = matsmalltrunc_init(N);
    4058        2319 :   u_forprime_init(&T, 3, usqrt(b));
    4059      191457 :   while ((p = u_forprime_next(&T)))
    4060             :   { /* p <= sqrt(b) */
    4061      191044 :     ulong pk = p, K = ulogint(b, p);
    4062      649000 :     for (k = 1; k <= K; k++)
    4063             :     {
    4064      459862 :       ulong j, t = (a / pk) | 1UL, ap = t * pk;
    4065             :       /* t and ap are odd, ap multiple of pk = p^k */
    4066      459862 :       if (ap < a) { ap += pk<<1; t+=2; }
    4067             :       /* c=t*p^k by steps of 2*p^k; factorization of c*=p^k if (t,p)=1 */
    4068      459862 :       t %= p;
    4069    34444124 :       for (j = ((ap-a)>>1)+1; j <= n; j += pk)
    4070             :       {
    4071    33986192 :         if (t) { v[j] *= pk; matsmalltrunc_append(gel(L,j), p,k); }
    4072    33984262 :         t += 2; if (t >= p) t -= p;
    4073             :       }
    4074      457932 :       pk *= p;
    4075             :     }
    4076             :   }
    4077             :   /* complete factorisation of non-sqrt(b)-smooth numbers */
    4078    18684838 :   for (k = 1, N = a; k <= n; k++, N+=2)
    4079    18682573 :     if (uel(v,k) != N) matsmalltrunc_append(gel(L,k), N/uel(v,k),1UL);
    4080        2265 :   return L;
    4081             : }
    4082             : GEN
    4083           0 : vecfactoroddu(ulong a, ulong b)
    4084             : {
    4085           0 :   pari_sp av = avma;
    4086           0 :   return gerepilecopy(av, vecfactoroddu_i(a,b));
    4087             : }
    4088             : 
    4089             : /* If 0 <= a <= c <= b; L[c-a+1] = factoru(c)[,1] if c squarefree, else NULL */
    4090             : GEN
    4091        7014 : vecfactorsquarefreeu(ulong a, ulong b)
    4092             : {
    4093        7014 :   ulong k, p, n = b-a+1, N = maxomegau(b) + 1;
    4094        7014 :   GEN v = const_vecsmall(n, 1);
    4095        7014 :   GEN L = cgetg(n+1, t_VEC);
    4096             :   forprime_t T;
    4097    14007238 :   for (k = 1; k <= n; k++) gel(L,k) = vecsmalltrunc_init(N);
    4098        7014 :   u_forprime_init(&T, 2, usqrt(b));
    4099      838334 :   while ((p = u_forprime_next(&T)))
    4100             :   { /* p <= sqrt(b), kill nonsquarefree */
    4101      831320 :     ulong j, pk = p*p, t = a / pk, ap = t * pk;
    4102      831320 :     if (ap < a) ap += pk;
    4103     7160090 :     for (j = ap-a+1; j <= n; j += pk) gel(L,j) = NULL;
    4104             : 
    4105      831320 :     t = a / p; ap = t * p;
    4106      831320 :     if (ap < a) { ap += p; t++; }
    4107    30551556 :     for (j = ap-a+1; j <= n; j += p, t++)
    4108    29720236 :       if (gel(L,j)) { v[j] *= p; vecsmalltrunc_append(gel(L,j), p); }
    4109             :   }
    4110             :   /* complete factorisation of non-sqrt(b)-smooth numbers */
    4111    14007238 :   for (k = 1, N = a; k <= n; k++, N++)
    4112    14000224 :     if (gel(L,k) && uel(v,k) != N) vecsmalltrunc_append(gel(L,k), N/uel(v,k));
    4113        7014 :   return L;
    4114             : }
    4115             : /* If 0 <= a <= c <= b; L[c-a+1] = factoru(c)[,1] if c squarefree and coprime
    4116             :  * to all the primes in sorted zv P, else NULL */
    4117             : GEN
    4118       32590 : vecfactorsquarefreeu_coprime(ulong a, ulong b, GEN P)
    4119             : {
    4120       32590 :   ulong k, p, n = b-a+1, sqb = usqrt(b), N = maxomegau(b) + 1;
    4121       32590 :   GEN v = const_vecsmall(n, 1);
    4122       32592 :   GEN L = cgetg(n+1, t_VEC);
    4123             :   forprime_t T;
    4124    90611472 :   for (k = 1; k <= n; k++) gel(L,k) = vecsmalltrunc_init(N);
    4125       32592 :   u_forprime_init(&T, 2, sqb);
    4126     3682123 :   while ((p = u_forprime_next(&T)))
    4127             :   { /* p <= sqrt(b), kill nonsquarefree */
    4128     3649250 :     ulong j, t, ap, bad = zv_search(P, p), pk = bad ? p: p * p;
    4129     3649269 :     t = a / pk; ap = t * pk; if (ap < a) ap += pk;
    4130    80854936 :     for (j = ap-a+1; j <= n; j += pk) gel(L,j) = NULL;
    4131     3649269 :     if (bad) continue;
    4132             : 
    4133     3587119 :     t = a / p; ap = t * p;
    4134     3587119 :     if (ap < a) { ap += p; t++; }
    4135   116578248 :     for (j = ap-a+1; j <= n; j += p, t++)
    4136   112990867 :       if (gel(L,j)) { v[j] *= p; vecsmalltrunc_append(gel(L,j), p); }
    4137             :   }
    4138       32591 :   if (uel(P,lg(P)-1) <= sqb) P = NULL;
    4139             :   /* complete factorisation of non-sqrt(b)-smooth numbers */
    4140    90900960 :   for (k = 1, N = a; k <= n; k++, N++)
    4141    90868291 :     if (gel(L,k) && uel(v,k) != N)
    4142             :     {
    4143    25682842 :       ulong q = N / uel(v,k);
    4144    25682842 :       if (!P || !zv_search(P, q)) vecsmalltrunc_append(gel(L,k), q);
    4145             :     }
    4146       32669 :   return L;
    4147             : }
    4148             : 
    4149             : GEN
    4150          49 : vecsquarefreeu(ulong a, ulong b)
    4151             : {
    4152          49 :   ulong j, k, p, n = b-a+1;
    4153          49 :   GEN L = const_vecsmall(n, 1);
    4154             :   forprime_t T;
    4155          49 :   u_forprime_init(&T, 2, usqrt(b));
    4156         462 :   while ((p = u_forprime_next(&T)))
    4157             :   { /* p <= sqrt(b), kill nonsquarefree */
    4158         413 :     ulong pk = p*p, t = a / pk, ap = t * pk;
    4159         413 :     if (ap < a) { ap += pk; t++; }
    4160             :     /* t = (j+a-1) \ pk */
    4161       21777 :     for (j = ap-a+1; j <= n; j += pk, t++) L[j] = 0;
    4162             :   }
    4163       48258 :   for (k = j = 1; k <= n; k++)
    4164       48209 :     if (L[k]) L[j++] = a+k-1;
    4165          49 :   setlg(L,j); return L;
    4166             : }

Generated by: LCOV version 1.16