File: mp_mul.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 (85 lines) | stat: -rw-r--r-- 3,043 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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*************************************************
* MP Multiplication Source File                  *
* (C) 1999-2005 The Botan Project                *
*************************************************/

#include <botan/mp_core.h>

namespace Botan {

namespace {

/*************************************************
* Length Checking                                *
*************************************************/
bool use_op(u32bit x_sw, u32bit y_sw,
            u32bit x_size, u32bit y_size, u32bit z_size,
            u32bit limit, u32bit min = 0)
   {
   return (x_sw <= limit && y_sw <= limit &&
           x_size >= limit && y_size >= limit && z_size >= 2*limit &&
           (x_sw + y_sw) >= min);
   }

/*************************************************
* Attempt a Karatsuba multiply                   *
*************************************************/
bool do_karat(word z[], u32bit z_size,
              const word x[], u32bit x_size, u32bit x_sw,
              const word y[], u32bit y_size, u32bit y_sw)
   {
   const u32bit KARAT_12_BOUND = 20;
   const u32bit KARAT_16_BOUND = 24;
   const u32bit KARAT_24_BOUND = 38;
   const u32bit KARAT_32_BOUND = 46;
   const u32bit KARAT_48_BOUND = 66;
   const u32bit KARAT_64_BOUND = 80;
   const u32bit KARAT_96_BOUND = 114;
   const u32bit KARAT_128_BOUND = 136;

   if(use_op(x_sw, y_sw, x_size, y_size, z_size, 12, KARAT_12_BOUND))
      bigint_karat12(z, x, y);
   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 16, KARAT_16_BOUND))
      bigint_karat16(z, x, y);
   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 24, KARAT_24_BOUND))
      bigint_karat24(z, x, y);
   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 32, KARAT_32_BOUND))
      bigint_karat32(z, x, y);
   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 48, KARAT_48_BOUND))
      bigint_karat48(z, x, y);
   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 64, KARAT_64_BOUND))
      bigint_karat64(z, x, y);
   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 96, KARAT_96_BOUND))
      bigint_karat96(z, x, y);
   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 128, KARAT_128_BOUND))
      bigint_karat128(z, x, y);
   else
      return false;

   return true;
   }


}

/*************************************************
* MP Multiplication Algorithm Dispatcher         *
*************************************************/
void bigint_mul3(word z[], u32bit z_size,
                 const word x[], u32bit x_size, u32bit x_sw,
                 const word y[], u32bit y_size, u32bit y_sw)
   {
   if(x_sw == 1)      bigint_linmul3(z, y, y_sw, x[0]);
   else if(y_sw == 1) bigint_linmul3(z, x, x_sw, y[0]);

   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 4))
      bigint_comba4(z, x, y);
   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 6))
      bigint_comba6(z, x, y);
   else if(use_op(x_sw, y_sw, x_size, y_size, z_size, 8))
      bigint_comba8(z, x, y);
   else if(!do_karat(z, z_size, x, x_size, x_sw, y, y_size, y_sw))
      bigint_smul(z, x, x_sw, y, y_sw);
   }

}