00001 #ifndef ECM_HEADER_
00002 #define ECM_HEADER_
00003
00004
00005
00006
00007
00013 #include <iosfwd>
00014 #include <gmp.h>
00015 #include "utils.H"
00016 #include "mpz_wrapper.H"
00017 using namespace my_mpz_wrapper;
00018
00019 using std::ostream;
00020 using std::istream;
00021
00022 using std::cout;
00023 using std::cerr;
00024 using std::flush;
00025
00026 extern mpz_t n;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #if defined(NRESIDUE) && defined (MODULAR_ARITHMETIC)
00065 #error "You must not define both: NRESIDUE and MODULAR_ARITHMETIC"
00066 #endif
00067
00068 #if ! ( defined(NRESIDUE) || defined(MODULAR_ARITHMETIC) )
00069
00070 #define mpz_mulmod(res,a,b,n) { mpz_mul(res,a,b); mpz_mod(res,res,n); }
00071 #define modulo(res,T,n) mpz_mod(res,T,n)
00072 #endif
00073
00074 #ifdef NRESIDUE
00075 #include "modular_mult.cc"
00076
00077
00078
00079
00080
00081
00082
00083 #define mpz_mulmod(res,a,b,n) { mpz_mul(res,a,b); NResidue.redc(res,res); }
00084 #define modulo(res,T,n) NResidue.redc(res,T)
00085 #endif
00086
00087 #ifdef MODULAR_ARITHMETIC
00088 #include "modular_arithmetic.cc"
00089 #define mpz_mulmod(res,a,b,n) { mpz_mul(res,a,b); NResidue.mod(res,res); }
00090 #define modulo(res,T,n) NResidue.mod(res,T)
00091 #endif
00092
00093
00094 #if (CONTINUATION_METHOD > 0)
00095 #include "polynomial.H"
00096 #endif
00097
00098 #if defined(DEBUG_ECM) && (!defined(SLOW_WEIERSTRASS) || defined(NRESIDUE))
00099 #error "DEBUG_ECM works only in SLOW_WEIERSTRASS-Mode without NRESIDUE!"
00100 #endif
00101
00102
00104 class TmpzPoint : private ForbidAssignment
00105 {
00106 public:
00107 mpz_t x,z;
00108 inline TmpzPoint() { mpz_init(x); mpz_init(z); }
00109 inline ~TmpzPoint() { mpz_clear(z); mpz_clear(x); }
00110 };
00111 typedef TmpzPoint* PmpzPoint;
00112 typedef const TmpzPoint* PconstmpzPoint;
00113
00114
00116 class elliptic_curves : private ForbidAssignment
00117 {
00118 public:
00119 typedef long long int NATNUM;
00120 private:
00121 mpz_t a,b;
00122 mpz_t h,k,m;
00123 mpz_t x3,y3;
00124 mpz_t xh_mul, yh_mul;
00125 PmpzPoint A,B,C,T1,T2;
00126 int sigma;
00127 int phase;
00128 #ifdef NRESIDUE
00129 CN_Residue NResidue;
00130 #endif
00131 #ifdef MODULAR_ARITHMETIC
00132 CN_Residue NResidue;
00133 #endif
00134 public:
00135 inline elliptic_curves()
00136 : A(new TmpzPoint), B(new TmpzPoint), C(new TmpzPoint),
00137 T1(new TmpzPoint), T2(new TmpzPoint), sigma(-1), phase(-1)
00138 #ifdef NRESIDUE
00139 , NResidue()
00140
00141
00142
00143
00144
00145
00146
00147
00148 #endif
00149 #ifdef MODULAR_ARITHMETIC
00150 , NResidue()
00151
00152
00153
00154
00155
00156
00157
00158
00159 #endif
00160 {
00161 mpz_init(a); mpz_init(b);
00162 mpz_init(h); mpz_init(k); mpz_init(m);
00163 mpz_init(x3); mpz_init(y3);
00164 mpz_init(xh_mul); mpz_init(yh_mul);
00165 #ifdef NRESIDUE
00166 NResidue.init(n);
00167 #endif
00168 #ifdef MODULAR_ARITHMETIC
00169 NResidue.init(n);
00170 #endif
00171 }
00172 inline ~elliptic_curves()
00173 {
00174 mpz_clear(a); mpz_clear(b);
00175 mpz_clear(h); mpz_clear(k); mpz_clear(m);
00176 mpz_clear(x3); mpz_clear(y3);
00177 mpz_clear(xh_mul); mpz_clear(yh_mul);
00178 delete A; delete B; delete C; delete T1; delete T2;
00179 }
00180 private:
00181 void check_curve(const mpz_t x, const mpz_t y) const;
00182 void factor_found(mpz_t k) const;
00183
00184 bool sub(mpz_t xr, mpz_t yr,
00185 const mpz_t x1, const mpz_t y1,
00186 const mpz_t x2, const mpz_t y2);
00187 bool add(mpz_t xr, mpz_t yr,
00188 const mpz_t x1, const mpz_t y1,
00189 const mpz_t x2, const mpz_t y2);
00190 bool mul2(mpz_t xr, mpz_t yr, const mpz_t x1, const mpz_t y1);
00191 bool mul(mpz_t xr, mpz_t yr,
00192 const mpz_t x1, const mpz_t y1,
00193 NATNUM K);
00194 bool add(mpz_t xr, mpz_t yr,
00195 const mpz_t x1, const mpz_t y1,
00196 const mpz_t x2, const mpz_t y2,
00197 mpz_t k);
00198 bool init_arithmetic_progression(mpz_t* const x, mpz_t* const y,
00199 const mpz_t startx, const mpz_t starty, const NATNUM startpos,
00200 const unsigned int delta, const unsigned int grad);
00201 bool arithmetic_progression(mpz_t* const x, mpz_t* const y, const int anz);
00202
00203 void XZ_mul2(mpz_t xr, mpz_t zr,
00204 const mpz_t x1, const mpz_t z1);
00205 inline void XZ_mul2(const PmpzPoint R, const PconstmpzPoint A)
00206 { XZ_mul2(R->x,R->z,A->x,A->z); }
00207 void XZ_mul2plus1(mpz_t xr, mpz_t zr,
00208 const mpz_t Xp0, const mpz_t Zp0,
00209 const mpz_t Xp1, const mpz_t Zp1,
00210 const mpz_t x1, const mpz_t z1);
00211 inline void XZ_mul2plus1(const PmpzPoint R, const PconstmpzPoint A, const PconstmpzPoint B, const PconstmpzPoint C)
00212 { XZ_mul2plus1(R->x,R->z,A->x,A->z,B->x,B->z,C->x,C->z); }
00213
00214 static unsigned int cost_of_evaluating_lucas_chain(const NATNUM K, const double alpha);
00215 void XZ_multiply(mpz_t xr, mpz_t zr, const mpz_t x1, const mpz_t z1, NATNUM K);
00216
00217 public:
00218 void go(const int ecm_sigma, NATNUM phase1, const NATNUM phase2);
00219 inline void go(const int ecm_sigma, const int phase1, const int phase2)
00220 {
00221 go(ecm_sigma,static_cast<NATNUM>(phase1),static_cast<NATNUM>(phase2));
00222 }
00223 inline void go(const int ecm_sigma, const double phase1, const double phase2)
00224 {
00225 go(ecm_sigma,static_cast<NATNUM>(phase1),static_cast<NATNUM>(phase2));
00226 }
00227
00228 };
00229
00230 #endif