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