00001 #include "polphi_template.H"
00002 #include "my_mpz_powm_ui.cc"
00003
00010 class CRingPhi
00011 {
00012 private:
00013 mpz_t a;
00014 public:
00015 static const std::string name;
00016 static const int SieveIntervalSize=2*3*5*7*11*13*17;
00017 CRingPhi() { mpz_init(a); }
00018 CRingPhi(const CRingPhi &x) { mpz_init_set(a,x.a); }
00019 ~CRingPhi() { mpz_clear(a); }
00020 bool set_startvalue(const unsigned int seed=1) { mpz_set_ui(a,seed+1); return true; }
00021 void set(const CRingPhi &x) { mpz_set(a,x.a); }
00022 void pow_mod(const unsigned int i, const mpz_t M) { mpz_powm_ui(a,a,i,M); }
00023 void fast_pow_mod(const unsigned int i, const mpz_t M) { my_mpz_powm_ui(a,i,M); }
00024 void test_gcd(mpz_t x, const mpz_t M) { mpz_sub_ui(x,a,1); mpz_gcd(x,x,M); }
00025 friend class CRingPhiPhase2;
00026 };
00027 const std::string CRingPhi::name = "phi";
00028
00029 class CRingPhiPhase2 : private ForbidAssignment
00030 {
00031 private:
00032 CRingPhi a;
00033 mpz_t b_inv, b, d, d_inv, b_plus_b_inv, d_plus_d_inv, prev_b_plus_b_inv,
00034 temp1, temp2;
00035
00036 public:
00037 explicit CRingPhiPhase2(const CRingPhi &_a) : a(_a)
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
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 mpz_init(b); mpz_init(b_inv); mpz_init(d); mpz_init(d_inv); mpz_init(b_plus_b_inv);
00076 mpz_init(d_plus_d_inv); mpz_init(prev_b_plus_b_inv);
00077 mpz_init(temp1); mpz_init(temp2);
00078
00079
00080
00081
00082
00083 mpz_set(b,a.a); mpz_invert(b_inv,b,n); mpz_mod(b_inv,b_inv,n);
00084 mpz_powm_ui(d,b,2,n); mpz_powm_ui(d_inv,b_inv,2,n);
00085 mpz_add(d_plus_d_inv,d,d_inv); mpz_mod(d_plus_d_inv,d_plus_d_inv,n);
00086 mpz_add(b_plus_b_inv,b,b_inv); mpz_mod(b_plus_b_inv,b_plus_b_inv,n);
00087 mpz_set(prev_b_plus_b_inv,b_plus_b_inv);
00088
00089 }
00090 ~CRingPhiPhase2()
00091 {
00092 mpz_clear(b); mpz_clear(b_inv); mpz_clear(d); mpz_clear(d_inv); mpz_clear(b_plus_b_inv);
00093 mpz_clear(d_plus_d_inv); mpz_clear(prev_b_plus_b_inv);
00094 mpz_clear(temp1); mpz_clear(temp2);
00095 }
00096
00097 void get_polynomdef_point(mpz_t x)
00098 {
00099 mpz_set(x,b_plus_b_inv);
00100 }
00101
00102 void calc_polynomdef_next_point()
00103 {
00104 mpz_set(temp1,prev_b_plus_b_inv); mpz_set(prev_b_plus_b_inv,b_plus_b_inv);
00105 mpz_mul(b_plus_b_inv,b_plus_b_inv,d_plus_d_inv);
00106 mpz_sub(b_plus_b_inv,b_plus_b_inv,temp1);
00107 mpz_mod(b_plus_b_inv,b_plus_b_inv,n);
00108 }
00109
00110 void calc_EvalStartingPoint(const int D, const double ii)
00111 {
00112 mpz_powm_ui(d,a.a,D,n); mpz_invert(d_inv,d,n); mpz_mod(d_inv,d_inv,n);
00113 mpz_add(d_plus_d_inv,d,d_inv); mpz_mod(d_plus_d_inv,d_plus_d_inv,n);
00114 mpz_set_d(temp1,ii); mpz_powm(b,a.a,temp1,n);
00115 mpz_invert(b_inv,b,n); mpz_mod(b_inv,b_inv,n);
00116 mpz_add(b_plus_b_inv,b,b_inv); mpz_mod(b_plus_b_inv,b_plus_b_inv,n);
00117 mpz_mul(temp1,b,d_inv); mpz_mod(temp1,temp1,n);
00118 mpz_mul(temp2,b_inv,d); mpz_mod(temp2,temp2,n);
00119 mpz_add(prev_b_plus_b_inv,temp1,temp2); mpz_mod(prev_b_plus_b_inv,prev_b_plus_b_inv,n);
00120 }
00121
00122 void get_point_and_calc_next_point(mpz_t x)
00123 {
00124 mpz_set(x,prev_b_plus_b_inv); mpz_set(prev_b_plus_b_inv,b_plus_b_inv);
00125 mpz_mul(b_plus_b_inv,b_plus_b_inv,d_plus_d_inv);
00126 mpz_sub(b_plus_b_inv,b_plus_b_inv,x);
00127 mpz_mod(b_plus_b_inv,b_plus_b_inv,n);
00128 mpz_set(x,prev_b_plus_b_inv);
00129 }
00130
00131 };
00132
00133
00134
00135 template void polphi_template<CRingPhi,CRingPhiPhase2>(const int phase1, const double phase2);
00136
00137 #define pollard_phi(phase1,phase2) polphi_template<CRingPhi,CRingPhiPhase2>(phase1,phase2)
00138