diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-06-14 21:48:00 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-06-14 21:48:00 (GMT) |
commit | 15e17d01d57f28aa3ccb9adcc344937c4b5a34e0 (patch) | |
tree | 80050a4af1fcd9e60dbc7cf57462a7ed505974c9 /libtommath/bn_mp_mul.c | |
parent | e69d76af16939ec4327b1793f8a2cb358a141972 (diff) | |
parent | db7fa65dce753b80d5f2a87799aabd481e9144a2 (diff) | |
download | tcl-15e17d01d57f28aa3ccb9adcc344937c4b5a34e0.zip tcl-15e17d01d57f28aa3ccb9adcc344937c4b5a34e0.tar.gz tcl-15e17d01d57f28aa3ccb9adcc344937c4b5a34e0.tar.bz2 |
Latest libtommath's "develop" branch adapted for Tcl 8.6. And Tcl 8.6 adapted for changes in libtommath
Diffstat (limited to 'libtommath/bn_mp_mul.c')
-rw-r--r-- | libtommath/bn_mp_mul.c | 84 |
1 files changed, 53 insertions, 31 deletions
diff --git a/libtommath/bn_mp_mul.c b/libtommath/bn_mp_mul.c index f83b1b7..f0ca04a 100644 --- a/libtommath/bn_mp_mul.c +++ b/libtommath/bn_mp_mul.c @@ -1,33 +1,59 @@ #include "tommath_private.h" #ifdef BN_MP_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * SPDX-License-Identifier: Unlicense - */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ /* high level multiplication (handles sign) */ -int mp_mul(const mp_int *a, const mp_int *b, mp_int *c) +mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c) { - int res, neg; + mp_err err; + mp_sign neg; +#ifdef BN_S_MP_BALANCE_MUL_C + int len_b, len_a; +#endif neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; +#ifdef BN_S_MP_BALANCE_MUL_C + len_a = a->used; + len_b = b->used; + + if (len_a == len_b) { + goto GO_ON; + } + /* + * Check sizes. The smaller one needs to be larger than the Karatsuba cut-off. + * The bigger one needs to be at least about one KARATSUBA_MUL_CUTOFF bigger + * to make some sense, but it depends on architecture, OS, position of the + * stars... so YMMV. + * Using it to cut the input into slices small enough for fast_s_mp_mul_digs + * was actually slower on the author's machine, but YMMV. + */ + if ((MP_MIN(len_a, len_b) < MP_KARATSUBA_MUL_CUTOFF) + || ((MP_MAX(len_a, len_b) / 2) < MP_KARATSUBA_MUL_CUTOFF)) { + goto GO_ON; + } + /* + * Not much effect was observed below a ratio of 1:2, but again: YMMV. + */ + if ((MP_MAX(len_a, len_b) / MP_MIN(len_a, len_b)) < 2) { + goto GO_ON; + } + + err = s_mp_balance_mul(a,b,c); + goto END; + +GO_ON: +#endif /* use Toom-Cook? */ -#ifdef BN_MP_TOOM_MUL_C - if (MIN(a->used, b->used) >= TOOM_MUL_CUTOFF) { - res = mp_toom_mul(a, b, c); +#ifdef BN_S_MP_TOOM_MUL_C + if (MP_MIN(a->used, b->used) >= MP_TOOM_MUL_CUTOFF) { + err = s_mp_toom_mul(a, b, c); } else #endif -#ifdef BN_MP_KARATSUBA_MUL_C +#ifdef BN_S_MP_KARATSUBA_MUL_C /* use Karatsuba? */ - if (MIN(a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { - res = mp_karatsuba_mul(a, b, c); + if (MP_MIN(a->used, b->used) >= MP_KARATSUBA_MUL_CUTOFF) { + err = s_mp_karatsuba_mul(a, b, c); } else #endif { @@ -39,26 +65,22 @@ int mp_mul(const mp_int *a, const mp_int *b, mp_int *c) */ int digs = a->used + b->used + 1; -#ifdef BN_FAST_S_MP_MUL_DIGS_C - if ((digs < (int)MP_WARRAY) && - (MIN(a->used, b->used) <= - (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { - res = fast_s_mp_mul_digs(a, b, c, digs); +#ifdef BN_S_MP_MUL_DIGS_FAST_C + if ((digs < MP_WARRAY) && + (MP_MIN(a->used, b->used) <= MP_MAXFAST)) { + err = s_mp_mul_digs_fast(a, b, c, digs); } else #endif { #ifdef BN_S_MP_MUL_DIGS_C - res = s_mp_mul(a, b, c); /* uses s_mp_mul_digs */ + err = s_mp_mul_digs(a, b, c, a->used + b->used + 1); #else - res = MP_VAL; + err = MP_VAL; #endif } } +END: c->sign = (c->used > 0) ? neg : MP_ZPOS; - return res; + return err; } #endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ |