home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 9 / 09.iso / e / e032 / 3.ddi / FILES / NUMBERTH.PAK / PRIMEQ.M < prev    next >
Encoding:
Text File  |  1992-07-29  |  44.5 KB  |  1,086 lines

  1.  
  2. (*:Version: Mathematica 2.0 *)
  3.  
  4. (*:Name: NumberTheory`PrimeQ` *)
  5.  
  6. (* :Title:  PrimeQ *)
  7.  
  8. (* :Author: Ilan Vardi *)
  9.  
  10. (*:Keywords: 
  11.     Primality Proving, Certificate of Primality, Pratt's Certificate,
  12.     Elliptic Curves, Complex Multiplication, Goldwasser-Kilian,
  13.     Atkin-Morain
  14. *)
  15.  
  16.  
  17. (* :Source: Francois Morain, ``Implementation of the Atkin-Goldwasser-Kilian
  18.             Primality Testing Algorithm,'' INRIA Research Report #911,
  19.             October 1988.
  20.  
  21.             A.O.L. Atkin and F. Morain, ``Elliptic Curves and 
  22.             Primality Proving,'' to appear, Mathematics of Computation.
  23.  
  24.             D.A. Cox, ``Primes of the Form x^2 + n y^2'', Wiley 1989.
  25.  
  26.             Stan Wagon, ``Mathematica in Action,'' Freeman 1991.
  27.  
  28.             D. Bressoud, ``Factorization and Primality Testing,''
  29.             Springer Verlag 1989.
  30. *)
  31.  
  32. (* :Warning: 
  33.  
  34.   
  35.     ProvablePrimeQ[p] has to wait until PrimeQCertificate has
  36.     finished to return its answer, i.e., until a certificate has been
  37.     generated. Since PrimeQCertificate caches its value, running 
  38.     PrimeQCertificate[p] after ProvablePrimeQ[p] will not take 
  39.     any extra time. (There have been problems with caching of 
  40.     certificates.)
  41.  
  42.     ProvablePrimeQ uses PrimeQ and only proves that the old PrimeQ 
  43.     has returned a correct answer. If PrimeQ is incorrect, i.e., 
  44.     it claims that a composite number is prime, then ProvablePrimeQ will 
  45.     either not return a value (will go in an 
  46.     infinite loop) or else it will find a nontrivial divisor of a number 
  47.     that is claimed to be prime by PrimeQ. Thus ProvablePrimeQ can
  48.     be used to find counterexamples to PrimeQ.
  49. *)
  50.  
  51.  
  52. (* :Limitation:  The Elliptic Curves method will not work for very 
  53.                  small primes, so SmallPrime indicating when this
  54.                  method takes over from Pratt's method has a minimum
  55.                  value of 1000.
  56.  
  57.                  It looks like this method will return an answer in 
  58.                  reasonable time for inputs of up to 200 digits, i.e.,
  59.                  this takes about 6 hours on a DEC workstation.
  60.                  
  61. *)  
  62.  
  63. (* :Discussion: 
  64.  
  65.       This package does primality proving. In fact, the package will
  66.       produce a certificate of primality, i.e., a short set of data
  67.       that is a witness to the primality of a prime. This certificate
  68.       can easily be checked in the sense that the theory involved in 
  69.       implementing a check is much easier than the theory that produced
  70.       the certificate. This is analogous to the certificate of 
  71.       compositeness given by exhibiting a nontrivial factorization.
  72.       The package also includes a certificate of compositeness, though 
  73.       it is more subtle than just giving a factor.
  74.     
  75. *********************************************************************
  76.                Pratt's certificate of Primality
  77. *********************************************************************
  78.  
  79.       For small prime p <= SmallPrime use Pratt's certificate of primality:
  80.  
  81.       Pratt's certificate gives a proof that a is a generator 
  82.       (primitive root) of the multiplicative group (mod p) which,
  83.       along with the fact that a has order p-1, proves that p is a
  84.       prime.  You need to factor p-1, which is feasible for p with 
  85.       20 digits or less. 
  86.      
  87.       The certificate shows that PowerMod[a, p-1, p] = 1 and 
  88.       PowerMod[ a, (p-1)/q, p] != 1 for all primes q dividing p-1
  89.       (=> a is a primitive root). These primes q are the children of 
  90.       {p,a} in the tree and are proved prime recursively. You have
  91.       to check that all prime factors of p - 1 are included.
  92.  
  93.       This part of the program uses some suggestions of Ferris Wheeler
  94.       as in the PrimitiveRoot[]  program in NumberTheoryFunctions.m
  95.       package.
  96.  
  97.       See Stan Wagon's book for details on this test.
  98.  
  99. ***************************************************************
  100.     Atkin-Goldwasser-Kilian-Morain certificate of primality
  101. ***************************************************************
  102.  
  103.       For large primes p > SmallPrime use the Atkin-Morain test:
  104.  
  105.       The Atkin-Morain test returns a recursive certificate for the 
  106.       prime p. This consists of a list of:
  107.  
  108.  (i)  A point (CertificatePoint) on an Elliptic Curve: PointEC[x,y,g2,g3,p],
  109.       in other words, a solution of the equation
  110.  
  111.           y^2 = x^3 + g2 x + g3  (mod p)
  112.  
  113.       for some numbers g2 and g3.
  114.  
  115.  (ii) A prime q with q > (p^(1/4) + 1)^2, such that for some
  116.       other number k (CertificateK), and m = k q (CertificateM)
  117.       such that k is not equal to 1 and such that 
  118.  
  119.            m PointEC[x,y,g2,g3,p] 
  120.  
  121.       is the identity on the curve, but 
  122.  
  123.            k PointEC[x,y,g2,g3,p]
  124.  
  125.        is not the identity. This guarantees primality of p
  126.        by a theorem of Goldwasser and Kilian (see Lenstra, 
  127.        Elliptic Curve algorithms, World Congress 1986). So one needs 
  128.        only to show that q is also prime in order to show that p is 
  129.        prime, and q is shown prime using the same method.
  130.  
  131.  (iii) Each q has its recursive certificate following it. So if 
  132.        the smallest q is known to be prime, all the numbers are
  133.        certified prime up the chain.
  134.  
  135.    Thus to check the certificate at level q, do
  136.  
  137.       CertificateK CertificatePoint /. 
  138.         Select[PrimeQCertificate[p, opts], #[[1]] == q &] [[2]] 
  139.  
  140.       CertificateM CertificatePoint /. 
  141.         Select[PrimeQCertificate[p, opts], #[[1]] == q &] [[2]] 
  142.  
  143.       CertificateNextPrime == CertificateM /CertificateK &&
  144.         CertificateNextPrime > ((N[q]^(1/4) + 1)^2) /.
  145.            Select[PrimeQCertificate[p, opts], #[[1]] == q &] [[2]]  
  146.  
  147.    The first should not be the identity, the second should be the
  148.    identity and the third should be True.
  149.  
  150.    This algorithm is described in Francois Morain's INRIA technical
  151.    report #911.  A more recent version is in the Atkin-Morain paper.
  152.  
  153.      
  154. ***************************************************************
  155.               Certificate of Compositeness 
  156. ***************************************************************
  157.    
  158.    The certificate of compositeness shows that either 
  159.    PowerMod[a, p - 1, p] != 1, or else a != 1 or -1 and
  160.    PowerMod[a, 2, p] == 1, which proves that p is not a prime. 
  161.  
  162.    Applying PowerMod to PrimeQCertificate[p] proves p composite
  163.    by checking this condition for the value of a given by the 
  164.    certificate.
  165.  
  166. *)
  167.  
  168.  
  169. BeginPackage["NumberTheory`PrimeQ`", "NumberTheory`NumberTheoryFunctions`"]  
  170.  
  171.  
  172. ProvablePrimeQ::usage = "ProvablePrimeQ[n] determines if n
  173. is prime or not and can provide a certificate (proof) of this."
  174.  
  175. Certificate::usage = "Certificate is an option to ProvablePrimeQ,
  176. which prints a certificate for the primality or compositeness of n if
  177. and only if Certificate -> True."
  178.  
  179. SmallPrime::usage = 
  180. "SmallPrime is an option for ProvablePrimeQ, PrimeQCertificate, and
  181. PrimeQCertificateCheck, which gives a lower bound for using the Atkin-Morain
  182. primality test."
  183.  
  184. PrimeQCertificate::usage = "PrimeQCertificate[n] prints out a certificate
  185. that n is prime or that n is composite."
  186.  
  187. TrialDivisionLimit::usage =
  188. "TrialDivisionLimit is an option to ProvablePrimeQ and PrimeQCertificate that
  189. specifies how many primes should be used in the trial division part of 
  190. PrimeQCertificate[n]."
  191.  
  192. PollardPTest::usage = 
  193. "PollardPTest is an option to ProvablePrimeQ and PrimeQCertificate which 
  194. determines whether the Pollard p-1 factoring algorithm in the factorization
  195. part of PrimeQCertificate[n] is used."
  196.  
  197. PollardRhoTest::usage =
  198. "PollardRhoTest is an option to ProvablePrimeQ and PrimeQCertificate which 
  199. determines whether the Pollard rho factoring algorithm in the factorization
  200. part of PrimeQCertificate[n] is used."
  201.  
  202. PrimeQCertificateCheck::usage = "PrimeQCertificateCheck[cert, n]
  203. checks that the certificate cert is a correct certificate for the
  204. primality or compositeness of n. It returns True if the certificate
  205. is correct. If it does not return True then it returns a counterexample
  206. to PrimeQ[], i.e., a nontrivial factor of a number declared prime
  207. by PrimeQ."
  208.  
  209. ModularInvariantj::usage = "ModularInvariantj[z] gives the j invariant
  210. of the complex number z, Im[z] > 0."
  211.  
  212. HilbertPolynomial::usage = "HilbertPolynomial[d] gives the irreducible
  213. polynomial of ModularInvariantj[(-1 + Sqrt[d])/2], where d < 0 is a 
  214. square free integer of the form 4 n + 1. The splitting field is
  215. the Hilbert Class Field (maximal unramified Abelian extension) of
  216. Q(Sqrt[d])."
  217.  
  218. x::usage= "Indeterminate in the Hilbert polynomial."
  219.  
  220. PointEC::usage = "PointEC[a, b, g2, g3, p] gives a point
  221. on the elliptic curve y^2 = x^3 + g2 x + g3 (mod p)."
  222.  
  223. PointECQ::usage = "PointECQ[PointEC[a, b, g2, g3, p]] returns True if
  224. b^2 = a^3 + g2 a + g3 (mod p) so that the point is on the elliptic
  225. curves that it claims it is."
  226.  
  227. CertificatePrime::usage = "CertificatePrime is used to certify primality."
  228.  
  229. CertificatePoint::usage = "CertificatePoint is used to certify primality."
  230.  
  231. CertificateK::usage = "CertificateK is used to certify primality."
  232.  
  233. CertificateM::usage = "CertificateM is used to certify primality."
  234.  
  235. CertificateNextPrime::usage = "CertificateNextPrime is used to certify primality."
  236.  
  237. CertificateDiscriminant::usage = "CertificateDiscriminant is used to certify primality."
  238.  
  239. PrimeQMessages::usage = "PrimeQMessages -> True is an option to
  240. PrimeQCertificate which prints out the progress of the algorithm."
  241.  
  242.  
  243. Begin["`Private`"]
  244.  
  245. Options[PrimeQCertificate] =
  246. {SmallPrime -> 10^10, Certificate -> False, PrimeQMessages->False,
  247.  PollardPTest -> Automatic, PollardRhoTest -> Automatic,
  248.  TrialDivisionLimit -> Automatic}
  249.  
  250. Options[ProvablePrimeQ] = Options[PrimeQCertificate]
  251.  
  252. ProvablePrimeQ[p_Integer, opts___]:=
  253.           If[!TrueQ[(Certificate /. {opts} /. Options[ProvablePrimeQ])],
  254.                Block[{},
  255.                  PrimeQCertificate[p, opts];
  256.                  Return[PrimeQ[p]]
  257.            ],
  258.           (*  Or else get a certificate along with the answer.   *)
  259.                  {PrimeQ[p], PrimeQCertificate[ p, opts]}
  260.           ]
  261.         
  262.  
  263. PrimeQCertificate::false =
  264.     "Warning: PrimeQCertificate has detected a counterexample to PrimeQ."
  265. PrimeQCertificate::smprm = "Warning: SmallPrime set to 1000."
  266. PrimeQCertificate::trdiv = "Warning: TrialDivisionLimit set to default ``."
  267. PrimeQCertificate::pollp = "Warning: PollardPTest set to default ``."
  268. PrimeQCertificate::pollr = "Warning: PollardRhoTest set to default ``."
  269.  
  270. PrimeQCertificate[p_Integer, opts___]:= PrimeQCertificate[p, opts]=
  271.    Block[{a, q, r, s, exp, smallprime, flist,
  272.           d = -7, qr,t,qplus,qminus,m,moverq,hr,ell,
  273.           sqrtp = Round[Sqrt[N[p]]], 
  274.           classtablelen = Length[ClassTable], tableq = True, 
  275.           trialvector, triallen, tdr, qplustr, pminustr, tdmod,
  276.           trialdivisionlimit, pollardptest, pollardrhotest,
  277.           g2,g3,xec,yec2,p1,p2,point,c,di = 1, hp, curve, messages},
  278.  
  279.  
  280.     Which[p == 2, 2, 
  281.  
  282. (* p Composite *)
  283.           Not[PrimeQ[p]], 
  284. (*
  285.              Certificate of compositeness  
  286.  
  287. *)
  288.    a = 1; q = (p - 1)/2;  s = -1;  exp = 2; 
  289.     While[EvenQ[q], q /= 2]; 
  290.           While[Mod[s + 1, p] == 0, 
  291.                     a++; 
  292.                      If[PowerMod[a, p - 1, p] != 1, 
  293.                           exp = p - 1;
  294.                           s = a;  
  295.                           Break[], 
  296.                             r = PowerMod[a, q, p];
  297.                             If[r != 1, 
  298.                             While[r != 1, 
  299.                                   s = r; 
  300.                                   r = PowerMod[s, 2, p] 
  301.                                  ]
  302.                               ]
  303.                        ]
  304.                      ];
  305.               {s, exp, p},
  306.  
  307. (* Prime *) 
  308.  
  309.      PrimeQ[p], 
  310.  
  311.      smallprime = SmallPrime /. {opts} /. Options[PrimeQCertificate];
  312.  
  313.    (* restrict SmallPrime to >= 1000 *)
  314.  
  315.      If[!NumberQ[smallprime] || smallprime < 1000,
  316.         Message[PrimeQCertificate::smprm];
  317.         smallprime=1000
  318.         ];
  319.  
  320.      (* Pratt's certificate *)
  321.  
  322. If[p <= smallprime,
  323.    a = 2; flist = First /@ FactorInteger[p-1];
  324.    While[JacobiSymbol[a, p] == 1 ||
  325.          Scan[If[PowerMod[a, (p-1)/#, p] == 1,
  326.                  Return[True]]&, flist],
  327.                         a++]; 
  328.                 If[PowerMod[a, p-1, p] == 1, 
  329.          {p, a, PrimeQCertificate[#, opts] & /@ flist}
  330.                    ],
  331.  
  332.        (* Elliptic curves certificate  *)
  333.  
  334. (* First build a vector of p + 1 mod small primes in order to 
  335.    facilitate trial division. *)
  336.  
  337. messages = PrimeQMessages /. {opts} /. Options[PrimeQCertificate]; 
  338.  
  339. If[messages, Print[p]; Print["Create trial division vector"]];
  340.  
  341. trialdivisionlimit = TrialDivisionLimit /. {opts} /. Options[PrimeQCertificate]; 
  342. If[trialdivisionlimit =!= Automatic &&
  343.    (!NumberQ[trialdivisionlimit] || Head[trialdivisionlimit] =!= Integer ||
  344.     trialdivisionlimit <= 0),
  345.     trialdivisionlimit = Which[p > 10^150, 20000,
  346.                    p > 10^60, 10000, True, 5000];
  347.         Message[PrimeQCertificate::trdiv, trialdivisionlimit]];
  348.  
  349. If[trialdivisionlimit === Automatic, 
  350.     trialdivisionlimit = Which[p > 10^150, 20000, 
  351.                                    p > 10^60, 10000, True, 5000]]; 
  352.  
  353. trialdivisionlimit = Min[trialdivisionlimit, 
  354.                          2 Sqrt[N[p]]/Log[N[p]]];
  355.  
  356. trialvector = Mod[p+1, Prime[Range[trialdivisionlimit]]]; 
  357.  
  358. triallen = Length[trialvector];
  359.  
  360. (* What kind of factoring tests should be used in LargeFactor. *)
  361.  
  362. pollardptest = PollardPTest /. {opts} /. Options[PrimeQCertificate]; 
  363. If[!MemberQ[{Automatic, True, False}, pollardptest],
  364.     pollardptest = (p < 10^150);
  365.     Message[PrimeQCertificate::pollp, pollardptest]];
  366. If[pollardptest === Automatic, pollardptest = p < 10^150];
  367.  
  368. pollardrhotest = PollardRhoTest /. {opts} /. Options[PrimeQCertificate]; 
  369. If[!MemberQ[{Automatic, True, False}, pollardrhotest],
  370.     pollardrhotest = (p < 10^60);
  371.     Message[PrimeQCertificate::pollr, pollardrhotest]];
  372. If[pollardrhotest === Automatic, pollardrhotest = p < 10^60];
  373.  
  374. If[messages, Print[{"Trial division vector done", triallen}]];  
  375.  
  376.     While[True, 
  377.          While[JacobiSymbol[d,p] != 1, 
  378.                 If[di < classtablelen, di++; d = 1 - 4 ClassTable[[di]],
  379.                    If[di == classtablelen || tableq, 
  380.                       d = -7; di++, tableq = False;
  381.                       {d, di} += {-4, 1}]];
  382.                 If[di > classtablelen, 
  383.                    While[MemberQ[ClassTable, (1 - d)/4] || 
  384.                          !SquareFreeQ[d], {d, di} += {-4, 1}]]
  385.                 ];
  386.           If[di > classtablelen && ClassNumber[d] > 30, 
  387.              {d, di} += {-4, 1};
  388.              While[MemberQ[ClassTable, (1 - d)/4] && 
  389.                    !SquareFreeQ[d], {d, di} += {-4, 1}];
  390.              Continue[]];
  391.            If[messages, Print[{di, d}]];
  392.            qr= QuadraticRepresentation4[d, p];
  393.            If[qr === False, 
  394.               If[di < classtablelen, di++; d = 1 - 4 ClassTable[[di]],
  395.                  If[di == classtablelen || tableq, 
  396.                     d = -7; di++; tableq = False,
  397.                     {d, di} += {-4, 1}]];
  398.               If[di > classtablelen, 
  399.                  While[MemberQ[ClassTable, (1 - d)/4] || 
  400.                        !SquareFreeQ[d], {d, di} += {-4, 1}]];
  401.                  Continue[]];                      
  402.             t = Abs[2 qr[[1]]]; s = Abs[2 qr[[2]]];
  403.             qplustr = p + 1 + t;
  404.             qminustr = p + 1 - t;
  405.  
  406. (* Trial division of p + 1 + t, p + 1 - t, is done in parallel
  407.    by comparing t mod small primes with the stored values 
  408.    of p + 1 mod small primes in trialvector. This allows one 
  409.    to do both trial divisions at once and by modular operations
  410.    with a number of size sqrt[p]. See Atkin-Morain for details. *)
  411.  
  412.   If[messages, Print["trying Trial Division"]];  
  413.  
  414.  
  415. tdmod = Mod[t, Prime[Range[triallen]]];
  416.  
  417. Scan[While[Mod[qminustr, #] == 0, qminustr = Quotient[qminustr, #]]&, 
  418.      Prime[Flatten[Position[tdmod - trialvector, 0]]]];
  419.  
  420. Scan[While[Mod[qplustr, #] == 0, qplustr = Quotient[qplustr, #]]&,   
  421.      Prime[Flatten[Position[
  422.            MapIndexed[If[#1 == 0 || {#1} == Prime[#2],0,1]&,
  423.                          tdmod + trialvector], 0]]]];
  424.            qplus =  
  425.            LargeFactor[qplustr, p+1+t, p, pollardptest, pollardrhotest];
  426.             If[IntegerQ[qplus], m = p + 1 + t; q = qplus,
  427.                qminus = 
  428.                LargeFactor[qminustr, p+1-t, p, pollardptest, pollardrhotest];
  429.                If[IntegerQ[qminus], m = p + 1 - t; q = qminus,
  430.                   If[di < classtablelen, di++; d = 1 - 4 ClassTable[[di]],
  431.                      If[di == classtablelen || tableq, 
  432.                         d = -7; di++; tableq = False,
  433.                       {d, di} += {-4, 1}]];
  434.                       If[di > classtablelen, 
  435.                          While[MemberQ[ClassTable, (1 - d)/4] ||
  436.  
  437.                                !SquareFreeQ[d], {d, di} += {-4, 1}]];
  438.                    Continue[]]]; 
  439.                 Break[]
  440.           ]; 
  441.           If[messages,  Print[{di, d}]]; 
  442.           hp = If[di > Length[HilbertPolynomialTable]
  443.                        || di > classtablelen,
  444.                   HilbertPolynomial[d], 
  445.                   HilbertPolynomialTable[[di]]];
  446.           SeedRandom[101];                   (* Same random factor  *)
  447.           hr = RootMod[hp, p]; 
  448.           ell = Mod[hr PowerMod[1728 - hr,-1,p], p]; 
  449.           g2 = Mod[3 ell,p]; g3= Mod[2 ell,p]; 
  450.           xec = 2; 
  451.           While[True, 
  452.                 yec2 = Mod[PowerMod[xec,3,p] + g2 xec + g3, p];
  453.                 While[JacobiSymbol[yec2,p] == -1,
  454.                       xec++;
  455.                       yec2 = Mod[PowerMod[xec,3,p] + g2 xec + g3, p];
  456.                       ];
  457.                 point = PointEC[xec, SqrtMod[yec2,p],g2,g3,p];  
  458.                 moverq = m/q; 
  459.  
  460. (* Point will be expressed in projective coordinates so as 
  461.    to avoid doing GCD operations. The X coordinate will be 
  462.    written as a ratio x:z. The identity element occurs when
  463.    z = 0. See Bressoud's book, p. 213.
  464.       One has to check that no nontrivial factors of p 
  465.    occur, i.e., that 1 < GCD[z, p] < p does not occur. *)
  466.  
  467.                 p1 = mult[{xec, 1}, moverq, g2, g3, p]; 
  468.                 If[p1[[2]] == 0, xec++; Continue[]]; 
  469.                 p2 = multcheckprime[p1, q, g2, g3, p]; 
  470.                 If[GCD[p2[[1]], p] > 1, 
  471.                    Message[PrimeQCertificate::false];
  472.                    Return[{p, GCD[p, p2[[1]]], g2, g3}]];
  473.  
  474. (* Check that second to last operation did not give a nontrivial
  475.    factor of p. If it does then PrimeQ[p] is wrong. 
  476.    p2[[1]] : p2[[2]] gives X coordinate of q * pt which should
  477.    be the identity (p2[[2]] == 0), p2[[3]] : p2[[4]] gives the
  478.    X coordinate of (q + 1) * pt. If a nontrivial divisor of
  479.    p occured in the computation of q * pt, then it would remain
  480.    in the the Z coordinate of (q+1) * pt (i.e., GCD[p2[[4]], p]>1).
  481. *)
  482.  
  483.                 If[p2[[3]] == 0, Break[]]; 
  484.                 c = 2; While[JacobiSymbol[c,p] == 1, c++];
  485.                 g2 = Mod[g2 c^2, p];
  486.                 g3 = Mod[g3 c^3, p]; 
  487.                 curve = 2;
  488.                 xec = 2
  489.                 ];  
  490.       Prepend[PrimeQCertificate[q, opts], 
  491.       {CertificatePrime -> p, 
  492.        CertificatePoint -> point,  
  493.        CertificateK -> m / q, 
  494.        CertificateM -> m,  
  495.        CertificateNextPrime -> q, 
  496.        CertificateDiscriminant -> d}]
  497.       ]]]
  498.              (*  End of PrimeQCertificate[p]   *)
  499.  
  500.  
  501.  
  502.  
  503.  
  504. (*  *************************************************************
  505.                Checking the certificate 
  506.     ************************************************************
  507.  
  508. *)
  509.  
  510. (*  
  511.     If p is composite check that PowerMod[a, p - 1, p] != 1 or
  512.     that ( PowerMod[ a, 2, p] == 1 for a != -1, 1 ), for some a. 
  513. *)
  514.  
  515. PrimeQCertificateCheck::badarg := "Certificate does not correspond
  516. to number being tested."
  517.  
  518. PrimeQCertificateCheck[2, 2] := True
  519.  
  520. PrimeQCertificateCheck[_, 2] := False
  521.  
  522. PrimeQCertificateCheck[list_List, p_] :=
  523.   Block[{am, pratt}, 
  524.         If[Not[PrimeQ[p]], 
  525.  
  526. (* Make sure that certificate corresponds to number. *)
  527.  
  528.   If[!VectorQ[list] || p != list[[3]], 
  529.      Message[PrimeQCertificateCheck::badarg]; Return[]]; 
  530.  
  531. Return[
  532.          Length[list] == 3 && 
  533.  
  534.  (* Either a^(p-1) != 1 (mod p)  *)
  535.  
  536.          ((Rest[list] == {p-1, p} && Apply[PowerMod, list] != 1) ||
  537.  
  538.  (* or there is an element a != 1 or -1 such that a^2 = 1 (mod p). *)
  539.  
  540.          (Rest[list] == {2, p} && (First[list] != 1 && First[list] != p-1)&&
  541.           Apply[PowerMod, list] == 1))]]; 
  542.      
  543.     (* Checking for primality: pratt is the Pratt portion of the test, i.e.,
  544.        the last 3 entries in the certificate and am the rest of the 
  545.        certificate, i.e., Atkin-Morain portion. *)
  546.  
  547. (* Check that certificate matches a certificate of primality, not
  548.    compositeness. *)
  549.  
  550. If[VectorQ[list], 
  551.    Message[PrimeQCertificateCheck::badarg]; Return[]]; 
  552.  
  553.       pratt = Take[list, -3];  am = Drop[list, -3]; 
  554.  
  555.  
  556. (* Make sure that certificate corresponds to number *)
  557.  
  558. If[Not[p == First[pratt] || (p == (CertificatePrime /. First[am]))], 
  559.    Message[PrimeQCertificateCheck::badarg]; Return[]]; 
  560.  
  561.  
  562.  
  563. (* Testing the Pratt certificate is equivalent to recomputing it.
  564.    
  565.    A nontrivial failed inversion during elliptic curve addition 
  566.    means that a counterexample to PrimeQ has been found, i.e., 
  567.    PrimeQ[p] is true, but a nontrivial factor of p is found. 
  568.    This test is implemented using a Throw/Catch construction. *)
  569.  
  570.  Catch[answer = 
  571.        (p == First[pratt] &&                  (* If only Pratt's test *)
  572.         pratt == PrimeQCertificate[First[pratt], 
  573.                                    SmallPrime-> p + 1]) ||
  574.   (     (* Elliptic curve test *)
  575. (((CertificateNextPrime /. Last[am]) == First[pratt])) &&
  576. (pratt == PrimeQCertificate[First[pratt], SmallPrime->First[pratt+1]]) &&
  577.    (p == First[pratt] || 
  578.    (And @@ Map[PointECQ[(CertificatePoint /. #)] &&
  579.               (!((CertificateK CertificatePoint /. #) === IdentityEC)) &&
  580.               (CertificateM CertificatePoint /. #) === IdentityEC &&
  581.               (CertificateM /. #) > (CertificateNextPrime /. #) > 
  582.                ((N[CertificatePrime /. #]^(1/4) + 1)^2) &&
  583.     (CertificateK /. #)  (CertificateNextPrime /. #) == (CertificateM /. #)&,
  584.              am]))
  585.    && (Table[CertificateNextPrime, {Length[am] -1}] /. Drop[am, -1]) ==
  586.       (Table[CertificatePrime, {Length[am] -1}] /. Rest[am]))];
  587.     If[Length[PrimeQCounterexample] == 3, 
  588.        PrimeCounterexample, 
  589.        answer]
  590.    ]
  591.  
  592.  
  593.    (* Computing the j invariant using the Dedekind eta function. 
  594.       See Atkin--Morain, Section 3.5. *)
  595.  
  596.    
  597. ModularEta[z_, prec_Integer, range_Integer]:= 
  598. Block[{q = Exp[2 N[Pi, prec] I N[z, prec]], i}, 
  599.        Exp[N[Pi, prec] I N[z, prec]/12] * 
  600.        (1 + 
  601.        Plus @@ Table[(-1)^i (q^(i (3 i -1)/2) + q^(i (3 i + 1)/2)), 
  602.                      {i, range}])
  603.       ]
  604.  
  605. ModularInvariantj[z_, prec_Integer, range_Integer] := 
  606. Block[{f2 = 
  607.        2^12 (ModularEta[2 z, prec, range] /
  608.               ModularEta[z, prec, range])^24},
  609.       (f2 + 16)^3/f2]   
  610.  
  611.  
  612. (* Computing the Hilbert Polynomial. The specifications for
  613.    the precision in computing the j-invariant and the number
  614.    of terms to use in the series for eta(z) are given in 
  615.    Atkin--Morain, Section 8.1. *)
  616.  
  617. HilbertPolynomial[d_Integer]:= 
  618.       Block[{hprec, hrange, s, classlist = ClassList[d]},  
  619.             hprec = Ceiling[10 + 2 Sqrt[N[-d]] * 
  620.                             (Plus @@ N[1/(First /@ classlist)])]; 
  621.             hrange = 3; 
  622.       Expand[Fold[#1 x + #2&, 1, 
  623.            Rest[Reverse[Round[N[CoefficientList[Expand[Apply[Times,
  624.            x - Map[ModularInvariantj[
  625.                (- #[[2]] + Sqrt[N[d, hprec]]) / (2 #[[1]]) , 
  626.                     hprec, Round[hrange Sqrt[N[#[[1]]]]]]&, 
  627.            classlist]]], {x}], hprec]]]]]]]
  628.                         
  629. (* 
  630.    Find a root of the monic reducible polynomial f[x] (mod p). 
  631.    This doesn't need Berlekamp's algorithm since Class Field Theory
  632.    guarantees that the Hilbert Polynomial splits completely (mod p). 
  633.    However this seems to be unnacceptable for larger degrees, e.g., 11.
  634. *)
  635.  
  636. (* PolynomialMod does the wrong thing, so use PolyMod instead. *)
  637.  
  638. PolyMod[f_, p_]:= PolynomialMod[Expand[f], p]
  639.  
  640. RootMod[f_, p_Integer]:= Mod[-Coefficient[f,x,0], p]  /; Exponent[f,x] == 1
  641.  
  642. RootMod[f_,p_Integer]:= 
  643.         Block[{cl,b,c},
  644.               cl = Map[Mod[#, p] &, CoefficientList[f,x]];
  645.               b = cl[[2]]; c = cl[[1]];
  646.               Return[Mod[(-b + SqrtMod[b b - 4 c, p]) PowerMod[2, -1,p],p]]
  647.              ]   /; Exponent[f,x] == 2
  648.  
  649. RootMod[f_, p_Integer] := 
  650.   Block[{exp = Exponent[f, x], fp = PolyMod[f,p], s, t, i, q},
  651.   While[True, 
  652.         s = Plus @@ Table[Random[Integer,{0,p}] x^i, {i,0,exp-2}] + 
  653.             x^(exp - 1); 
  654.         t = GCDMod[s, fp, p]; 
  655.        If[0 < Exponent[t,x] < exp, Break[],
  656.          t =  GCDMod[fp, PolyPowerMod[s, (p-1)/2, {fp, p}] - 1, p];
  657.             If[ 0 < Exponent[t,x] < exp, Break[]]
  658.         ]]; 
  659.     q = PolyMod[PolynomialQuotient[fp, t, x], p];
  660.     t = If[Exponent[q, x] < Exponent[t, x], q, t];
  661.     RootMod[t, p]
  662.    ]       /; Exponent[f,x] > 2
  663.  
  664.  
  665. (* You need a different GCD for polynomials (mod p). E.g., 
  666.    GCD[x^3 - 1, x-2] = 1, but PolynomialRemainder[x^3 -1, x - 2, x] = 7.
  667.    In other words, using the built-in GCD would not allow you to find
  668.    the root 2 of x^3 - 1 == 0 (mod 7).      *)
  669.    
  670. GCDMod[f_,g_,p_Integer] := 
  671.     GCDMod[g,f,p] /; Exponent[f,x] < Exponent[g,x] 
  672.  
  673. GCDMod[f_, g_, p_Integer] := f  /;  Exponent[g,x] == -Infinity
  674.  
  675. GCDMod[f_, g_, p_Integer] := 
  676.           Block[{fp = PolyMod[f, p], gp = PolyMod[g, p], 
  677.                  q,r,monic},
  678.                      monic = Coefficient[gp, x, Exponent[gp,x]];
  679.                      If[monic != 1, 
  680.                         gp = PolyMod[PowerMod[monic, -1, p] gp, p]];
  681.                      q = PolyMod[PolynomialQuotient[fp, gp, x], p];
  682.                      r = PolyMod[PolynomialRemainder[fp, gp, x], p];
  683.                      If[Exponent[r, x] <= 0,
  684.                         If[r == 0, Return[gp], Return[1]],
  685.                      Return[GCDMod[gp,r,p]]
  686.                      ]
  687.              ]  /; Exponent[g,x] >= 0
  688.  
  689.  
  690. PolynomialRemainderMod[f_, g_, x_, p_Integer] := 
  691.     PolyMod[PolynomialRemainder[PolyMod[f, p], 
  692.                   PolyMod[g, p], x], p];
  693.    
  694. PolyPowerMod[f_,n_Integer,{g_,p_Integer}] :=
  695. Fold[PolynomialRemainderMod[#1^2 #2, g, x, p] &,
  696.      1, 
  697.      Block[{prm = PolynomialRemainderMod[f, g, x, p]},
  698.             If[# == 0, 1, prm]& /@ IntegerDigits[n, 2]]] /; n > 0
  699.  
  700.  
  701.  
  702. (* 
  703.    This tries to find a nontrivial large prime factor of n.  
  704.    (This part of the program is the bottleneck since large numbers require 
  705.    nontrivial factoring routines). The problem in this implementation
  706.    is the fact that trial division is so slow. This part of the 
  707.    program should be speeded up a lot when the complete version of 
  708.    FactorInteger is implemented in the kernel.
  709.  
  710.    The larger the number, the simpler the factoring routine used. 
  711.    For very large numbers, one uses only trial division. 
  712. *)
  713.  
  714.  
  715. LargeFactor[qq_, m_Integer,n_Integer, pptest_, prtest_] :=
  716.          Block[{q = qq, pp, pr, nn = (N[n]^(1/4)+1)^2}, 
  717.                 If[PrimeQ[q] &&  nn < q < m, Return[q]];
  718.                 If[pptest, 
  719.                  If[messages, Print["trying PollardP"]];   
  720.                    pp = GCD[q, PowerMod[2, LCM @@ Range[3000], q]-1];
  721.                    q = Quotient[q, pp];
  722.                    If[PrimeQ[q] &&  nn < q < m, 
  723.                       Return[q]]]; 
  724.                  If[prtest, 
  725.                  If[messages,  Print["trying PollardRho"]];  
  726.                    If[!(N[10^5 nn] < q < m), Return[]];
  727.                  pr = PollardRhoPrimeQ[q, 2, Min[2000, Round[N[n]^(1/4)]]];
  728.                    If[pr != q, q = Quotient[q, pr]];
  729.                    If[PrimeQ[q] &&  nn < q < m, 
  730.                       Return[q]]];
  731.               ]
  732.  
  733.  
  734. (* Finding a solution of  4p = x^2 + |d| y^2  if it exists.  *)
  735.  
  736.  
  737. QuadraticRepresentation4[d_Integer,p_Integer] :=
  738.       Block[{b,prec,u,v,w,x,y,lr, inv},
  739.             b = SqrtMod[d,p];
  740.             If[EvenQ[b], b = p - b];
  741.             prec = Max[Round[N[4/3 Log[10,p]]], 50];   
  742.             v = HighPoint[ N[ (-b +  Sqrt[d])/(2 p), prec]];
  743.             x= v[[2]]; y = v[[1]];
  744.             If[(x p - b y/2)^2 - y^2 d/4 == p, 
  745.                {x p - b y/2, y/2}, 
  746.                False]
  747.            ]    /;     d < 0 && Mod[d,4] == 1   
  748.  
  749. HighPoint[z_Complex] :=  
  750.    Block[{g = IdentityMatrix[2], abs, t=z, round}, 
  751.          While[True,
  752.                round = Round[Re[t]]; 
  753.                If[round != 0,
  754.                       t = t - round;  
  755.                       g = {{1,-round},{0,1}}. g,
  756.                       abs = 1/(Re[t]^2 + Im[t]^2);
  757.                   If[abs > 1, 
  758.                      t =  - Conjugate[t] abs; 
  759.                      g = {{0,-1},{1,0}} . g,
  760.                      Break[]
  761.                     ]
  762.                   ]
  763.                ];
  764.           g[[2]]
  765.         ]   
  766.  
  767. (* This version of PollardRho doesn't do intermediate GCD's,,
  768.    since you want to find all the small factors of a large 
  769.    number. *)
  770.  
  771. PollardRhoPrimeQ[n_, c_, max_]:= 
  772.   Block[{x1 = 2, x2 = 2^2 + c, i = 0, j, gcd, 
  773.          range = 1, prod = 1, factor = 1},
  774.          While[i <= max, 
  775.                Do[x2 = Mod[x2^2 + c, n];
  776.                   prod = Mod[prod (x1 - x2), n], {range}];
  777.                i += range; 
  778.                x1 = x2; range *= 2;
  779.                x2 = Nest[Mod[#^2 + c, n]&, x2, range]];
  780.            factor = GCD[prod, n]; 
  781.         If[factor > 1, factor, n]]
  782.  
  783.  
  784. (* ClassTable stores the fundamental discriminants d > -24000 with
  785.    class number 20 or less. They are ordered by class number and by 
  786.    size. Since d is negative of the form 4k + 1, d is stored as 
  787.    (1 - d)/4 in order to save space. This large list of 1186 numbers
  788.    is required so that weaker factoring algorithms can be used on 
  789.    large numbers (so that the algorithms searches more numbers). 
  790.    If this is too large, you can reduce it by taking the first 489
  791.    elements (class number <= 12). 
  792. *)
  793.  
  794. ClassTable = 
  795.   {2, 3, 5, 11, 17, 41, 4, 9, 13, 23, 29, 31, 47, 59, 67, 101, 107, 6, 8, 15, 
  796.    21, 27, 35, 53, 71, 77, 83, 95, 125, 137, 161, 221, 227, 10, 14, 39, 49, 
  797.    51, 55, 65, 73, 81, 89, 109, 121, 139, 149, 157, 167, 179, 181, 191, 199, 
  798.    239, 251, 257, 307, 311, 347, 353, 359, 377, 389, 12, 20, 26, 32, 33, 45, 
  799.    57, 87, 111, 131, 143, 155, 171, 173, 185, 197, 237, 263, 281, 431, 437, 
  800.    467, 551, 587, 671, 22, 62, 85, 103, 113, 129, 177, 193, 209, 211, 265, 
  801.    275, 287, 301, 305, 317, 329, 337, 341, 391, 401, 461, 479, 491, 557, 571, 
  802.    611, 629, 641, 697, 731, 809, 857, 881, 941, 18, 38, 56, 63, 116, 117, 
  803.    122, 147, 203, 207, 215, 291, 293, 371, 381, 407, 447, 497, 503, 521, 545, 
  804.    563, 617, 677, 755, 767, 797, 977, 1151, 1277, 1481, 24, 28, 46, 74, 75, 
  805.    93, 99, 145, 146, 163, 229, 235, 245, 247, 249, 261, 283, 289, 299, 325, 
  806.    335, 361, 409, 413, 415, 433, 443, 449, 451, 485, 487, 499, 509, 515, 517, 
  807.    535, 541, 577, 581, 599, 605, 613, 647, 653, 667, 679, 689, 707, 737, 749, 
  808.    751, 811, 829, 839, 851, 877, 899, 947, 971, 991, 1031, 1049, 1067, 1081, 
  809.    1097, 1187, 1211, 1217, 1271, 1367, 1397, 1427, 1487, 1577, 50, 92, 105, 
  810.    123, 141, 206, 272, 297, 323, 356, 395, 501, 701, 791, 815, 827, 887, 911, 
  811.    1007, 1061, 1091, 1121, 1181, 1247, 1361, 1511, 1607, 1691, 1721, 1931, 
  812.    2141, 2201, 2267, 2657, 30, 36, 40, 76, 80, 104, 153, 159, 175, 195, 201, 
  813.    213, 231, 279, 411, 427, 445, 455, 459, 473, 481, 591, 661, 725, 773, 785, 
  814.    787, 823, 909, 917, 921, 953, 965, 1021, 1057, 1109, 1145, 1157, 1229, 
  815.    1283, 1291, 1379, 1403, 1417, 1451, 1529, 1565, 1601, 1667, 1781, 1841, 
  816.    1847, 1859, 1871, 1907, 2057, 2237, 2327, 2537, 2621, 3461, 42, 68, 165, 
  817.    242, 321, 326, 327, 365, 383, 425, 507, 567, 635, 683, 713, 743, 801, 837, 
  818.    875, 935, 983, 1013, 1295, 1421, 1541, 1637, 1757, 1877, 1901, 1967, 2111, 
  819.    2321, 2351, 2411, 2447, 2747, 3251, 3317, 3527, 3671, 3917, 58, 64, 82, 
  820.    136, 164, 172, 183, 189, 253, 267, 309, 314, 339, 343, 355, 373, 379, 387, 
  821.    441, 452, 489, 523, 539, 559, 589, 597, 623, 639, 649, 657, 659, 681, 699, 
  822.    717, 739, 757, 761, 779, 847, 863, 865, 905, 931, 937, 959, 989, 1009, 
  823.    1037, 1039, 1073, 1103, 1117, 1133, 1139, 1147, 1175, 1189, 1193, 1199, 
  824.    1207, 1227, 1237, 1241, 1259, 1289, 1315, 1325, 1327, 1343, 1349, 1381, 
  825.    1399, 1439, 1441, 1453, 1459, 1547, 1559, 1567, 1571, 1621, 1651, 1661, 
  826.    1679, 1697, 1711, 1733, 1739, 1741, 1747, 1777, 1823, 1889, 1921, 1973, 
  827.    2033, 2039, 2081, 2087, 2099, 2197, 2207, 2251, 2285, 2339, 2381, 2417, 
  828.    2461, 2501, 2651, 2677, 2687, 2699, 2729, 2789, 2837, 2927, 2951, 3077, 
  829.    3161, 3611, 3791, 3821, 4001, 4451, (* last classno = 12 *)
  830.    48, 66, 152, 158, 182, 255, 363, 375, 
  831.    417, 477, 533, 536, 593, 665, 741, 771, 923, 1001, 1127, 1161, 1337, 1355, 
  832.    1445, 1655, 1811, 1991, 2387, 2435, 2867, 2897, 2957, 2981, 3011, 3587, 
  833.    3947, 4241, 5141, 54, 72, 98, 112, 128, 134, 176, 202, 225, 303, 351, 382, 
  834.    463, 471, 531, 537, 543, 584, 607, 627, 643, 695, 733, 807, 895, 927, 929, 
  835.    967, 1047, 1079, 1111, 1165, 1201, 1257, 1273, 1313, 1317, 1431, 1493, 
  836.    1625, 1631, 1745, 1767, 1775, 1787, 1979, 2009, 2047, 2153, 2225, 2279, 
  837.    2309, 2357, 2531, 2579, 2591, 2603, 2807, 3037, 3167, 3197, 3257, 3359, 
  838.    3371, 3401, 3551, 4217, 4547, 4637, 4661, 5057, 5387, 5771, 60, 110, 188, 
  839.    243, 315, 332, 357, 392, 405, 561, 662, 675, 711, 833, 893, 951, 1025, 
  840.    1055, 1251, 1307, 1331, 1391, 1457, 1497, 1517, 1523, 1553, 1643, 1805, 
  841.    1865, 1887, 2117, 2177, 2195, 2261, 2477, 2561, 2567, 2615, 2663, 2681, 
  842.    2771, 2993, 3041, 3191, 3287, 3491, 3581, 3707, 3713, 3797, 3911, 3977, 
  843.    4151, 4211, 4367, 4481, 4511, 4631, 4847, 4967, 5177, 5501, 100, 102, 118, 
  844.    140, 166, 200, 224, 226, 236, 254, 256, 262, 285, 290, 345, 399, 496, 505, 
  845.    524, 549, 553, 595, 685, 703, 766, 793, 841, 845, 859, 861, 883, 901, 949, 
  846.    955, 985, 1011, 1043, 1045, 1063, 1095, 1107, 1129, 1171, 1172, 1225, 
  847.    1235, 1243, 1279, 1297, 1299, 1341, 1351, 1471, 1477, 1499, 1525, 1531, 
  848.    1549, 1579, 1589, 1599, 1649, 1687, 1693, 1731, 1751, 1759, 1763, 1799, 
  849.    1829, 1837, 1849, 1873, 1895, 1927, 1937, 1939, 1949, 1955, 1961, 1981, 
  850.    1999, 2011, 2021, 2071, 2075, 2129, 2137, 2159, 2161, 2171, 2179, 2209, 
  851.    2215, 2305, 2371, 2377, 2399, 2441, 2459, 2467, 2489, 2549, 2551, 2557, 
  852.    2597, 2641, 2647, 2659, 2701, 2711, 2741, 2767, 2777, 2795, 2801, 2881, 
  853.    2891, 2909, 2929, 2999, 3007, 3065, 3097, 3131, 3149, 3187, 3209, 3215, 
  854.    3281, 3299, 3331, 3341, 3377, 3449, 3455, 3457, 3539, 3593, 3601, 3637, 
  855.    3677, 3691, 3749, 3767, 3847, 3851, 3887, 3929, 4007, 4049, 4087, 4133, 
  856.    4139, 4181, 4307, 4331, 4337, 4357, 4379, 4601, 4679, 4721, 4727, 4787, 
  857.    4799, 4987, 4997, 5039, 5099, 5351, 5429, 5459, 5561, 5711, 5849, 5897, 
  858.    96, 248, 273, 393, 416, 446, 633, 831, 987, 1085, 1112, 1137, 1163, 1371, 
  859.    1551, 1595, 1613, 1707, 1727, 1971, 2135, 2183, 2471, 2813, 2861, 3227, 
  860.    3407, 3521, 3695, 3737, 4175, 4457, 4577, 4991, 5267, 5891, 84, 130, 132, 
  861.    170, 284, 302, 346, 422, 423, 482, 512, 513, 542, 573, 579, 687, 715, 759, 
  862.    777, 886, 913, 1075, 1077, 1205, 1221, 1329, 1385, 1475, 1557, 1583, 1597, 
  863.    1685, 1709, 1831, 1835, 1893, 1929, 1943, 1957, 2051, 2083, 2101, 2127, 
  864.    2147, 2281, 2303, 2391, 2407, 2421, 2587, 2631, 2855, 2911, 2921, 2963, 
  865.    3017, 3047, 3059, 3071, 3163, 3181, 3203, 3307, 3329, 3347, 3437, 3487, 
  866.    3497, 3541, 3557, 3629, 3667, 3779, 3811, 4031, 4043, 4097, 4157, 4259, 
  867.    4283, 4351, 4409, 4571, 4757, 4781, 4913, 5009, 5207, 5261, 5417, 5477, 
  868.    5567, 5611, 5627, 5737, 5837, 5867, 5921, 5981, 78, 90, 230, 266, 386, 
  869.    458, 525, 585, 615, 836, 866, 867, 902, 1005, 1035, 1082, 1265, 1287, 
  870.    1382, 1415, 1701, 2105, 2231, 2243, 2405, 2723, 2825, 3773, 3833, 4091, 
  871.    4187, 4253, 4325, 4385, 4421, 4877, 5297, 5303, 5321, 5801, 114, 154, 316, 
  872.    374, 424, 435, 472, 562, 602, 621, 622, 651, 686, 746, 747, 752, 775, 776, 
  873.    783, 789, 805, 842, 849, 879, 892, 914, 939, 995, 1003, 1004, 1089, 1093, 
  874.    1099, 1101, 1135, 1183, 1191, 1214, 1223, 1255, 1333, 1433, 1489, 1513, 
  875.    1535, 1585, 1617, 1689, 1783, 1791, 1793, 1867, 1903, 1909, 1913, 1917, 
  876.    1963, 1985, 2017, 2063, 2089, 2123, 2189, 2249, 2263, 2287, 2299, 2333, 
  877.    2335, 2341, 2361, 2393, 2423, 2439, 2449, 2495, 2507, 2521, 2539, 2543, 
  878.    2573, 2575, 2627, 2629, 2705, 2839, 2845, 2849, 2857, 2885, 2915, 2939, 
  879.    2971, 2987, 2989, 3005, 3035, 3079, 3083, 3089, 3091, 3117, 3125, 3147, 
  880.    3151, 3221, 3233, 3239, 3241, 3289, 3311, 3389, 3413, 3451, 3577, 3583, 
  881.    3617, 3623, 3665, 3689, 3809, 3839, 3901, 3923, 3941, 3971, 3989, 4037, 
  882.    4099, 4109, 4121, 4127, 4171, 4177, 4229, 4231, 4267, 4297, 4391, 4411, 
  883.    4441, 4477, 4517, 4541, 4549, 4589, 4591, 4771, 4861, 4889, 4981, 5021, 
  884.    5051, 5147, 5171, 5189, 5221, 5273, 5309, 5327, 5347, 5399, 5431, 5441, 
  885.    5471, 5597, 5617, 5639, 5651, 5681, 5861, 5987}
  886.  
  887.  
  888. (* Table of Hilbert polynomials corresponding to fundamental 
  889.    discriminants of class number <= 3. *)
  890.  
  891. HilbertPolynomialTable = 
  892.   {3375 + x, 32768 + x, 884736 + x, 884736000 + x, 147197952000 + x, 
  893.    262537412640768000 + x, -121287375 + 191025*x + x^2, 
  894.    -134217728000 + 117964800*x + x^2, 6262062317568 + 5541101568*x + x^2, 
  895.    -3845689020776448 + 10359073013760*x + x^2, 
  896.    130231327260672000 + 427864611225600*x + x^2, 
  897.    148809594175488000000 + 1354146840576000*x + x^2, 
  898.    -3845689020776448000000 + 4545336381788160000*x + x^2, 
  899.    11946621170462723407872000 + 823177419449425920000*x + x^2, 
  900.    531429662672621376897024000000 + 19683091854079488000000*x + x^2, 
  901.    -108844203402491055833088000000 + 2452811389229331391979520000*x + x^2, 
  902.    155041756222618916546936832000000 + 15611455512523783919812608000*x + x^2, 
  903.    12771880859375 - 5151296875*x + 3491750*x^2 + x^3, 
  904.    1566028350940383 - 58682638134*x + 39491307*x^2 + x^3, 
  905.    374643194001883136 - 140811576541184*x + 30197678080*x^2 + x^3, 
  906.    549755813888000000000 - 41490055168000000*x + 2691907584000*x^2 + x^3, 
  907.    337618789203968000000000 - 6764523159552000000*x + 129783279616000*x^2 + 
  908.     x^3, 67408489017571610198016 - 53041786755137667072*x + 
  909.     12183160834031616*x^2 + x^3, 
  910.    5310823021408898698117644288 + 277390576406111100862464*x + 
  911.     65873587288630099968*x^2 + x^3, 
  912.    201371843156955365376000000000 + 90839236535446929408000000*x + 
  913.     89611323386832801792000*x^2 + x^3, 
  914.    8987619631060626702336000000000 - 5083646425734146162688000000*x + 
  915.     805016812009981390848000*x^2 + x^3, 
  916.    56176242840389398230218488594563072 + 368729929041040103875232661504*x + 
  917.     6647404730173793386463232*x^2 + x^3, 
  918.    15443600047689011948024601807415148544 - 
  919.     121567791009880876719538528321536*x + 364395404104624239018246144*x^2 + 
  920.     x^3, 4671133182399954782798673154437441310949376 - 
  921.     6063717825494266394722392560011051008*x + 
  922.     3005101108071026200706725969920*x^2 + x^3, 
  923.    83303937570678403968635240448000000000 - 
  924.     139712328431787827943469744128000000*x + 
  925.     81297395539631654721637478400000*x^2 + x^3, 
  926.    308052554652302847380880841299197952000000000 - 
  927.     6300378505047247876499651797450752000000*x + 
  928.     39545575162726134099492467011584000*x^2 + x^3, 
  929.    167990285381627318187575520800123387904000000000 - 
  930.     151960111125245282033875619529124478976000000*x + 
  931.     34903934341011819039224295011933392896000*x^2 + x^3, 
  932.    149161274746524841328545894969274007552000000000 + 
  933.     39181594208014819617565811575376314368000000*x + 
  934.     123072080721198402394477590506838687744000*x^2 + x^3}
  935.  
  936.  
  937.  
  938.  
  939. (* Elliptic Curves *)
  940.  
  941.  
  942. PointEC /: PointECQ[PointEC[pt___]] := PointECQ @@ PointEC[pt]
  943.  
  944.  
  945. PointECQ[x_,y_,g2_,g3_,p_] := Mod[y^2 - x^3 - g2 x - g3, p] === 0
  946.  
  947. PointEC /:  PointEC[x1_,y1_,g2_,g3_,p_] == PointEC[x2_,y2_,g2_,g3_,p_]:=
  948.               (Mod[x1,p] == Mod[x2,p]) && (Mod[y1,p] == Mod[y2,p]) 
  949.  
  950.  
  951. (* 
  952.     Addition on the Elliptic curve y^2 = x^3 + g2 x + g3 (mod p).
  953.     This is the part of the algorithm that gets used the most.
  954. *)
  955.  
  956. PointEC /:  PointEC[x_Integer,y_Integer,g2_,g3_,p_] + IdentityEC := 
  957.                       PointEC[x,y,g2,g3,p]
  958.  
  959. PointEC /: PointEC[x1_,y1_,g2_,g3_,p_] + PointEC[x2_,y2_,g2_,g3_,p_] :=
  960. Block[{slope, IdentityECQ = False, gcd},
  961.        If[Mod[x1 - x2, p] == 0,
  962.           If[Mod[y1 + y2, p] == 0,
  963.              IdentityECQ = True,
  964.        slope = Mod[(3 x1^2 + g2) PowerMod[2 y1, -1, p], p]],
  965.        slope = Mod[(y2 - y1) PowerMod[x2 - x1, -1, p], p],
  966.               ]; 
  967.  (* A failed inversion implies that a counterexample to PrimeQ. *) 
  968.  
  969.        If[!IntegerQ[slope], 
  970.           gcd = GCD[y1, p]; 
  971.           If[1 < gcd < p,   
  972.              Message[PrimeQCertificate::false];
  973.              PrimeQCounterexample = {False, p, gcd, False}; 
  974.              Throw[True]];
  975.           gcd = GCD[x2 - x1, p]; 
  976.           If[1 < gcd < p,   
  977.              Message[PrimeQCertificate::false];
  978.              PrimeQCounterexample = {False, p, gcd, False}; 
  979.              Throw[True]]
  980.            ];
  981.  
  982. (*   Otherwise continue with addition. *)
  983.  
  984.              If[SameQ[IdentityECQ, True], 
  985.                      IdentityEC,
  986.                      x3 =  Mod[slope^2 - x1 - x2, p];
  987.                      y3 =  Mod[slope (x1-x3) - y1, p];
  988.                      PointEC[x3,y3,g2,g3,p]
  989.                  ]
  990.             ]
  991.              
  992.  (* Multiply a point on the curve by an integer by repeated doubling, 
  993.     exactly like PowerMod[a,b,c].  *)
  994.  
  995. IdentityEC /:  n_Integer * IdentityEC := IdentityEC
  996.  
  997. PointEC /:  0 * PointEC[x_,y_,g2_,g3_,p_]:= IdentityEC
  998.  
  999. PointEC /:  1 * PointEC[x_,y_,g2_,g3_,p_]:= PointEC[x,y,g2,g3,p]
  1000.  
  1001. PointEC /: 2 * PointEC[x_, y_, g2_, g3_, p_]:= 
  1002.                 PointEC[x, y, g2, g3, p] + PointEC[x, y, g2, g3, p]
  1003.  
  1004. PointEC /: n_ * PointEC[x_, y_, g2_, g3_, p_]:= 
  1005.                  (-n) * PointEC[x, -y, g2, g3, p] /; n < 0
  1006.  
  1007. PointEC /: n_ * PointEC[x_, y_, g2_, g3_, p_]:= 
  1008.   Fold[2 #1 + #2&, IdentityEC, 
  1009.        IntegerDigits[n, 2] PointEC[x, y, g2, g3, p]]  /; 2 < n  <= 2^100 
  1010.  
  1011. (* For large n use base 16 to speed up the calculation by 25-> 50%.
  1012.    If used repeatedly, precompute digits in main algorithm. *)
  1013.  
  1014.  
  1015. PointEC /: n_ * PointEC[x_, y_, g2_, g3_, p_]:= 
  1016.   Fold[16 #1 + #2&, IdentityEC, 
  1017.        NestList[# + PointEC[x, y, g2, g3, p]&, 
  1018.                 IdentityEC, 15] [[IntegerDigits[n, 16] + 1]]] /; n > 2^100
  1019.  
  1020.  
  1021.  
  1022. (* Elliptic curve multiplication in homogeneous form (no GCD's),
  1023.    as in Bressoud's book, p. 213. *)
  1024.  
  1025. (* X coordinate of 2*P. *)
  1026.  
  1027. double[{x_, z_, g2_, g3_, m_}]:= 
  1028. Block[{x2 = Mod[x^2, m], z2 = Mod[z^2, m], bz3},
  1029.        bz3 = g3 Mod[z2 z, m]; 
  1030.        {Mod[(x2 - Mod[g2 z2, m])^2 - 8 x bz3, m],
  1031.         Mod[4 z Mod[Mod[x2 x, m] + g2 Mod[x z2, m] + bz3, m], m]}
  1032.       ]    
  1033.  
  1034.  
  1035. (* X coordinate of (2i+1)*P from i*P and (i+1)*P. *)
  1036.  
  1037. doubleplusone[{x1_, z1_, xi_, zi_, xi1_, zi1_, g2_, g3_, m_}]:= 
  1038. Block[{zizi1 = Mod[zi zi1, m], xi1zi = Mod[xi1 zi, m],
  1039.        xizi1 = Mod[xi zi1, m]},
  1040.       {Mod[z1 Mod[PowerMod[xi xi1 - g2 zizi1, 2, m] -
  1041.                   4 g3 Mod[zizi1 (xizi1 + xi1zi), m], m], m],
  1042.        Mod[x1 PowerMod[xi1zi - xizi1, 2, m], m]}
  1043.      ] 
  1044.    
  1045.  
  1046. (* X coordinate of {2i*P, (2i+1)*P} from {i*P, (i+1)*P}. *)
  1047.  
  1048. even[{x1_, z1_, xn_, zn_, xm_, zm_, g2_, g3_, m_}]:= 
  1049. Join[{x1, z1}, double[{xn, zn, g2, g3, m}], 
  1050.      doubleplusone[{x1, z1, xn, zn, xm, zm, g2, g3, m}], {g2, g3, m}]
  1051.  
  1052. (* X coordinate of {(2i+1)*P, (2i+2)*P} from {i*P, (i+1)*P} *)
  1053.  
  1054. odd[{x1_, z1_, xn_, zn_, xm_, zm_, g2_, g3_, m_}]:= 
  1055. Join[{x1, z1}, doubleplusone[{x1, z1, xn, zn, xm, zm, g2, g3, m}], 
  1056.      double[{xm, zm, g2, g3,  m}], {g2, g3, m}]
  1057.  
  1058. (* Compute n*P, where P has X coordinate x1:z1. *)
  1059.  
  1060. mult[{x1_, z1_}, n_, g2_, g3_,  m_]:= 
  1061.      Fold[If[#2 == 0, even[#1], odd[#1]]&,
  1062.           Join[{x1, z1}, {x1,z1},double[{x1, z1, g2, g3, m}], {g2, g3, m}],
  1063.                Rest[IntegerDigits[n, 2]]] [[{3,4}]]
  1064.  
  1065. (* This is the same as mult but multiplies together all the 
  1066.    intermediate zi's in order to see whether a spurious 
  1067.    factor of p exists. *) 
  1068.  
  1069. multcheckprime[{x1_, z1_}, n_, g2_, g3_,  m_]:= 
  1070.   Fold[Join[{Mod[#1[[1]] #1[[5]] #1[[7]], m]}, 
  1071.              If[#2 == 0, even[Rest[#1]], odd[Rest[#1]]]]&,
  1072.        Join[{1}, {x1, z1}, {x1,z1}, double[{x1, z1, g2, g3, m}], {g2, g3, m}],
  1073.             Rest[IntegerDigits[n, 2]]] [[{1, 4, 5}]]
  1074.  
  1075. Protect[ProvablePrimeQ, PrimeQCertificateCheck, (* PrimeQCertificate, *)
  1076.         SmallPrime, Certificate, TrialDivisionLimit, PollardPTest,
  1077.         PollardRhoTest, ModularInvariantj, HilbertPolynomial, fact,
  1078.         CertificatePrime, CertificatePoint, CertificateK, CertificateM,
  1079.         CertificateNextPrime, CertificateDiscriminant, PointEC, PointECQ]
  1080.  
  1081.  
  1082. End[]
  1083.  
  1084.  
  1085. EndPackage[]
  1086.