void bigint_mul(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, const word y[], size_t y_size, size_t y_sw, word workspace[], size_t ws_size) { clear_mem(z, z_size); if(x_sw == 1) { bigint_linmul3(z, y, y_sw, x[0]); } else if(y_sw == 1) { bigint_linmul3(z, x, x_sw, y[0]); } else if(sized_for_comba_mul<4>(x_sw, x_size, y_sw, y_size, z_size)) { bigint_comba_mul4(z, x, y); } else if(sized_for_comba_mul<6>(x_sw, x_size, y_sw, y_size, z_size)) { bigint_comba_mul6(z, x, y); } else if(sized_for_comba_mul<8>(x_sw, x_size, y_sw, y_size, z_size)) { bigint_comba_mul8(z, x, y); } else if(sized_for_comba_mul<9>(x_sw, x_size, y_sw, y_size, z_size)) { bigint_comba_mul9(z, x, y); } else if(sized_for_comba_mul<16>(x_sw, x_size, y_sw, y_size, z_size)) { bigint_comba_mul16(z, x, y); } else if(x_sw < KARATSUBA_MULTIPLY_THRESHOLD || y_sw < KARATSUBA_MULTIPLY_THRESHOLD || !workspace) { basecase_mul(z, z_size, x, x_sw, y, y_sw); } else { const size_t N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw); if(N && z_size >= 2*N && ws_size >= 2*N) karatsuba_mul(z, x, y, N, workspace); else basecase_mul(z, z_size, x, x_sw, y, y_sw); } }
/* * Squaring Algorithm Dispatcher */ void bigint_sqr(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, word workspace[], size_t ws_size) { clear_mem(z, z_size); BOTAN_ASSERT(z_size/2 >= x_sw, "Output size is sufficient"); if(x_sw == 1) { bigint_linmul3(z, x, x_sw, x[0]); } else if(sized_for_comba_sqr<4>(x_sw, x_size, z_size)) { bigint_comba_sqr4(z, x); } else if(sized_for_comba_sqr<6>(x_sw, x_size, z_size)) { bigint_comba_sqr6(z, x); } else if(sized_for_comba_sqr<8>(x_sw, x_size, z_size)) { bigint_comba_sqr8(z, x); } else if(sized_for_comba_sqr<9>(x_sw, x_size, z_size)) { bigint_comba_sqr9(z, x); } else if(sized_for_comba_sqr<16>(x_sw, x_size, z_size)) { bigint_comba_sqr16(z, x); } else if(x_size < KARATSUBA_SQUARE_THRESHOLD || !workspace) { basecase_sqr(z, z_size, x, x_sw); } else { const size_t N = karatsuba_size(z_size, x_size, x_sw); if(N && z_size >= 2*N && ws_size >= 2*N) karatsuba_sqr(z, x, N, workspace); else basecase_sqr(z, z_size, x, x_sw); } }
/************************************************* * Multiplication Algorithm Dispatcher * *************************************************/ void bigint_mul(word z[], u32bit z_size, word workspace[], const word x[], u32bit x_size, u32bit x_sw, const word y[], u32bit y_size, u32bit y_sw) { if(x_size <= 8 || y_size <= 8) { handle_small_mul(z, z_size, x, x_size, x_sw, y, y_size, y_sw); return; } const u32bit N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw); if(N) { clear_mem(workspace, 2*N); karatsuba_mul(z, x, y, N, workspace); } else bigint_simple_mul(z, x, x_sw, y, y_sw); }