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
16namespace Botan {
17
18extern "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*/
25void 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*/
42word 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*/
64word 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
78void 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*/
93word 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*/
114word 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*/
139void 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*/
148void 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*/
158word 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*/
179void 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*/
198word 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*/
220void 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*/
238void 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}
T expand_mask(T x)
Definition ct_utils.h:33
T select(T mask, T from0, T from1)
Definition ct_utils.h:45
word word8_sub3(word z[8], const word x[8], const word y[8], word carry)
Definition mp_asmi.h:110
void bigint_sub2_rev(word x[], const word y[], size_t y_size)
Definition mp_asm.cpp:179
word word_sub(word x, word y, word *carry)
Definition mp_asmi.h:66
void bigint_linmul3(word z[], const word x[], size_t x_size, word y)
Definition mp_asm.cpp:238
word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size)
Definition mp_asm.cpp:158
word word8_sub2(word x[8], const word y[8], word carry)
Definition mp_asmi.h:78
void bigint_add3(word z[], const word x[], size_t x_size, const word y[], size_t y_size)
Definition mp_asm.cpp:148
void bigint_cnd_swap(word cnd, word x[], word y[], size_t size)
Definition mp_asm.cpp:25
word bigint_cnd_add(word cnd, word x[], const word y[], size_t size)
Definition mp_asm.cpp:42
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_cnd_sub(word cnd, word x[], const word y[], size_t size)
Definition mp_asm.cpp:64
word word8_linmul2(word x[8], word y, word carry)
Definition mp_asmi.h:127
word word8_add3(word z[8], const word x[8], const word y[8], word carry)
Definition mp_asmi.h:49
void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size)
Definition mp_asm.cpp:139
word word_madd2(word a, word b, word *c)
Definition mp_asm.h:86
word word_add(word x, word y, word *carry)
Definition mp_asmi.h:21
word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size)
Definition mp_asm.cpp:93
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_rev(word x[8], const word y[8], word carry)
Definition mp_asmi.h:94
void bigint_cnd_abs(word cnd, word x[], size_t size)
Definition mp_asm.cpp:78
void bigint_linmul2(word x[], size_t x_size, word y)
Definition mp_asm.cpp:220
word bigint_sub3(word z[], const word x[], size_t x_size, const word y[], size_t y_size)
Definition mp_asm.cpp:198
Internal_Error(const std::string &err)
Definition exceptn.h:47