/*************************************************
* Modular Exponentiation Proxy Source File *
* (C) 1999-2007 The Botan Project *
*************************************************/
#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);
}
}
syntax highlighted by Code2HTML, v. 0.9.1