00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef _ARAGELI_prime_hpp_
00013 #define _ARAGELI_prime_hpp_
00014
00015 #include "config.hpp"
00016 #include "factory.hpp"
00017 #include "cmp.hpp"
00018 #include "vector.hpp"
00019
00020 #include "std_import.hpp"
00021
00022
00023 namespace Arageli
00024 {
00025
00026
00028
00030
00032
00033 template <typename T, typename T_factory>
00034 bool is_prime_division (const T& x, const T_factory& tfctr);
00035
00037
00038 template <typename T>
00039 inline bool is_prime_division (const T& x)
00040 { return is_prime_division(x, factory<T>()); }
00041
00043
00045 template <typename T, typename N, typename T_factory>
00046 bool is_pseudoprime_miller_rabin (const T& x, const N& n, const T_factory& tfctr);
00047
00049
00050 template <typename T>
00051 bool is_prime_AKS_classic (const T& n);
00052
00054
00055 template <typename T>
00056 bool is_prime_AKS (const T& n);
00057
00059
00061 template <typename T, typename N>
00062 inline bool is_pseudoprime_miller_rabin (const T& x, const N& n)
00063 { return is_pseudoprime_miller_rabin(x, n, factory<T>()); }
00064
00066
00067 template <typename T, typename N, typename T_factory>
00068 bool is_pseudoprime_solovay_strassen (const T& x, const N& n, const T_factory& tfctr);
00069
00071
00072 template <typename T, typename N>
00073 inline bool is_prime_solovey_strassen (const T& x, const N& n)
00074 { return is_pseudoprime_solovay_strassen(x, n, factory<T>()); }
00075
00076
00078
00079 template <typename T, typename T_factory>
00080 inline bool is_prime (const T& x, const T_factory& tfctr)
00081 { return is_prime_division(x, tfctr); }
00082
00083
00085 template <typename T>
00086 inline bool is_prime (const T& x)
00087 { return is_prime(x, factory<T>()); }
00088
00090
00091 template <typename T, typename T_factory>
00092 inline bool is_probably_prime (const T& x, const T_factory& tfctr)
00093 { return is_pseudoprime_solovay_strassen(x, 10, tfctr); }
00094
00095
00097 template <typename T>
00098 inline bool is_probably_prime (const T& x)
00099 { return is_probably_prime(x, factory<T>()); }
00100
00102
00105 template <typename Out, typename T>
00106 Out small_primes (Out primes, const T& N);
00107
00113 template <typename T, typename N>
00114 int is_prime_small_primes_division (const T& n, const N& np);
00115
00121 template <typename T>
00122 int is_prime_small_primes_division(const T& n)
00123 { return is_prime_small_primes_division(n, ARAGELI_IS_PRIME_SMALL_PRIMES_DIVISION_NUMBER); }
00124
00126 template <typename T, typename T_factory>
00127 inline bool is_composite (const T& x, const T_factory& tfctr)
00128 {
00129 return
00130 !is_null(x) &&
00131 !is_unit(x) &&
00132 !is_opposite_unit(x) &&
00133 !is_prime(x, tfctr);
00134 }
00135
00136
00138 template <typename T>
00139 inline bool is_composite (const T& x)
00140 { return is_composite(x, factory<T>()); }
00141
00142
00143
00144
00145
00147
00149
00151
00155 template <typename T1, typename T2, bool REFCNT2, typename T_factory>
00156 vector<T2, REFCNT2>& factorize_division
00157 (T1 x, vector<T2, REFCNT2>& res, const T_factory& tfctr);
00158
00159
00161 template <typename T1, typename T2, bool REFCNT2>
00162 inline vector<T2, REFCNT2>& factorize_division
00163 (const T1& x, vector<T2, REFCNT2>& res)
00164 { return factorize_division(x, res, factory<T1>()); }
00165
00166
00168 template <typename T, typename T_factory>
00169 inline vector<T, true> factorize_division
00170 (const T& x, const T_factory& tfctr)
00171 {
00172 vector<T, true> res;
00173 return factorize_division(x, res, tfctr);
00174 }
00175
00176
00178 template <typename T>
00179 inline vector<T, true> factorize_division (const T& x)
00180 { return factorize_division(x, factory<T>()); }
00181
00182
00184
00185 template <typename T1, typename T2, bool REFCNT2, typename T_factory>
00186 inline vector<T2, REFCNT2>& factorize
00187 (const T1& x, vector<T2, REFCNT2>& res, const T_factory& tfctr)
00188 { return factorize_division(x, res, tfctr); }
00189
00190
00192 template <typename T1, typename T2, bool REFCNT2>
00193 inline vector<T2, REFCNT2>& factorize
00194 (const T1& x, vector<T2, REFCNT2>& res)
00195 { return factorize(x, res, factory<T1>()); }
00196
00197
00199 template <typename T, typename T_factory>
00200 inline vector<T, true> factorize
00201 (const T& x, const T_factory& tfctr)
00202 {
00203 vector<T, true> res;
00204 return factorize(x, res, tfctr);
00205 }
00206
00207
00209 template <typename T>
00210 inline vector<T, true> factorize (const T& x)
00211 { return factorize(x, factory<T>()); }
00212
00214
00215
00216
00218
00220
00222 template
00223 <
00224 typename T1,
00225 typename T2, bool REFCNT2,
00226 typename T3, typename T4
00227 >
00228 vector<T2, REFCNT2>& partial_factorize_division
00229 (T1 x, vector<T2, REFCNT2>& res, const T3& max, T4& rest);
00230
00232
00235 template<typename T, typename N, typename T_factory>
00236 T pollard_pm1(const T& n, const N& no_of_iter, const T_factory& tfctr);
00237
00239
00242 template<typename T, typename N>
00243 T pollard_pm1(const T& n, const N& no_of_iter = 10000)
00244 {return pollard_pm1(n, no_of_iter, factory<T>());}
00245
00246
00248
00251 template<typename T, typename T_factory>
00252 T rho_pollard(const T& n, const T_factory& tfctr);
00253
00254
00256
00259 template<typename T>
00260 T rho_pollard(const T& n)
00261 {return rho_pollard(n, factory<T>());}
00262
00264
00269 template<typename T, typename N, typename T_factory>
00270 T brent(const T& n, N no_of_iter, const T_factory& tfctr);
00271
00273
00278 template<typename T, typename N>
00279 T brent(const T& n, N no_of_iter)
00280 {return brent(n, no_of_iter, factory<T>());}
00281
00283 template <typename T, typename T3, typename T4>
00284 inline vector<T, true> partial_factorize_division
00285 (const T& x, const T3& max, T4& rest)
00286 {
00287 vector<T, true> res;
00288 return partial_factorize_division(x, res, max, rest);
00289 }
00290
00291
00293 template
00294 <
00295 typename T1,
00296 typename TT1, typename T2, bool REFCNT2,
00297 typename T3
00298 >
00299 inline vector<T2, REFCNT2>& partial_factorize_division
00300 (const T1& x, vector<T2, REFCNT2>& res, const T3& max)
00301 {
00302 T1 rest;
00303 return partial_factorize_division(x, res, max, rest);
00304 }
00305
00306
00308 template <typename T, typename T3>
00309 inline vector<T, true> partial_factorize_division
00310 (const T& x, const T3& max)
00311 {
00312 T rest;
00313 return partial_factorize_division(x, max, rest);
00314 }
00315
00316
00318 template
00319 <
00320 typename T1,
00321 typename T2, bool REFCNT2,
00322 typename T3, typename T4
00323 >
00324 inline vector<T2, REFCNT2>& partial_factorize
00325 (const T1& x, vector<T2, REFCNT2>& res, const T3& max, T4& rest)
00326 { return partial_factorize_division(x, res, max, rest); }
00327
00328
00330 template <typename T, typename T3, typename T4>
00331 inline vector<T, true> partial_factorize
00332 (const T& x, const T3& max, T4& rest)
00333 {
00334 vector<T, true> res;
00335 return partial_factorize(x, res, max, rest);
00336 }
00337
00338
00340 template
00341 <
00342 typename T1,
00343 typename TT1, typename T2, bool REFCNT2,
00344 typename T3
00345 >
00346 inline vector<T2, REFCNT2>& partial_factorize
00347 (const T1& x, vector<T2, REFCNT2>& res, const T3& max)
00348 {
00349 T1 rest;
00350 return partial_factorize(x, res, max, rest);
00351 }
00352
00353
00355 template <typename T, typename T3>
00356 inline vector<T, true> partial_factorize
00357 (const T& x, const T3& max)
00358 {
00359 T rest;
00360 return partial_factorize(x, max, rest);
00361 }
00362
00363
00365 template <typename T1, typename T2, typename T3, typename T4>
00366 const T4& factorize_multiplier (T1 x, const T2& m, T3& rest, T4& nm);
00367
00368
00370 template <typename T1, typename T2, typename T3>
00371 T1 factorize_multiplier (const T1& x, const T2& m, T3& rest)
00372 {
00373 T1 nm;
00374 factorize_multiplier(x, m, rest, nm);
00375 return nm;
00376 }
00377
00378
00380 template <typename T1, typename T2>
00381 T1 factorize_multiplier (const T1& x, const T2& m)
00382 {
00383 T1 rest;
00384 return factorize_multiplier(x, m, rest);
00385 }
00386
00387
00388
00389
00390
00392
00394
00396
00398 template <typename T>
00399 T next_prime_successive_checking (T x);
00400
00401
00403
00405 template <typename T>
00406 T prev_prime_successive_checking (T x);
00407
00408
00410 template <typename T>
00411 inline T next_prime (const T& x)
00412 { return next_prime_successive_checking(x); }
00413
00414
00416 template <typename T>
00417 inline T prev_prime (const T& x)
00418 { return prev_prime_successive_checking(x); }
00419
00421 template <typename T>
00422 inline T next_probably_prime (T x);
00423
00424
00426 template <typename T>
00427 inline T prev_probably_prime (T x);
00428
00429
00431
00432
00434
00436
00441 template<typename T, typename N>
00442 void rsa_generate_keys(N l, T& c, T& public_key, T& d);
00443
00447 template<typename T>
00448 T rsa_encyph(const T& x, const T& c, const T& key);
00449
00453 template<typename T>
00454 T rsa_decyph(const T& y, const T& d, const T& key);
00455
00456
00458
00459
00460
00462
00464
00465
00467
00469 template <typename T>
00470 inline bool is_mersen_prime_degree (const T& n)
00471 { return n == next_mersen_prime_degree(n-1); }
00472
00473
00475
00477 template <typename T>
00478 T next_mersen_prime_degree (const T& n);
00479
00480
00482
00483
00484 }
00485
00486
00487 #ifdef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE
00488 #define ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_PRIME
00489 #include "prime.cpp"
00490 #undef ARAGELI_INCLUDE_CPP_WITH_EXPORT_TEMPLATE_PRIME
00491 #endif
00492
00493
00494 #endif // #ifndef _ARAGELI_prime_hpp_