00001 #ifndef CmpqsFactor_header
00002 #define CmpqsFactor_header
00003
00009 #include <cstdlib>
00010 #include <iosfwd>
00011 #include <gmp.h>
00012 #include "utils.H"
00013 #include "mpz_wrapper.H"
00014 using namespace my_mpz_wrapper;
00015
00016 using std::ostream;
00017 using std::istream;
00018
00019 using std::cout;
00020 using std::cerr;
00021
00022 extern const int SingleLargePrime_Threshold;
00023
00024
00035 class CmpqsFactortypes
00036 {
00037 public:
00038 enum Factortype { empty, static_prime, single_large_prime, double_large_prime, Factortype_size };
00039 };
00040
00051 class CmpqsFactor : public CmpqsFactortypes
00052 {
00053 private:
00054
00056 unsigned int p1,p2;
00057
00059 static double rejected_dlp_counter;
00060
00061 public:
00062
00064 static mpz_t DLP_Threshold;
00065
00067 static inline bool DLP_rejected(const mpz_t n)
00068 {
00069 if (mpz_cmp(n,DLP_Threshold)>0)
00070 {
00071 rejected_dlp_counter+=1.0;
00072 return true;
00073 }
00074
00075 return mpz_probab_prime_p(n,10)!=0;
00076 }
00077
00079 bool DLP_get_using_pollard_rho(const mpz_t n);
00080
00092 bool DLP_get(const mpz_t n);
00093
00095 inline const CmpqsFactor& operator= (const unsigned int x)
00096 { p1=0; p2=x; return *this; }
00097
00099 inline int int_value() const
00100 {
00101
00102 if (p1)
00103 {
00104 cerr << "Cannot assign two integers to a single integer value!" << endl;
00105 exit(1);
00106 return 0;
00107 }
00108 return p2;
00109 }
00110
00112 inline int LP1() const { return p1; }
00113
00115 inline int LP2() const { return p2; }
00116
00127 inline void set_for_search(const unsigned int x)
00128 {
00129
00130 p1=x; p2=0;
00131 }
00132
00134 inline void swap(void) { unsigned int h=p1; p1=p2; p2=h; }
00135
00137 inline void assign_to_mpz(mpz_t x) const
00138 {
00139 if (p1==0) { mpz_set_ui(x,p2); return; }
00140 if (p2==0) { mpz_set_ui(x,p1); return; }
00141 mpz_set_ui(x,p1); mpz_mul_ui(x,x,p2);
00142 }
00143
00150 inline Factortype Type() const
00151 {
00152 if (p1>p2)
00153 { cerr << "CmpqsFactor: unordered factors!" << endl; }
00154 if (p1==0 && p2==0) return empty;
00155 if (p1==0 && p2==1) return static_prime;
00156 if (p1==0) return single_large_prime;
00157 return double_large_prime;
00158 }
00159
00160 inline bool IsTypeOf(const Factortype givenType) const
00161 {
00162 return Type()==givenType;
00163 }
00164
00166 inline bool DLP_divisible_by(const unsigned int x) const
00167 { return p1==x || p2==x; }
00168
00169 inline bool operator< (const CmpqsFactor &x) const
00170 {
00171 if (p1==x.p1) return p2<x.p2;
00172 else return p1<x.p1;
00173 }
00174
00175 inline bool operator== (const CmpqsFactor &x) const
00176 {
00177 return (p1==x.p1 && p2==x.p2);
00178 }
00179
00180 inline bool operator!= (const CmpqsFactor &x) const
00181 {
00182 return !((*this)==x);
00183 }
00184
00186 inline int operator/ (const unsigned int u) const
00187 {
00188
00189 if (p1==u) return p2;
00190 if (p2==u) return p1;
00191 cerr << "CmpqsFactor: invalid division!" << endl;
00192 exit(1);
00193 return 0;
00194 }
00195
00197 friend ostream& operator<< (ostream &ostr, const CmpqsFactor &x);
00198
00200 friend istream& operator>> (istream &istr, CmpqsFactor &x);
00201 };
00202
00203
00204 inline ostream& operator<< (ostream &ostr, const CmpqsFactor &x)
00205 {
00206 if (x.p1) ostr << x.p1 << "*" << x.p2;
00207 else ostr << x.p2;
00208 return ostr;
00209 }
00210
00211 #endif