00001
00007 #include "at_startup.H"
00008
00009
00010 #ifdef IS_CLIENT
00011 #error "qsieve is not a client!"
00012 #endif
00013
00014 #ifdef IS_SERVER
00015 #error "qsieve is not a server!"
00016 #endif
00017
00018 #ifdef USE_NETWORK
00019 #error "qsieve uses no network features!"
00020 #endif
00021
00022 #ifndef IS_STANDALONE
00023 #error "qsieve is a standalone application!"
00024 #endif
00025
00026
00027
00028 extern "C"
00029 {
00030 #include <unistd.h>
00031 }
00032
00033 #include <cstdio>
00034 #include <cstdlib>
00035 #include <fstream>
00036 #include <sstream>
00037 #include <cmath>
00038 #include <gmp.h>
00039 #include <list>
00040 #include <set>
00041 #include <ctime>
00042
00043 #include "qsieve.H"
00044 #include "StaticFactorbase.H"
00045
00046
00047 #include "FactorFound.H"
00048 TFoundFactors FoundFactors;
00049
00050
00051
00052 #include <vector>
00053 #include <stack>
00054 #include <algorithm>
00055
00056
00057 #ifdef NOTIFY_PARENT
00058 #warning "undefining NOTIFY_PARENT, since this is not a networked server"
00059 #undef NOTIFY_PARENT
00060 #endif
00061
00062
00063
00064
00065 const string RecoveryFile = "recovery.dat";
00066 const string FoundFactorsFile = "FoundFactors.dat";
00067 const string StaticRelationsFile = "static_relations.dat";
00068 const string SpecialRelationsFile = "special_relations.dat";
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 filebuf Recovery_buffer;
00084 ostream Recovery_to_file (&Recovery_buffer);
00085 istream Recovery_from_file (&Recovery_buffer);
00086
00087
00088
00089 #include "mpqsPolynom.H"
00090
00091
00092 mpz_t n,
00093 kN;
00094
00095
00096 #include "StaticRelations.H"
00097 #include "DynamicRelations.H"
00098 #include "SpecialRelations.H"
00099
00100 #include "Sieving.H"
00101 #include "ConfigFile.cc"
00102
00103
00104 CmpqsPolynom Polynom;
00105 #include "mpqsStatistics.cc"
00106
00107
00108 #include "modulo.H"
00109 using namespace numtheory;
00110
00111 #include "FactorFound.cc"
00112 #include "polynomial.H"
00113 #include "fft_param.cc"
00114 #include "elliptic_curve.H"
00115 #include "elliptic_curve-variant.cc"
00116
00117 #include "ExitManager.cc"
00118 #include "StaticRelations.cc"
00119
00120
00121 #include "easy_factor.H"
00122
00123
00124
00125 const bool without_multi_combine_init = false;
00126
00127 #include "CRelation-inc.cc"
00128 #include "SpecialRelations.cc"
00129
00130 #include "parse_term.cc"
00131
00132
00133 void process_ecm()
00134 {
00135 streampos fpos = Recovery_from_file.tellg();
00136 int Anzahl_Kurven = 0;
00137 string s;
00138
00139 srand(time(NULL));
00140
00141 unsigned int dezimalstellen = mpz_sizeinbase(n,10);
00142 tune_parameters(dezimalstellen);
00143
00144 Recovery_from_file >> Anzahl_Kurven;
00145 Recovery_from_file.ignore(1,'\n');
00146
00147 {
00148 ifstream in("ecm-recover.dat");
00149 if (in)
00150 {
00151 in.close();
00152 elliptic_curves elliptic_curve;
00153 elliptic_curve.go(-1,elcu_Phase1,elcu_Phase2);
00154 }
00155 }
00156
00157 while (Anzahl_Kurven<elcu_Kurven)
00158 {
00159
00160 Anzahl_Kurven++;
00161 cout << "elliptic curve #" << Anzahl_Kurven << "/" << elcu_Kurven << endl;
00162
00163 int ecm_sigma = rand();
00164 elliptic_curves elliptic_curve;
00165 elliptic_curve.go(ecm_sigma,elcu_Phase1,elcu_Phase2);
00166
00167
00168 Recovery_to_file.seekp(fpos);
00169 Recovery_to_file << Anzahl_Kurven << endl << flush;
00170
00171
00172 if (dezimalstellen==mpz_sizeinbase(n,10)) continue;
00173
00174
00175
00176 if (mpz_probab_prime_p(n,probab_prime_checks))
00177 {
00178 Factorization_to_file << MAL(n);
00179 cout << "remaining factor: " << n << endl;
00180 cout << "remaining factor is most probably prime!" << endl;
00181 mpz_set_ui(n,1);
00182 }
00183
00184 if ( (mpz_cmp_ui(n,1)==0) || Potenztest(n) )
00185 {
00186 cout << "factorization successfully completed." << endl;
00187 Factorization_to_file << endl;
00188 ExitManager::StopFactorization();
00189 }
00190
00191
00192 dezimalstellen=mpz_sizeinbase(n,10);
00193 tune_parameters(dezimalstellen);
00194
00195
00196 Recovery_buffer.close();
00197 Recovery_buffer.open(RecoveryFile.c_str(),ios::in|ios::out|ios::trunc);
00198 Recovery_to_file << n << endl;
00199 fpos = Recovery_from_file.tellg();
00200 Recovery_to_file << Anzahl_Kurven << endl << flush;
00201 ecm_curves_processed=Anzahl_Kurven;
00202
00203 }
00204 cout << "ECM-Phase (standalone) completed." << endl;
00205 }
00206
00207
00208
00209
00210 void cleanup_files()
00211 {
00212 #ifdef VERBOSE_INFO
00213 cout << "cleaning files..." << endl;
00214 #endif
00215 StaticRelations::cleanup_files();
00216 SpecialRelations::cleanup_files();
00217 DynamicRelations::cleanup_files();
00218 Recovery_buffer.close();
00219 remove(RecoveryFile.c_str());
00220 }
00221
00222 void cleanup_memory()
00223 {
00224 #ifdef VERBOSE_INFO
00225 cout << "cleanup allocated memory" << endl;
00226 #endif
00227 StaticRelations::cleanup_memory();
00228 CSieveStaticFactors::destruct();
00229 mpz_clear(CmpqsFactor::DLP_Threshold);
00230 mpz_clear(kN); mpz_clear(n);
00231 }
00232
00233
00234
00235
00236 int main(const int argc, const char* const argv[])
00237 {
00238
00239 #ifdef USE_NCURSES
00240 new Cncursed();
00241 #endif
00242
00243 PrintHeader("Qsieve standalone");
00244
00245 if (argc>2)
00246 {
00247 cerr << "number for factorization expected!" << endl;
00248 exit(1);
00249 }
00250
00251 const bool recover = (argc==1);
00252
00253 cout.setf(ios::fixed);
00254
00255 mpz_init(n);
00256 mpz_init(kN);
00257 ExitManager::register_exithandler(cleanup_memory);
00258
00259 Read_ConfigFile();
00260
00261 if (!recover)
00262 {
00263
00264 char* const neuer_str = strdup(argv[1]);
00265 char* str = neuer_str;
00266 if (!parse_term::get_number(n, str))
00267 {
00268 cout << "Wrong input at: '" << str << "'" << endl;
00269 exit(1);
00270 }
00271 else
00272 if (str[0]!='\0')
00273 {
00274 cout << "Syntax error in input term. (parenthesis?)" << endl;
00275 exit(1);
00276 }
00277 else
00278 if (mpz_cmp_ui(n,0)<=0)
00279 {
00280 cout << "Input must be positive natural number!" << endl;
00281 exit(1);
00282 }
00283 free(neuer_str);
00284 FoundFactors.regarding=argv[1];
00285 mpz_set(FoundFactors.regarding_numeric_value,n);
00286 }
00287
00288 if (recover)
00289 {
00290
00291
00292 StaticRelations::FileBuffer.open(StaticRelationsFile.c_str(),ios::in|ios::out);
00293 SpecialRelations::FileBuffer.open(SpecialRelationsFile.c_str(),ios::in|ios::out);
00294 if (!DynamicRelations::FileBuffer.open(DynamicRelationsFile.c_str(),ios::in|ios::out))
00295 {
00296 cerr << "Cannot access " << DynamicRelationsFile << endl;
00297 exit(1);
00298 }
00299 Recovery_buffer.open(RecoveryFile.c_str(),ios::in|ios::out|ios::ate);
00300
00301
00302
00303 if (Recovery_from_file) Recovery_from_file.seekg(0,ios::end);
00304 #ifdef STL_STREAM_workaround
00305 if ( (!Recovery_from_file) || (Recovery_from_file.tellg()==std::streampos(0)) || (Recovery_from_file.tellg()==std::streampos(-1)) )
00306
00307
00308
00309
00310
00311 #else
00312 if ( (!Recovery_from_file) || (Recovery_from_file.tellg()<1) )
00313 #endif
00314 {
00315 cerr << "Recovery not possible!" << endl;
00316 exit(1);
00317 }
00318
00319 Recovery_from_file.seekg(0,ios::beg);
00320 Recovery_to_file.seekp(0,ios::beg);
00321 Recovery_from_file >> n;
00322 Recovery_from_file.ignore(1,'\n');
00323
00324 cout << "Continue factorization for " << endl;
00325 cout << n << endl;
00326
00327
00328
00329 Factorization_to_file << " [RECOVERY] ";
00330 FoundFactors.AutoLoad();
00331 }
00332 else
00333 {
00334
00335
00336 StaticRelations::FileBuffer.open(StaticRelationsFile.c_str(),ios::out|ios::trunc);
00337 SpecialRelations::FileBuffer.open(SpecialRelationsFile.c_str(),ios::in|ios::out|ios::trunc);
00338 if (!DynamicRelations::FileBuffer.open(DynamicRelationsFile.c_str(),ios::in|ios::out|ios::trunc))
00339 {
00340 cerr << "Cannot access " << DynamicRelationsFile << endl;
00341 exit(1);
00342 }
00343
00344 Recovery_buffer.open(RecoveryFile.c_str(),ios::in|ios::out|ios::trunc);
00345
00346 cout_status << "Starting factorization for" << endl;
00347 cout_status << n << endl;
00348
00349 Factorization_to_file << endl << "Factorization of " << argv[1] << ":" << endl;
00350 Factorization_to_file << n << " = " << endl;
00351
00352 easy_factor();
00353
00354 #ifdef VERBOSE_NOTICE
00355 cout_status << "Starting factorization with ECM and MPQS for" << endl;
00356 cout_status << n << endl;
00357 #endif
00358 Recovery_to_file << n << endl;
00359 unlink("ecm-recover.dat");
00360 }
00361 ExitManager::register_exithandler(cleanup_files);
00362
00363
00364
00365
00366 if (!SkipECM) process_ecm();
00367
00368 #if defined(USE_DFT) || (CONTINUATION_METHOD==2)
00369
00370
00371
00372 polynomial::clear_dft_tempmemory();
00373 #endif
00374
00375
00376
00377 determine_best_MPQS_Multiplier(n,kN,MPQS_Multiplier);
00378 tune_parameters(mpz_sizeinbase(n,10));
00379
00380
00381 if ( sqrt(mpz_get_d(kN)) < PhysicalSieveSize )
00382 {
00383 cerr << "Sieve size too big (you may want to reduce its size)!" << endl;
00384 exit(1);
00385 }
00386
00387
00388
00389 mpz_init(CmpqsFactor::DLP_Threshold);
00390 mpz_set_ui(CmpqsFactor::DLP_Threshold,SingleLargePrime_Threshold);
00391 mpz_mul(CmpqsFactor::DLP_Threshold,CmpqsFactor::DLP_Threshold,CmpqsFactor::DLP_Threshold);
00392
00393 StaticFactorbase::compute_StaticFactorbase();
00394 CSieveStaticFactors::initialize();
00395 SieveControl::compute_SieveThreshold();
00396 for (int i=0; i<64; ++i) SieveArray_[i]=-1;
00397 Polynom.compute_first_polynomial(kN,LogicalSieveSize);
00398
00399 if (recover)
00400 {
00401 StaticRelations::Load();
00402 DynamicRelations::Load();
00403 SpecialRelations::Load();
00404 statistical_data::ProgressStats.take_sample();
00405
00406
00407
00408 SpecialRelations::CycleSearch();
00409
00410 #ifdef SAFEMODE
00411
00412 CRelation::SanityCheckRelationsFile(StaticRelationsFile);
00413 CRelation::SanityCheckRelationsFile(DynamicRelationsFile);
00414 CRelation::SanityCheckRelationsFile(SpecialRelationsFile);
00415 #endif
00416 streampos fpos = Recovery_from_file.tellg();
00417 Polynom.load_if_available(Recovery_from_file);
00418 Recovery_to_file.seekp(fpos);
00419 }
00420
00421
00422 display_StatusLegend();
00423
00424
00425 while(true)
00426 {
00427
00428 streampos fpos = Recovery_to_file.tellp();
00429 Polynom.save(Recovery_to_file);
00430 Recovery_to_file.seekp(fpos);
00431 do_sieving();
00432 Polynom.compute_next_polynomial();
00433 }
00434
00435 #ifdef VERBOSE_INFO
00436 cout << endl << "Session ended successfully." << endl;
00437 #endif
00438 return 0;
00439 }