Coverage Report

Created: 2025-10-28 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dropbear/libtommath/bn_s_mp_mul_digs.c
Line
Count
Source
1
#include "tommath_private.h"
2
#ifdef BN_S_MP_MUL_DIGS_C
3
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
4
/* SPDX-License-Identifier: Unlicense */
5
6
/* multiplies |a| * |b| and only computes upto digs digits of result
7
 * HAC pp. 595, Algorithm 14.12  Modified so you can control how
8
 * many digits of output are created.
9
 */
10
mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
11
64.0k
{
12
64.0k
   mp_int  t;
13
64.0k
   mp_err  err;
14
64.0k
   int     pa, pb, ix, iy;
15
64.0k
   mp_digit u;
16
64.0k
   mp_word r;
17
64.0k
   mp_digit tmpx, *tmpt, *tmpy;
18
19
64.0k
   if (digs < 0) {
20
0
      return MP_VAL;
21
0
   }
22
23
   /* can we use the fast multiplier? */
24
64.0k
   if ((digs < MP_WARRAY) &&
25
64.0k
       (MP_MIN(a->used, b->used) < MP_MAXFAST)) {
26
64.0k
      return s_mp_mul_digs_fast(a, b, c, digs);
27
64.0k
   }
28
29
0
   if ((err = mp_init_size(&t, digs)) != MP_OKAY) {
30
0
      return err;
31
0
   }
32
0
   t.used = digs;
33
34
   /* compute the digits of the product directly */
35
0
   pa = a->used;
36
0
   for (ix = 0; ix < pa; ix++) {
37
      /* set the carry to zero */
38
0
      u = 0;
39
40
      /* limit ourselves to making digs digits of output */
41
0
      pb = MP_MIN(b->used, digs - ix);
42
43
      /* setup some aliases */
44
      /* copy of the digit from a used within the nested loop */
45
0
      tmpx = a->dp[ix];
46
47
      /* an alias for the destination shifted ix places */
48
0
      tmpt = t.dp + ix;
49
50
      /* an alias for the digits of b */
51
0
      tmpy = b->dp;
52
53
      /* compute the columns of the output and propagate the carry */
54
0
      for (iy = 0; iy < pb; iy++) {
55
         /* compute the column as a mp_word */
56
0
         r       = (mp_word)*tmpt +
57
0
                   ((mp_word)tmpx * (mp_word)*tmpy++) +
58
0
                   (mp_word)u;
59
60
         /* the new column is the lower part of the result */
61
0
         *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK);
62
63
         /* get the carry word from the result */
64
0
         u       = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT);
65
0
      }
66
      /* set carry if it is placed below digs */
67
0
      if ((ix + iy) < digs) {
68
0
         *tmpt = u;
69
0
      }
70
0
   }
71
72
0
   mp_clamp(&t);
73
0
   mp_exch(&t, c);
74
75
0
   mp_clear(&t);
76
0
   return MP_OKAY;
77
0
}
78
#endif