diff options
Diffstat (limited to 'src/bigint/pow_mod.cpp')
-rw-r--r-- | src/bigint/pow_mod.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/bigint/pow_mod.cpp b/src/bigint/pow_mod.cpp new file mode 100644 index 000000000..17ca7b796 --- /dev/null +++ b/src/bigint/pow_mod.cpp @@ -0,0 +1,155 @@ +/************************************************* +* Modular Exponentiation Proxy Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/pow_mod.h> +#include <botan/engine.h> + +namespace Botan { + +/************************************************* +* Power_Mod Constructor * +*************************************************/ +Power_Mod::Power_Mod(const BigInt& n, Usage_Hints hints) + { + core = 0; + set_modulus(n, hints); + } + +/************************************************* +* Power_Mod Copy Constructor * +*************************************************/ +Power_Mod::Power_Mod(const Power_Mod& other) + { + core = 0; + if(other.core) + core = other.core->copy(); + } + +/************************************************* +* Power_Mod Assignment Operator * +*************************************************/ +Power_Mod& Power_Mod::operator=(const Power_Mod& other) + { + delete core; + core = 0; + if(other.core) + core = other.core->copy(); + return (*this); + } + +/************************************************* +* Power_Mod Destructor * +*************************************************/ +Power_Mod::~Power_Mod() + { + delete core; + } + +/************************************************* +* Set the modulus * +*************************************************/ +void Power_Mod::set_modulus(const BigInt& n, Usage_Hints hints) const + { + delete core; + core = ((n == 0) ? 0 : Engine_Core::mod_exp(n, hints)); + } + +/************************************************* +* Set the base * +*************************************************/ +void Power_Mod::set_base(const BigInt& b) const + { + if(b.is_zero() || b.is_negative()) + throw Invalid_Argument("Power_Mod::set_base: arg must be > 0"); + + if(!core) + throw Internal_Error("Power_Mod::set_base: core was NULL"); + core->set_base(b); + } + +/************************************************* +* Set the exponent * +*************************************************/ +void Power_Mod::set_exponent(const BigInt& e) const + { + if(e.is_negative()) + throw Invalid_Argument("Power_Mod::set_exponent: arg must be > 0"); + + if(!core) + throw Internal_Error("Power_Mod::set_exponent: core was NULL"); + core->set_exponent(e); + } + +/************************************************* +* Compute the result * +*************************************************/ +BigInt Power_Mod::execute() const + { + if(!core) + throw Internal_Error("Power_Mod::execute: core was NULL"); + return core->execute(); + } + +namespace { + +/************************************************* +* Choose potentially useful hints * +*************************************************/ +Power_Mod::Usage_Hints choose_base_hints(const BigInt& b, const BigInt& n) + { + if(b == 2) + return Power_Mod::Usage_Hints(Power_Mod::BASE_IS_2 | + Power_Mod::BASE_IS_SMALL); + + const u32bit b_bits = b.bits(); + const u32bit n_bits = n.bits(); + + if(b_bits < n_bits / 32) + return Power_Mod::BASE_IS_SMALL; + if(b_bits > n_bits / 4) + return Power_Mod::BASE_IS_LARGE; + + return Power_Mod::NO_HINTS; + } + +/************************************************* +* Choose potentially useful hints * +*************************************************/ +Power_Mod::Usage_Hints choose_exp_hints(const BigInt& e, const BigInt& n) + { + const u32bit e_bits = e.bits(); + const u32bit n_bits = n.bits(); + + if(e_bits < n_bits / 32) + return Power_Mod::BASE_IS_SMALL; + if(e_bits > n_bits / 4) + return Power_Mod::BASE_IS_LARGE; + return Power_Mod::NO_HINTS; + } + +} + +/************************************************* +* Fixed_Exponent_Power_Mod Constructor * +*************************************************/ +Fixed_Exponent_Power_Mod::Fixed_Exponent_Power_Mod(const BigInt& e, + const BigInt& n, + Usage_Hints hints) : + Power_Mod(n, Usage_Hints(hints | EXP_IS_FIXED | choose_exp_hints(e, n))) + { + set_exponent(e); + } + +/************************************************* +* Fixed_Base_Power_Mod Constructor * +*************************************************/ +Fixed_Base_Power_Mod::Fixed_Base_Power_Mod(const BigInt& b, const BigInt& n, + Usage_Hints hints) : + Power_Mod(n, Usage_Hints(hints | BASE_IS_FIXED | choose_base_hints(b, n))) + { + set_base(b); + } + +} |