File: mp_fkmul.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 (139 lines) | stat: -rw-r--r-- 6,615 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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*************************************************
* Fixed Karatsuba Multiplication Source File     *
* (C) 1999-2005 The Botan Project                *
*************************************************/

#include <botan/mp_core.h>
#include <botan/mem_ops.h>
#include <botan/parsing.h>
#include <botan/exceptn.h>

namespace Botan {

/*************************************************
* Karatsuba Multiplication Operation             *
*************************************************/
#define KARATSUBA_CORE(N, INNER_MUL, z, x, y)                     \
   {                                                              \
   const u32bit N2 = N / 2;                                       \
                                                                  \
   const word* x0 = x;                                            \
   const word* x1 = x + N2;                                       \
   const word* y0 = y;                                            \
   const word* y1 = y + N2;                                       \
   word* z0 = z;                                                  \
   word* z1 = z + N;                                              \
                                                                  \
   const s32bit cmp0 = bigint_cmp(x0, N2, x1, N2);                \
   const s32bit cmp1 = bigint_cmp(y1, N2, y0, N2);                \
                                                                  \
   bool positive = (cmp0 == cmp1) || (cmp0 == 0) || (cmp1 == 0);  \
                                                                  \
   word ws[N+N+1] = { 0 };                                        \
   word* middle = ws + N;                                         \
                                                                  \
   if(cmp0 && cmp1)                                               \
      {                                                           \
      if(cmp0 > 0)                                                \
         bigint_sub3(middle, x0, N2, x1, N2);                     \
      else                                                        \
         bigint_sub3(middle, x1, N2, x0, N2);                     \
                                                                  \
      if(cmp1 > 0)                                                \
         bigint_sub3(z, y1, N2, y0, N2);                          \
      else                                                        \
         bigint_sub3(z, y0, N2, y1, N2);                          \
                                                                  \
      INNER_MUL(ws, middle, z);                                   \
      }                                                           \
                                                                  \
   INNER_MUL(z0, x0, y0);                                         \
   INNER_MUL(z1, x1, y1);                                         \
                                                                  \
   bigint_add3(middle, z0, N, z1, N);                             \
                                                                  \
   if(positive)                                                   \
      bigint_add2(middle, N+1, ws, N);                            \
   else                                                           \
      {                                                           \
      const s32bit scmp = bigint_cmp(middle, N+1, ws, N);         \
                                                                  \
      if(scmp < 0)                                                \
         throw Internal_Error("bigint_karat" + to_string(N) +     \
                              ": scmp < 0");                      \
                                                                  \
      if(scmp > 0)                                                \
         bigint_sub2(middle, N+1, ws, N);                         \
      else                                                        \
         clear_mem(middle, N+1);                                  \
      }                                                           \
   bigint_add2(z + N2, 2*N-N2, middle, N+1);                      \
                                                                  \
   clear_mem(ws, 2*N+1);                                          \
   }

/*************************************************
* Karatsuba 16x16 Multiplication                 *
*************************************************/
void bigint_karat16(word z[32], const word x[16], const word y[16])
   {
   KARATSUBA_CORE(16, bigint_comba8, z, x, y);
   }

/*************************************************
* Karatsuba 32x32 Multiplication                 *
*************************************************/
void bigint_karat32(word z[64], const word x[32], const word y[32])
   {
   KARATSUBA_CORE(32, bigint_karat16, z, x, y);
   }

/*************************************************
* Karatsuba 64x64 Multiplication                 *
*************************************************/
void bigint_karat64(word z[128], const word x[64], const word y[64])
   {
   KARATSUBA_CORE(64, bigint_karat32, z, x, y);
   }

/*************************************************
* Karatsuba 128x128 Multiplication               *
*************************************************/
void bigint_karat128(word z[256], const word x[128], const word y[128])
   {
   KARATSUBA_CORE(128, bigint_karat64, z, x, y);
   }

/*************************************************
* Karatsuba 12x12 Multiplication                 *
*************************************************/
void bigint_karat12(word z[24], const word x[12], const word y[12])
   {
   KARATSUBA_CORE(12, bigint_comba6, z, x, y);
   }

/*************************************************
* Karatsuba 24x24 Multiplication                 *
*************************************************/
void bigint_karat24(word z[48], const word x[24], const word y[24])
   {
   KARATSUBA_CORE(24, bigint_karat12, z, x, y);
   }

/*************************************************
* Karatsuba 48x48 Multiplication                 *
*************************************************/
void bigint_karat48(word z[96], const word x[48], const word y[48])
   {
   KARATSUBA_CORE(48, bigint_karat24, z, x, y);
   }

/*************************************************
* Karatsuba 96x96 Multiplication                 *
*************************************************/
void bigint_karat96(word z[192], const word x[96], const word y[96])
   {
   KARATSUBA_CORE(96, bigint_karat48, z, x, y);
   }

}