8 #include <botan/internal/mp_core.h> 9 #include <botan/internal/mp_asmi.h> 10 #include <botan/internal/assert.h> 11 #include <botan/mem_ops.h> 20 void karatsuba_mul(word z[],
const word x[],
const word y[],
size_t N,
23 if(N < BOTAN_KARAT_MUL_THRESHOLD || N % 2)
35 const size_t N2 = N / 2;
38 const word* x1 = x + N2;
40 const word* y1 = y + N2;
61 karatsuba_mul(workspace, z0, z1, N2, workspace+N);
64 karatsuba_mul(z0, x0, y0, N2, workspace+N);
65 karatsuba_mul(z1, x1, y1, N2, workspace+N);
67 const size_t blocks_of_8 = N - (N % 8);
71 for(
size_t j = 0; j != blocks_of_8; j += 8)
72 ws_carry =
word8_add3(workspace + N + j, z0 + j, z1 + j, ws_carry);
74 for(
size_t j = blocks_of_8; j != N; ++j)
75 workspace[N + j] =
word_add(z0[j], z1[j], &ws_carry);
79 for(
size_t j = 0; j != blocks_of_8; j += 8)
80 z_carry =
word8_add2(z + N2 + j, workspace + N + j, z_carry);
82 for(
size_t j = blocks_of_8; j != N; ++j)
83 z[N2 + j] =
word_add(z[N2 + j], workspace[N + j], &z_carry);
85 z[N + N2] =
word_add(z[N + N2], ws_carry, &z_carry);
88 for(
size_t j = 1; j != N2; ++j)
92 if((cmp0 == cmp1) || (cmp0 == 0) || (cmp1 == 0))
101 void karatsuba_sqr(word z[],
const word x[],
size_t N, word workspace[])
103 if(N < BOTAN_KARAT_SQR_THRESHOLD || N % 2)
115 const size_t N2 = N / 2;
118 const word* x1 = x + N2;
133 karatsuba_sqr(workspace, z0, N2, workspace+N);
136 karatsuba_sqr(z0, x0, N2, workspace+N);
137 karatsuba_sqr(z1, x1, N2, workspace+N);
139 const size_t blocks_of_8 = N - (N % 8);
143 for(
size_t j = 0; j != blocks_of_8; j += 8)
144 ws_carry =
word8_add3(workspace + N + j, z0 + j, z1 + j, ws_carry);
146 for(
size_t j = blocks_of_8; j != N; ++j)
147 workspace[N + j] =
word_add(z0[j], z1[j], &ws_carry);
151 for(
size_t j = 0; j != blocks_of_8; j += 8)
152 z_carry =
word8_add2(z + N2 + j, workspace + N + j, z_carry);
154 for(
size_t j = blocks_of_8; j != N; ++j)
155 z[N2 + j] =
word_add(z[N2 + j], workspace[N + j], &z_carry);
157 z[N + N2] =
word_add(z[N + N2], ws_carry, &z_carry);
160 for(
size_t j = 1; j != N2; ++j)
175 size_t karatsuba_size(
size_t z_size,
176 size_t x_size,
size_t x_sw,
177 size_t y_size,
size_t y_sw)
179 if(x_sw > x_size || x_sw > y_size || y_sw > x_size || y_sw > y_size)
182 if(((x_size == x_sw) && (x_size % 2)) ||
183 ((y_size == y_sw) && (y_size % 2)))
186 const size_t start = (x_sw > y_sw) ? x_sw : y_sw;
187 const size_t end = (x_size < y_size) ? x_size : y_size;
196 for(
size_t j = start; j <= end; ++j)
204 if(x_sw <= j && j <= x_size && y_sw <= j && j <= y_size)
207 (j+2) <= x_size && (j+2) <= y_size && 2*(j+2) <= z_size)
219 size_t karatsuba_size(
size_t z_size,
size_t x_size,
size_t x_sw)
228 for(
size_t j = x_sw; j <= x_size; ++j)
236 if(j % 4 == 2 && (j+2) <= x_size && 2*(j+2) <= z_size)
250 const word x[],
size_t x_size,
size_t x_sw,
251 const word y[],
size_t y_size,
size_t y_sw)
253 BOTAN_ASSERT(z_size > x_sw && z_size > y_sw && z_size - x_sw >= y_sw,
"Sufficient output size");
263 else if(x_sw <= 4 && x_size >= 4 &&
264 y_sw <= 4 && y_size >= 4 && z_size >= 8)
268 else if(x_sw <= 6 && x_size >= 6 &&
269 y_sw <= 6 && y_size >= 6 && z_size >= 12)
273 else if(x_sw <= 8 && x_size >= 8 &&
274 y_sw <= 8 && y_size >= 8 && z_size >= 16)
278 else if(x_sw <= 16 && x_size >= 16 &&
279 y_sw <= 16 && y_size >= 16 && z_size >= 32)
283 else if(x_sw < BOTAN_KARAT_MUL_THRESHOLD ||
284 y_sw < BOTAN_KARAT_MUL_THRESHOLD ||
291 const size_t N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw);
296 karatsuba_mul(z, x, y, N, workspace);
307 const word x[],
size_t x_size,
size_t x_sw)
309 BOTAN_ASSERT(z_size/2 >= x_sw,
"Sufficient output size");
315 else if(x_sw <= 4 && x_size >= 4 && z_size >= 8)
319 else if(x_sw <= 6 && x_size >= 6 && z_size >= 12)
323 else if(x_sw <= 8 && x_size >= 8 && z_size >= 16)
327 else if(x_sw <= 16 && x_size >= 16 && z_size >= 32)
331 else if(x_size < BOTAN_KARAT_SQR_THRESHOLD || !workspace)
337 const size_t N = karatsuba_size(z_size, x_size, x_sw);
342 karatsuba_sqr(z, x, N, workspace);
void bigint_simple_mul(word z[], const word x[], size_t x_size, const word y[], size_t y_size)
word word8_add2(word x[8], const word y[8], word carry)
void clear_mem(T *ptr, size_t n)
word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size)
void bigint_comba_mul4(word z[8], const word x[4], const word y[4])
word bigint_sub3(word z[], const word x[], size_t x_size, const word y[], size_t y_size)
#define BOTAN_ASSERT(expr, msg)
void bigint_linmul3(word z[], const word x[], size_t x_size, word y)
void bigint_comba_sqr16(word z[32], const word x[16])
void bigint_sqr(word z[], size_t z_size, word workspace[], const word x[], size_t x_size, size_t x_sw)
word word8_add3(word z[8], const word x[8], const word y[8], word carry)
void bigint_comba_mul8(word z[16], const word x[8], const word y[8])
void bigint_mul(word z[], size_t z_size, word workspace[], const word x[], size_t x_size, size_t x_sw, const word y[], size_t y_size, size_t y_sw)
void bigint_comba_sqr8(word z[16], const word x[8])
void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size)
void bigint_comba_mul16(word z[32], const word x[16], const word y[16])
word word_add(word x, word y, word *carry)
void bigint_comba_mul6(word z[12], const word x[6], const word y[6])
void bigint_simple_sqr(word z[], const word x[], size_t x_size)
void bigint_comba_sqr4(word z[8], const word x[4])
void bigint_comba_sqr6(word z[12], const word x[6])
s32bit bigint_cmp(const word x[], size_t x_size, const word y[], size_t y_size)