1 #include "tommath_private.h"
2 #ifdef BN_S_MP_MUL_HIGH_DIGS_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 /* SPDX-License-Identifier: Unlicense */
6 /* multiplies |a| * |b| and does not compute the lower digs digits
7 * [meant to get the higher part of the product]
9 mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
16 mp_digit tmpx, *tmpt, *tmpy;
18 /* can we use the fast multiplier? */
19 if (MP_HAS(S_MP_MUL_HIGH_DIGS_FAST)
20 && ((a->used + b->used + 1) < MP_WARRAY)
21 && (MP_MIN(a->used, b->used) < MP_MAXFAST)) {
22 return s_mp_mul_high_digs_fast(a, b, c, digs);
25 if ((err = mp_init_size(&t, a->used + b->used + 1)) != MP_OKAY) {
28 t.used = a->used + b->used + 1;
32 for (ix = 0; ix < pa; ix++) {
36 /* left hand side of A[ix] * B[iy] */
39 /* alias to the address of where the digits will be stored */
42 /* alias for where to read the right hand side from */
43 tmpy = b->dp + (digs - ix);
45 for (iy = digs - ix; iy < pb; iy++) {
46 /* calculate the double precision result */
48 ((mp_word)tmpx * (mp_word)*tmpy++) +
51 /* get the lower part */
52 *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
55 u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);