2
* (C) 2009,2010,2015 Jack Lloyd
4
* Botan is released under the Simplified BSD License (see license.txt)
9
#if defined(BOTAN_HAS_NUMBERTHEORY)
11
#include <botan/reducer.h>
12
#include <botan/numthry.h>
17
class Modular_Inverse final : public Command
20
Modular_Inverse() : Command("mod_inverse n mod") {}
24
const Botan::BigInt n(get_arg("n"));
25
const Botan::BigInt mod(get_arg("mod"));
27
output() << Botan::inverse_mod(n, mod) << "\n";
31
BOTAN_REGISTER_COMMAND("mod_inverse", Modular_Inverse);
33
class Gen_Prime final : public Command
36
Gen_Prime() : Command("gen_prime --count=1 bits") {}
40
const size_t bits = get_arg_sz("bits");
41
const size_t cnt = get_arg_sz("count");
43
for(size_t i = 0; i != cnt; ++i)
45
const Botan::BigInt p = Botan::random_prime(rng(), bits);
46
output() << p << "\n";
51
BOTAN_REGISTER_COMMAND("gen_prime", Gen_Prime);
53
class Is_Prime final : public Command
56
Is_Prime() : Command("is_prime --prob=56 n") {}
60
Botan::BigInt n(get_arg("n"));
61
const size_t prob = get_arg_sz("prob");
62
const bool prime = Botan::is_prime(n, rng(), prob);
64
output() << n << " is " << (prime ? "probably prime" : "composite") << "\n";
68
BOTAN_REGISTER_COMMAND("is_prime", Is_Prime);
71
* Factor integers using a combination of trial division by small
72
* primes, and Pollard's Rho algorithm
74
class Factor final : public Command
77
Factor() : Command("factor n") {}
81
Botan::BigInt n(get_arg("n"));
83
std::vector<Botan::BigInt> factors = factorize(n, rng());
84
std::sort(factors.begin(), factors.end());
86
output() << n << ": ";
87
std::copy(factors.begin(), factors.end(), std::ostream_iterator<Botan::BigInt>(output(), " "));
88
output() << std::endl;
93
std::vector<Botan::BigInt> factorize(const Botan::BigInt& n_in,
94
Botan::RandomNumberGenerator& rng)
96
Botan::BigInt n = n_in;
97
std::vector<Botan::BigInt> factors = remove_small_factors(n);
101
if(Botan::is_prime(n, rng))
103
factors.push_back(n);
107
Botan::BigInt a_factor = 0;
110
a_factor = rho(n, rng);
113
std::vector<Botan::BigInt> rho_factored = factorize(a_factor, rng);
114
for(size_t j = 0; j != rho_factored.size(); j++)
116
factors.push_back(rho_factored[j]);
126
* Pollard's Rho algorithm, as described in the MIT algorithms book. We
127
* use (x^2+x) mod n instead of (x*2-1) mod n as the random function,
128
* it _seems_ to lead to faster factorization for the values I tried.
130
Botan::BigInt rho(const Botan::BigInt& n, Botan::RandomNumberGenerator& rng)
132
Botan::BigInt x = Botan::BigInt::random_integer(rng, 0, n - 1);
136
Botan::Modular_Reducer mod_n(n);
143
if(i == 0) // overflow, bail out
148
x = mod_n.multiply((x + 1), x);
150
d = Botan::gcd(y - x, n);
165
// Remove (and return) any small (< 2^16) factors
166
std::vector<Botan::BigInt> remove_small_factors(Botan::BigInt& n)
168
std::vector<Botan::BigInt> factors;
172
factors.push_back(2);
176
for(size_t j = 0; j != Botan::PRIME_TABLE_SIZE; j++)
178
uint16_t prime = Botan::PRIMES[j];
184
Botan::BigInt x = Botan::gcd(n, prime);
193
factors.push_back(prime);
202
BOTAN_REGISTER_COMMAND("factor", Factor);