aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/math/numbertheory/mp_numth.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/math/numbertheory/mp_numth.cpp')
-rw-r--r--src/lib/math/numbertheory/mp_numth.cpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/lib/math/numbertheory/mp_numth.cpp b/src/lib/math/numbertheory/mp_numth.cpp
new file mode 100644
index 000000000..e6826b9dd
--- /dev/null
+++ b/src/lib/math/numbertheory/mp_numth.cpp
@@ -0,0 +1,74 @@
+/*
+* Fused and Important MP Algorithms
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/numthry.h>
+#include <botan/internal/mp_core.h>
+#include <botan/internal/rounding.h>
+#include <algorithm>
+
+namespace Botan {
+
+/*
+* Square a BigInt
+*/
+BigInt square(const BigInt& x)
+ {
+ const size_t x_sw = x.sig_words();
+
+ BigInt z(BigInt::Positive, round_up<size_t>(2*x_sw, 16));
+ secure_vector<word> workspace(z.size());
+
+ bigint_sqr(z.mutable_data(), z.size(),
+ &workspace[0],
+ x.data(), x.size(), x_sw);
+ return z;
+ }
+
+/*
+* Multiply-Add Operation
+*/
+BigInt mul_add(const BigInt& a, const BigInt& b, const BigInt& c)
+ {
+ if(c.is_negative() || c.is_zero())
+ throw Invalid_Argument("mul_add: Third argument must be > 0");
+
+ BigInt::Sign sign = BigInt::Positive;
+ if(a.sign() != b.sign())
+ sign = BigInt::Negative;
+
+ const size_t a_sw = a.sig_words();
+ const size_t b_sw = b.sig_words();
+ const size_t c_sw = c.sig_words();
+
+ BigInt r(sign, std::max(a.size() + b.size(), c_sw) + 1);
+ secure_vector<word> workspace(r.size());
+
+ bigint_mul(r.mutable_data(), r.size(),
+ &workspace[0],
+ a.data(), a.size(), a_sw,
+ b.data(), b.size(), b_sw);
+
+ const size_t r_size = std::max(r.sig_words(), c_sw);
+ bigint_add2(r.mutable_data(), r_size, c.data(), c_sw);
+ return r;
+ }
+
+/*
+* Subtract-Multiply Operation
+*/
+BigInt sub_mul(const BigInt& a, const BigInt& b, const BigInt& c)
+ {
+ if(a.is_negative() || b.is_negative())
+ throw Invalid_Argument("sub_mul: First two arguments must be >= 0");
+
+ BigInt r = a;
+ r -= b;
+ r *= c;
+ return r;
+ }
+
+}