Line data Source code
1 : /* factor.c - public interface for libecm.
2 :
3 : Copyright 2005, 2006, 2007, 2009, 2011, 2020 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 *
30 5906 : ecm_version ()
31 : {
32 : static const char *version = ECM_VERSION;
33 5906 : return version;
34 : }
35 :
36 : void
37 3116 : ecm_init (ecm_params q)
38 : {
39 3116 : __ell_curve_struct *ptrE = (__ell_curve_struct *) malloc(sizeof(__ell_curve_struct));
40 :
41 3116 : q->method = ECM_ECM; /* default method */
42 3116 : mpz_init_set_ui (q->x, 0);
43 3116 : mpz_init_set_ui (q->y, 0);
44 3116 : mpz_init_set_ui (q->sigma, 0);
45 3116 : q->sigma_is_A = 0;
46 3116 : mpz_init_set_ui (ptrE->a1, 0);
47 3116 : mpz_init_set_ui (ptrE->a3, 0);
48 3116 : mpz_init_set_ui (ptrE->a2, 0);
49 3116 : mpz_init_set_ui (ptrE->a4, 0);
50 3116 : mpz_init_set_ui (ptrE->a6, 0);
51 3116 : ptrE->type = ECM_EC_TYPE_MONTGOMERY;
52 3116 : ptrE->disc = 0;
53 3116 : mpz_init_set_ui (ptrE->sq[0], 1);
54 3116 : q->E = ptrE;
55 3116 : q->param = ECM_PARAM_DEFAULT;
56 3116 : mpz_init_set_ui (q->go, 1);
57 3116 : q->B1done = ECM_DEFAULT_B1_DONE;
58 3116 : mpz_init_set_si (q->B2min, -1.0); /* default: B2min will be set to B1 */
59 3116 : mpz_init_set_si (q->B2, ECM_DEFAULT_B2);
60 3116 : q->k = ECM_DEFAULT_K;
61 3116 : q->S = ECM_DEFAULT_S; /* automatic choice of polynomial */
62 3116 : q->repr = ECM_MOD_DEFAULT; /* automatic choice of representation */
63 3116 : q->nobase2step2 = 0; /* continue special base 2 code in ecm step 2, if used */
64 3116 : q->verbose = 0; /* no output (default in library mode) */
65 3116 : q->os = stdout; /* standard output */
66 3116 : q->es = stderr; /* error output */
67 3116 : q->chkfilename = NULL;
68 3116 : q->TreeFilename = NULL;
69 3116 : q->maxmem = 0.0;
70 3116 : q->stage1time = 0.0;
71 3116 : gmp_randinit_default (q->rng);
72 3116 : mpz_set_ui (q->rng->_mp_seed, 0); /* trick to tell that the random number
73 : generator has not been initialized */
74 3116 : q->use_ntt = 1;
75 3116 : q->stop_asap = NULL;
76 3116 : q->batch_last_B1_used = 1.0;
77 3116 : mpz_init_set_ui (q->batch_s, 1);
78 3116 : q->gpu = 0; /* no gpu by default in library mode */
79 3116 : q->gpu_device = -1;
80 3116 : q->gpu_device_init = 0;
81 3116 : q->gpu_number_of_curves = 0;
82 3116 : q->gw_k = 0.0;
83 3116 : q->gw_b = 0;
84 3116 : q->gw_n = 0;
85 3116 : q->gw_c = 0;
86 3116 : }
87 :
88 : /* function to be called between two calls of ecm_factor, it the same
89 : ecm_params q is reused */
90 : void
91 0 : ecm_reset (ecm_params q)
92 : {
93 0 : mpz_set_ui (q->sigma, 0);
94 0 : q->B1done = ECM_DEFAULT_B1_DONE;
95 0 : mpz_set_ui (q->x, 0);
96 0 : }
97 :
98 : void
99 2474 : ecm_clear (ecm_params q)
100 : {
101 2474 : mpz_clear (q->x);
102 2474 : mpz_clear (q->y);
103 2474 : mpz_clear (q->sigma);
104 2474 : mpz_clear (q->go);
105 2474 : mpz_clear (q->B2min);
106 2474 : mpz_clear (q->B2);
107 2474 : gmp_randclear (q->rng);
108 2474 : mpz_clear (q->batch_s);
109 2474 : mpz_clear (q->E->a1);
110 2474 : mpz_clear (q->E->a3);
111 2474 : mpz_clear (q->E->a2);
112 2474 : mpz_clear (q->E->a4);
113 2474 : mpz_clear (q->E->a6);
114 2474 : mpz_clear (q->E->sq[0]);
115 2474 : free (q->E);
116 2474 : }
117 :
118 : /* returns ECM_FACTOR_FOUND, ECM_NO_FACTOR_FOUND, or ECM_ERROR */
119 : int
120 2169 : ecm_factor (mpz_t f, mpz_t n, double B1, ecm_params p0)
121 : {
122 : int res; /* return value */
123 : ecm_params q;
124 : ecm_params_ptr p;
125 :
126 2169 : if (mpz_cmp_ui (n, 0) <= 0)
127 : {
128 10 : fprintf ((p0 == NULL) ? stderr : p0->es,
129 : "Error, n should be positive.\n");
130 10 : return ECM_ERROR;
131 : }
132 2159 : else if (mpz_cmp_ui (n, 1) == 0)
133 : {
134 : /* we consider n=1 is fully factored (thus in step 1) */
135 0 : mpz_set_ui (f, 1);
136 0 : return ECM_FACTOR_FOUND_STEP1;
137 : }
138 2159 : else if (mpz_divisible_2exp_p (n, 1))
139 : {
140 30 : mpz_set_ui (f, 2);
141 30 : return ECM_FACTOR_FOUND_STEP1;
142 : }
143 :
144 2129 : if (p0 == NULL)
145 : {
146 0 : p = q;
147 0 : ecm_init (q);
148 : }
149 : else
150 2129 : p = p0;
151 :
152 2129 : if (p->method == ECM_ECM)
153 : {
154 : #ifdef WITH_GPU
155 : if (p->gpu == 0)
156 : {
157 : #endif
158 1588 : res = ecm (f, p->x, p->y, p->param, p->sigma, n, p->go,
159 : &(p->B1done),
160 1588 : B1, p->B2min, p->B2, p->k, p->S, p->verbose,
161 : p->repr, p->nobase2step2, p->use_ntt,
162 : p->sigma_is_A, p->E,
163 : p->os, p->es, p->chkfilename, p->TreeFilename, p->maxmem,
164 1588 : p->stage1time, p->rng, p->stop_asap, p->batch_s,
165 : &(p->batch_last_B1_used), p->gw_k, p->gw_b, p->gw_n,
166 : p->gw_c);
167 : #ifdef WITH_GPU
168 : }
169 : else
170 : {
171 : res = gpu_ecm (f, p->x, p->param, p->sigma, n, p->go,
172 : &(p->B1done), B1, p->B2min, p->B2, p->k,
173 : p->S, p->verbose, p->repr, p->nobase2step2,
174 : p->use_ntt, p->sigma_is_A, p->os, p->es,
175 : p->chkfilename, p->TreeFilename, p->maxmem,
176 : p->stop_asap, p->batch_s, &(p->batch_last_B1_used),
177 : p->gpu_cgbn, p->gpu_device, &(p->gpu_device_init),
178 : &(p->gpu_number_of_curves));
179 : }
180 : #endif
181 : }
182 541 : else if (p->method == ECM_PM1)
183 272 : res = pm1 (f, p->x, n, p->go, &(p->B1done), B1, p->B2min, p->B2,
184 : p->k, p->verbose, p->repr, p->use_ntt, p->os, p->es,
185 272 : p->chkfilename, p->TreeFilename, p->maxmem, p->rng,
186 : p->stop_asap);
187 269 : else if (p->method == ECM_PP1)
188 269 : res = pp1 (f, p->x, n, p->go, &(p->B1done), B1, p->B2min, p->B2,
189 : p->k, p->verbose, p->repr, p->use_ntt, p->os, p->es,
190 269 : p->chkfilename, p->TreeFilename, p->maxmem, p->rng,
191 : p->stop_asap);
192 : else
193 : {
194 0 : fprintf (p->es, "Error, unknown method: %d\n", p->method);
195 0 : res = ECM_ERROR;
196 : }
197 :
198 2129 : if (p0 == NULL)
199 0 : ecm_clear (q);
200 :
201 2129 : return res;
202 : }
|