aboutsummaryrefslogtreecommitdiffstats
path: root/src/math/numbertheory/powm_fw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/numbertheory/powm_fw.cpp')
-rw-r--r--src/math/numbertheory/powm_fw.cpp102
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;
+ }
+
+}