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)