Line data Source code
1 : #include "tommath_private.h" 2 : #ifdef BN_MP_MUL_C 3 : /* LibTomMath, multiple-precision integer library -- Tom St Denis */ 4 : /* SPDX-License-Identifier: Unlicense */ 5 : 6 : /* high level multiplication (handles sign) */ 7 120283 : mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c) 8 : { 9 5280 : mp_err err; 10 120283 : int min_len = MP_MIN(a->used, b->used), 11 120283 : max_len = MP_MAX(a->used, b->used), 12 120283 : digs = a->used + b->used + 1; 13 120283 : mp_sign neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; 14 : 15 120283 : if (MP_HAS(S_MP_BALANCE_MUL) && 16 : /* Check sizes. The smaller one needs to be larger than the Karatsuba cut-off. 17 : * The bigger one needs to be at least about one MP_KARATSUBA_MUL_CUTOFF bigger 18 : * to make some sense, but it depends on architecture, OS, position of the 19 : * stars... so YMMV. 20 : * Using it to cut the input into slices small enough for fast_s_mp_mul_digs 21 : * was actually slower on the author's machine, but YMMV. 22 : */ 23 906 : (min_len >= MP_KARATSUBA_MUL_CUTOFF) && 24 906 : ((max_len / 2) >= MP_KARATSUBA_MUL_CUTOFF) && 25 : /* Not much effect was observed below a ratio of 1:2, but again: YMMV. */ 26 0 : (max_len >= (2 * min_len))) { 27 0 : err = s_mp_balance_mul(a,b,c); 28 120283 : } else if (MP_HAS(S_MP_TOOM_MUL) && 29 : (min_len >= MP_TOOM_MUL_CUTOFF)) { 30 0 : err = s_mp_toom_mul(a, b, c); 31 120283 : } else if (MP_HAS(S_MP_KARATSUBA_MUL) && 32 : (min_len >= MP_KARATSUBA_MUL_CUTOFF)) { 33 906 : err = s_mp_karatsuba_mul(a, b, c); 34 119377 : } else if (MP_HAS(S_MP_MUL_DIGS_FAST) && 35 : /* can we use the fast multiplier? 36 : * 37 : * The fast multiplier can be used if the output will 38 : * have less than MP_WARRAY digits and the number of 39 : * digits won't affect carry propagation 40 : */ 41 119377 : (digs < MP_WARRAY) && 42 5280 : (min_len <= MP_MAXFAST)) { 43 119377 : err = s_mp_mul_digs_fast(a, b, c, digs); 44 0 : } else if (MP_HAS(S_MP_MUL_DIGS)) { 45 0 : err = s_mp_mul_digs(a, b, c, digs); 46 : } else { 47 : err = MP_VAL; 48 : } 49 120283 : c->sign = (c->used > 0) ? neg : MP_ZPOS; 50 120283 : return err; 51 : } 52 : #endif