aboutsummaryrefslogtreecommitdiffstats
path: root/src/math/mp/mp_generic/mp_madd.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/mp/mp_generic/mp_madd.h')
-rw-r--r--src/math/mp/mp_generic/mp_madd.h73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/math/mp/mp_generic/mp_madd.h b/src/math/mp/mp_generic/mp_madd.h
new file mode 100644
index 000000000..17713f55f
--- /dev/null
+++ b/src/math/mp/mp_generic/mp_madd.h
@@ -0,0 +1,73 @@
+/*
+* Lowest Level MPI Algorithms
+* (C) 1999-2008,2013 Jack Lloyd
+* 2006 Luca Piccarreta
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_MP_WORD_MULADD_H__
+#define BOTAN_MP_WORD_MULADD_H__
+
+#include <botan/mp_types.h>
+
+namespace Botan {
+
+extern "C" {
+
+/*
+* Word Multiply/Add
+*/
+inline word word_madd2(word a, word b, word* c)
+ {
+#if defined(BOTAN_HAS_MP_DWORD)
+ const dword s = static_cast<dword>(a) * b + *c;
+ *c = static_cast<word>(s >> BOTAN_MP_WORD_BITS);
+ return static_cast<word>(s);
+#else
+ static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size");
+
+ word hi = 0, lo = 0;
+
+ mul64x64_128(a, b, &lo, &hi);
+
+ lo += *c;
+ hi += (lo < *c); // carry?
+
+ *c = hi;
+ return lo;
+#endif
+ }
+
+/*
+* Word Multiply/Add
+*/
+inline word word_madd3(word a, word b, word c, word* d)
+ {
+#if defined(BOTAN_HAS_MP_DWORD)
+ const dword s = static_cast<dword>(a) * b + c + *d;
+ *d = static_cast<word>(s >> BOTAN_MP_WORD_BITS);
+ return static_cast<word>(s);
+#else
+ static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size");
+
+ word hi = 0, lo = 0;
+
+ mul64x64_128(a, b, &lo, &hi);
+
+ lo += c;
+ hi += (lo < c); // carry?
+
+ lo += *d;
+ hi += (lo < *d); // carry?
+
+ *d = hi;
+ return lo;
+#endif
+ }
+
+}
+
+}
+
+#endif