diff options
Diffstat (limited to 'src/math/mp/mp_generic/mp_madd.h')
-rw-r--r-- | src/math/mp/mp_generic/mp_madd.h | 73 |
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 |