Botan  1.10.17
mp_asm.cpp
Go to the documentation of this file.
1 /*
2 * Lowest Level MPI Algorithms
3 * (C) 1999-2010 Jack Lloyd
4 * 2006 Luca Piccarreta
5 *
6 * Distributed under the terms of the Botan license
7 */
8 
9 #include <botan/internal/mp_asm.h>
10 #include <botan/internal/mp_asmi.h>
11 #include <botan/internal/mp_core.h>
12 #include <botan/internal/ct_utils.h>
13 #include <botan/exceptn.h>
14 #include <botan/mem_ops.h>
15 
16 namespace Botan {
17 
18 extern "C" {
19 
20 /*
21 * If cond == 0, does nothing.
22 * If cond > 0, swaps x[0:size] with y[0:size]
23 * Runs in constant time
24 */
25 void bigint_cnd_swap(word cnd, word x[], word y[], size_t size)
26  {
27  const word mask = CT::expand_mask(cnd);
28 
29  for(size_t i = 0; i != size; ++i)
30  {
31  word a = x[i];
32  word b = y[i];
33  x[i] = CT::select(mask, b, a);
34  y[i] = CT::select(mask, a, b);
35  }
36  }
37 
38 /*
39 * If cond > 0 adds x[0:size] to y[0:size] and returns carry
40 * Runs in constant time
41 */
42 word bigint_cnd_add(word cnd, word x[], const word y[], size_t size)
43  {
44  const word mask = CT::expand_mask(cnd);
45 
46  word carry = 0;
47  for(size_t i = 0; i != size; ++i)
48  {
49  /*
50  Here we are relying on asm version of word_add being
51  a single addcl or equivalent. Fix this.
52  */
53  const word z = word_add(x[i], y[i], &carry);
54  x[i] = CT::select(mask, z, x[i]);
55  }
56 
57  return carry & mask;
58  }
59 
60 /*
61 * If cond > 0 subs x[0:size] to y[0:size] and returns borrow
62 * Runs in constant time
63 */
64 word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size)
65  {
66  const word mask = CT::expand_mask(cnd);
67 
68  word carry = 0;
69  for(size_t i = 0; i != size; ++i)
70  {
71  const word z = word_sub(x[i], y[i], &carry);
72  x[i] = CT::select(mask, z, x[i]);
73  }
74 
75  return carry & mask;
76  }
77 
78 void bigint_cnd_abs(word cnd, word x[], size_t size)
79  {
80  const word mask = CT::expand_mask(cnd);
81 
82  word carry = mask & 1;
83  for(size_t i = 0; i != size; ++i)
84  {
85  const word z = word_add(~x[i], 0, &carry);
86  x[i] = CT::select(mask, z, x[i]);
87  }
88  }
89 
90 /*
91 * Two Operand Addition, No Carry
92 */
93 word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size)
94  {
95  word carry = 0;
96 
97  const size_t blocks = y_size - (y_size % 8);
98 
99  for(size_t i = 0; i != blocks; i += 8)
100  carry = word8_add2(x + i, y + i, carry);
101 
102  for(size_t i = blocks; i != y_size; ++i)
103  x[i] = word_add(x[i], y[i], &carry);
104 
105  for(size_t i = y_size; i != x_size; ++i)
106  x[i] = word_add(x[i], 0, &carry);
107 
108  return carry;
109  }
110 
111 /*
112 * Three Operand Addition, No Carry
113 */
114 word bigint_add3_nc(word z[], const word x[], size_t x_size,
115  const word y[], size_t y_size)
116  {
117  if(x_size < y_size)
118  { return bigint_add3_nc(z, y, y_size, x, x_size); }
119 
120  word carry = 0;
121 
122  const size_t blocks = y_size - (y_size % 8);
123 
124  for(size_t i = 0; i != blocks; i += 8)
125  carry = word8_add3(z + i, x + i, y + i, carry);
126 
127  for(size_t i = blocks; i != y_size; ++i)
128  z[i] = word_add(x[i], y[i], &carry);
129 
130  for(size_t i = y_size; i != x_size; ++i)
131  z[i] = word_add(x[i], 0, &carry);
132 
133  return carry;
134  }
135 
136 /*
137 * Two Operand Addition
138 */
139 void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size)
140  {
141  if(bigint_add2_nc(x, x_size, y, y_size))
142  x[x_size] += 1;
143  }
144 
145 /*
146 * Three Operand Addition
147 */
148 void bigint_add3(word z[], const word x[], size_t x_size,
149  const word y[], size_t y_size)
150  {
151  z[(x_size > y_size ? x_size : y_size)] +=
152  bigint_add3_nc(z, x, x_size, y, y_size);
153  }
154 
155 /*
156 * Two Operand Subtraction
157 */
158 word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size)
159  {
160  word borrow = 0;
161 
162  const size_t blocks = y_size - (y_size % 8);
163 
164  for(size_t i = 0; i != blocks; i += 8)
165  borrow = word8_sub2(x + i, y + i, borrow);
166 
167  for(size_t i = blocks; i != y_size; ++i)
168  x[i] = word_sub(x[i], y[i], &borrow);
169 
170  for(size_t i = y_size; i != x_size; ++i)
171  x[i] = word_sub(x[i], 0, &borrow);
172 
173  return borrow;
174  }
175 
176 /*
177 * Two Operand Subtraction x = y - x
178 */
179 void bigint_sub2_rev(word x[], const word y[], size_t y_size)
180  {
181  word borrow = 0;
182 
183  const size_t blocks = y_size - (y_size % 8);
184 
185  for(size_t i = 0; i != blocks; i += 8)
186  borrow = word8_sub2_rev(x + i, y + i, borrow);
187 
188  for(size_t i = blocks; i != y_size; ++i)
189  x[i] = word_sub(y[i], x[i], &borrow);
190 
191  if(borrow)
192  throw Internal_Error("bigint_sub2_rev: x >= y");
193  }
194 
195 /*
196 * Three Operand Subtraction
197 */
198 word bigint_sub3(word z[], const word x[], size_t x_size,
199  const word y[], size_t y_size)
200  {
201  word borrow = 0;
202 
203  const size_t blocks = y_size - (y_size % 8);
204 
205  for(size_t i = 0; i != blocks; i += 8)
206  borrow = word8_sub3(z + i, x + i, y + i, borrow);
207 
208  for(size_t i = blocks; i != y_size; ++i)
209  z[i] = word_sub(x[i], y[i], &borrow);
210 
211  for(size_t i = y_size; i != x_size; ++i)
212  z[i] = word_sub(x[i], 0, &borrow);
213 
214  return borrow;
215  }
216 
217 /*
218 * Two Operand Linear Multiply
219 */
220 void bigint_linmul2(word x[], size_t x_size, word y)
221  {
222  const size_t blocks = x_size - (x_size % 8);
223 
224  word carry = 0;
225 
226  for(size_t i = 0; i != blocks; i += 8)
227  carry = word8_linmul2(x + i, y, carry);
228 
229  for(size_t i = blocks; i != x_size; ++i)
230  x[i] = word_madd2(x[i], y, &carry);
231 
232  x[x_size] = carry;
233  }
234 
235 /*
236 * Three Operand Linear Multiply
237 */
238 void bigint_linmul3(word z[], const word x[], size_t x_size, word y)
239  {
240  const size_t blocks = x_size - (x_size % 8);
241 
242  word carry = 0;
243 
244  for(size_t i = 0; i != blocks; i += 8)
245  carry = word8_linmul3(z + i, x + i, y, carry);
246 
247  for(size_t i = blocks; i != x_size; ++i)
248  z[i] = word_madd2(x[i], y, &carry);
249 
250  z[x_size] = carry;
251  }
252 
253 }
254 
255 }
void bigint_sub2_rev(word x[], const word y[], size_t y_size)
Definition: mp_asm.cpp:179
word word8_sub2_rev(word x[8], const word y[8], word carry)
Definition: mp_asmi.h:94
word word8_add2(word x[8], const word y[8], word carry)
Definition: mp_asmi.h:33
word word8_linmul3(word z[8], const word x[8], word y, word carry)
Definition: mp_asmi.h:143
word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size)
Definition: mp_asm.cpp:158
void bigint_linmul2(word x[], size_t x_size, word y)
Definition: mp_asm.cpp:220
word bigint_add3_nc(word z[], const word x[], size_t x_size, const word y[], size_t y_size)
Definition: mp_asm.cpp:114
word word8_sub2(word x[8], const word y[8], word carry)
Definition: mp_asmi.h:78
word bigint_sub3(word z[], const word x[], size_t x_size, const word y[], size_t y_size)
Definition: mp_asm.cpp:198
word word_madd2(word a, word b, word *c)
Definition: mp_asm.h:86
void bigint_linmul3(word z[], const word x[], size_t x_size, word y)
Definition: mp_asm.cpp:238
T expand_mask(T x)
Definition: ct_utils.h:33
word bigint_cnd_sub(word cnd, word x[], const word y[], size_t size)
Definition: mp_asm.cpp:64
void bigint_cnd_swap(word cnd, word x[], word y[], size_t size)
Definition: mp_asm.cpp:25
word word8_linmul2(word x[8], word y, word carry)
Definition: mp_asmi.h:127
T select(T mask, T from0, T from1)
Definition: ct_utils.h:45
word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size)
Definition: mp_asm.cpp:93
word word8_add3(word z[8], const word x[8], const word y[8], word carry)
Definition: mp_asmi.h:49
word word_sub(word x, word y, word *carry)
Definition: mp_asmi.h:66
void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size)
Definition: mp_asm.cpp:139
word bigint_cnd_add(word cnd, word x[], const word y[], size_t size)
Definition: mp_asm.cpp:42
word word_add(word x, word y, word *carry)
Definition: mp_asmi.h:21
void bigint_cnd_abs(word cnd, word x[], size_t size)
Definition: mp_asm.cpp:78
word word8_sub3(word z[8], const word x[8], const word y[8], word carry)
Definition: mp_asmi.h:110
void bigint_add3(word z[], const word x[], size_t x_size, const word y[], size_t y_size)
Definition: mp_asm.cpp:148