diff options
Diffstat (limited to 'src/math/numbertheory/powm_fw.cpp')
-rw-r--r-- | src/math/numbertheory/powm_fw.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/math/numbertheory/powm_fw.cpp b/src/math/numbertheory/powm_fw.cpp new file mode 100644 index 000000000..c29b9f311 --- /dev/null +++ b/src/math/numbertheory/powm_fw.cpp @@ -0,0 +1,102 @@ +/************************************************* +* Fixed Window Exponentiation Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/def_powm.h> +#include <botan/numthry.h> +#include <vector> + +namespace Botan { + +namespace { + +/************************************************* +* Try to choose a good window size * +*************************************************/ +u32bit choose_window_bits(u32bit exp_bits, u32bit, + Power_Mod::Usage_Hints hints) + { + static const u32bit wsize[][2] = { + { 2048, 7 }, { 1024, 6 }, { 256, 5 }, { 128, 4 }, { 64, 3 }, { 0, 0 } + }; + + u32bit window_bits = 3; + + if(exp_bits) + { + for(u32bit j = 0; wsize[j][0]; ++j) + { + if(exp_bits >= wsize[j][0]) + { + window_bits += wsize[j][1]; + break; + } + } + } + + if(hints & Power_Mod::EXP_IS_FIXED) + window_bits += 2; + if(hints & Power_Mod::EXP_IS_LARGE) + window_bits += 2; + if(hints & Power_Mod::BASE_IS_FIXED) + ++window_bits; + + return window_bits; + } + +} + +/************************************************* +* Set the exponent * +*************************************************/ +void Fixed_Window_Exponentiator::set_exponent(const BigInt& e) + { + exp = e; + } + +/************************************************* +* Set the base * +*************************************************/ +void Fixed_Window_Exponentiator::set_base(const BigInt& base) + { + window_bits = choose_window_bits(exp.bits(), base.bits(), hints); + + g.resize((1 << window_bits) - 1); + g[0] = base; + for(u32bit j = 1; j != g.size(); ++j) + g[j] = reducer.multiply(g[j-1], g[0]); + } + +/************************************************* +* Compute the result * +*************************************************/ +BigInt Fixed_Window_Exponentiator::execute() const + { + const u32bit exp_nibbles = (exp.bits() + window_bits - 1) / window_bits; + + BigInt x = 1; + for(u32bit j = exp_nibbles; j > 0; --j) + { + for(u32bit k = 0; k != window_bits; ++k) + x = reducer.square(x); + + u32bit nibble = exp.get_substring(window_bits*(j-1), window_bits); + if(nibble) + x = reducer.multiply(x, g[nibble-1]); + } + return x; + } + +/************************************************* +* Fixed_Window_Exponentiator Constructor * +*************************************************/ +Fixed_Window_Exponentiator::Fixed_Window_Exponentiator(const BigInt& n, + Power_Mod::Usage_Hints hints) + { + reducer = Modular_Reducer(n); + this->hints = hints; + window_bits = 0; + } + +} |