1 #include "tommath_private.h"
2 #ifdef BN_MP_MUL_D_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis
4  *
5  * LibTomMath is a library that provides multiple-precision
6  * integer arithmetic as well as number theoretic functionality.
7  *
8  * The library was designed directly after the MPI library by
9  * Michael Fromberger but has been written from scratch with
10  * additional optimizations in place.
11  *
12  * SPDX-License-Identifier: Unlicense
13  */
14 
15 /* multiply by a digit */
16 int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c)
17 {
18    mp_digit u, *tmpa, *tmpc;
19    mp_word  r;
20    int      ix, res, olduse;
21 
22    /* make sure c is big enough to hold a*b */
23    if (c->alloc < (a->used + 1)) {
24       if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
25          return res;
26       }
27    }
28 
29    /* get the original destinations used count */
30    olduse = c->used;
31 
32    /* set the sign */
33    c->sign = a->sign;
34 
35    /* alias for a->dp [source] */
36    tmpa = a->dp;
37 
38    /* alias for c->dp [dest] */
39    tmpc = c->dp;
40 
41    /* zero carry */
42    u = 0;
43 
44    /* compute columns */
45    for (ix = 0; ix < a->used; ix++) {
46       /* compute product and carry sum for this term */
47       r       = (mp_word)u + ((mp_word)*tmpa++ * (mp_word)b);
48 
49       /* mask off higher bits to get a single digit */
50       *tmpc++ = (mp_digit)(r & (mp_word)MP_MASK);
51 
52       /* send carry into next iteration */
53       u       = (mp_digit)(r >> (mp_word)DIGIT_BIT);
54    }
55 
56    /* store final carry [if any] and increment ix offset  */
57    *tmpc++ = u;
58    ++ix;
59 
60    /* now zero digits above the top */
61    while (ix++ < olduse) {
62       *tmpc++ = 0;
63    }
64 
65    /* set used count */
66    c->used = a->used + 1;
67    mp_clamp(c);
68 
69    return MP_OKAY;
70 }
71 #endif
72 
73 /* ref:         $Format:%D$ */
74 /* git commit:  $Format:%H$ */
75 /* commit time: $Format:%ai$ */
76