1 /* factor.c - public interface for libecm.
2 
3 Copyright 2005, 2006, 2007, 2009, 2011 Paul Zimmermann, Alexander Kruppa,
4 David Cleaver, Cyril Bouvier.
5 
6 This file is part of the ECM Library.
7 
8 The ECM Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 The ECM Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public License
19 along with the ECM Library; see the file COPYING.LIB.  If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 
23 #include <stdio.h>
24 #include <math.h>
25 #include "ecm-impl.h"
26 #include "ecm-gpu.h"
27 
28 
29 const char *
ecm_version()30 ecm_version ()
31 {
32   static const char *version = ECM_VERSION;
33   return version;
34 }
35 
36 void
ecm_init(ecm_params q)37 ecm_init (ecm_params q)
38 {
39   __ell_curve_struct *ptrE = (__ell_curve_struct *) malloc(sizeof(__ell_curve_struct));
40 
41   q->method = ECM_ECM; /* default method */
42   mpz_init_set_ui (q->x, 0);
43   mpz_init_set_ui (q->y, 0);
44   mpz_init_set_ui (q->sigma, 0);
45   q->sigma_is_A = 0;
46   mpz_init_set_ui (ptrE->a1, 0);
47   mpz_init_set_ui (ptrE->a3, 0);
48   mpz_init_set_ui (ptrE->a2, 0);
49   mpz_init_set_ui (ptrE->a4, 0);
50   mpz_init_set_ui (ptrE->a6, 0);
51   ptrE->type = ECM_EC_TYPE_MONTGOMERY;
52   ptrE->disc = 0;
53   mpz_init_set_ui (ptrE->sq[0], 1);
54   q->E = ptrE;
55   q->param = ECM_PARAM_DEFAULT;
56   mpz_init_set_ui (q->go, 1);
57   q->B1done = ECM_DEFAULT_B1_DONE;
58   mpz_init_set_si (q->B2min, -1.0); /* default: B2min will be set to B1 */
59   mpz_init_set_si (q->B2, ECM_DEFAULT_B2);
60   q->k = ECM_DEFAULT_K;
61   q->S = ECM_DEFAULT_S; /* automatic choice of polynomial */
62   q->repr = ECM_MOD_DEFAULT; /* automatic choice of representation */
63   q->nobase2step2 = 0; /* continue special base 2 code in ecm step 2, if used */
64   q->verbose = 0; /* no output (default in library mode) */
65   q->os = stdout; /* standard output */
66   q->es = stderr; /* error output */
67   q->chkfilename = NULL;
68   q->TreeFilename = NULL;
69   q->maxmem = 0.0;
70   q->stage1time = 0.0;
71   gmp_randinit_default (q->rng);
72   mpz_set_ui (q->rng->_mp_seed, 0); /* trick to tell that the random number
73                                        generator has not been initialized */
74   q->use_ntt = 1;
75   q->stop_asap = NULL;
76   q->batch_last_B1_used = 1.0;
77   mpz_init_set_ui (q->batch_s, 1);
78   q->gpu = 0; /* no gpu by default in library mode */
79   q->gpu_device = -1;
80   q->gpu_device_init = 0;
81   q->gpu_number_of_curves = 0;
82   q->gw_k = 0.0;
83   q->gw_b = 0;
84   q->gw_n = 0;
85   q->gw_c = 0;
86 }
87 
88 void
ecm_clear(ecm_params q)89 ecm_clear (ecm_params q)
90 {
91   mpz_clear (q->x);
92   mpz_clear (q->y);
93   mpz_clear (q->sigma);
94   mpz_clear (q->go);
95   mpz_clear (q->B2min);
96   mpz_clear (q->B2);
97   gmp_randclear (q->rng);
98   mpz_clear (q->batch_s);
99   mpz_clear (q->E->a1);
100   mpz_clear (q->E->a3);
101   mpz_clear (q->E->a2);
102   mpz_clear (q->E->a4);
103   mpz_clear (q->E->a6);
104   mpz_clear (q->E->sq[0]);
105   free (q->E);
106 }
107 
108 /* returns ECM_FACTOR_FOUND, ECM_NO_FACTOR_FOUND, or ECM_ERROR */
109 int
ecm_factor(mpz_t f,mpz_t n,double B1,ecm_params p0)110 ecm_factor (mpz_t f, mpz_t n, double B1, ecm_params p0)
111 {
112   int res; /* return value */
113   ecm_params q;
114   ecm_params_ptr p;
115 
116   if (mpz_cmp_ui (n, 0) <= 0)
117     {
118       fprintf ((p0 == NULL) ? stderr : p0->es,
119                "Error, n should be positive.\n");
120       return ECM_ERROR;
121     }
122   else if (mpz_cmp_ui (n, 1) == 0)
123     {
124       mpz_set_ui (f, 1);
125       return ECM_FACTOR_FOUND_STEP1;
126     }
127   else if (mpz_divisible_2exp_p (n, 1))
128     {
129       mpz_set_ui (f, 2);
130       return ECM_FACTOR_FOUND_STEP1;
131     }
132 
133   if (p0 == NULL)
134     {
135       p = q;
136       ecm_init (q);
137     }
138   else
139     p = p0;
140 
141   if (p->method == ECM_ECM)
142     {
143 #ifdef WITH_GPU
144       if (p->gpu == 0)
145         {
146 #endif
147             res = ecm (f, p->x, p->y, &(p->param), p->sigma, n, p->go,
148 		       &(p->B1done),
149                        B1, p->B2min, p->B2, p->k, p->S, p->verbose,
150                        p->repr, p->nobase2step2, p->use_ntt,
151 		       p->sigma_is_A, p->E,
152                        p->os, p->es, p->chkfilename, p->TreeFilename, p->maxmem,
153                        p->stage1time, p->rng, p->stop_asap, p->batch_s,
154                        &(p->batch_last_B1_used), p->gw_k, p->gw_b, p->gw_n,
155                        p->gw_c);
156 #ifdef WITH_GPU
157         }
158       else
159         {
160           res = gpu_ecm (f, p->x, &(p->param), p->sigma, n, p->go,
161                          &(p->B1done), B1, p->B2min, p->B2, p->k,
162                          p->S, p->verbose, p->repr, p->nobase2step2,
163                          p->use_ntt, p->sigma_is_A, p->os, p->es,
164                          p->chkfilename, p->TreeFilename, p->maxmem,
165                          p->stop_asap, p->batch_s, &(p->batch_last_B1_used),
166                          p->gpu_device, &(p->gpu_device_init),
167                          &(p->gpu_number_of_curves));
168         }
169 #endif
170     }
171   else if (p->method == ECM_PM1)
172     res = pm1 (f, p->x, n, p->go, &(p->B1done), B1, p->B2min, p->B2,
173                p->k, p->verbose, p->repr, p->use_ntt, p->os, p->es,
174                p->chkfilename, p->TreeFilename, p->maxmem, p->rng,
175                p->stop_asap);
176   else if (p->method == ECM_PP1)
177     res = pp1 (f, p->x, n, p->go, &(p->B1done), B1, p->B2min, p->B2,
178                p->k, p->verbose, p->repr, p->use_ntt, p->os, p->es,
179                p->chkfilename, p->TreeFilename, p->maxmem, p->rng,
180                p->stop_asap);
181   else
182     {
183       fprintf (p->es, "Error, unknown method: %d\n", p->method);
184       res = ECM_ERROR;
185     }
186 
187   if (p0 == NULL)
188     ecm_clear (q);
189 
190   return res;
191 }
192