File: fused.cpp

package info (click to toggle)
monotone 0.31-6
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 20,680 kB
  • ctags: 14,801
  • sloc: cpp: 87,711; ansic: 64,862; sh: 5,691; lisp: 954; perl: 783; makefile: 509; python: 265; sql: 98; sed: 16
file content (66 lines) | stat: -rw-r--r-- 2,018 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*************************************************
* Fused Arithmetic Operations Source File        *
* (C) 1999-2005 The Botan Project                *
*************************************************/

#include <botan/numthry.h>
#include <botan/mp_core.h>

namespace Botan {

/*************************************************
* Fused 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 u32bit a_sw = a.sig_words();
   const u32bit b_sw = b.sig_words();
   const u32bit c_sw = c.sig_words();

   BigInt r(sign, std::max(a.size() + b.size(), c_sw) + 1);
   bigint_mul3(r.get_reg(), r.size(),
               a.data(), a.size(), a_sw,
               b.data(), b.size(), b_sw);
   const u32bit r_size = std::max(r.sig_words(), c_sw);
   bigint_add2(r.get_reg(), r_size, c.data(), c_sw);
   return r;
   }

/*************************************************
* Fused 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;
   }

/*************************************************
* Fused Multiply/Modulo Operation                *
*************************************************/
BigInt mul_mod(const BigInt& a, const BigInt& b, const BigInt& m)
   {
   if(a.is_negative() || b.is_negative())
      throw Invalid_Argument("mul_mod: First two arguments must be >= 0");
   if(m <= 0)
      throw Invalid_Argument("mul_mod: Modulo must be positive");

   BigInt r = a;
   r *= b;
   r %= m;
   return r;
   }

}