/src/dropbear/libtommath/bn_mp_mul_2d.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "tommath_private.h" |
2 | | #ifdef BN_MP_MUL_2D_C |
3 | | /* LibTomMath, multiple-precision integer library -- Tom St Denis */ |
4 | | /* SPDX-License-Identifier: Unlicense */ |
5 | | |
6 | | /* shift left by a certain bit count */ |
7 | | mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) |
8 | 1.34M | { |
9 | 1.34M | mp_digit d; |
10 | 1.34M | mp_err err; |
11 | | |
12 | 1.34M | if (b < 0) { |
13 | 0 | return MP_VAL; |
14 | 0 | } |
15 | | |
16 | | /* copy */ |
17 | 1.34M | if (a != c) { |
18 | 0 | if ((err = mp_copy(a, c)) != MP_OKAY) { |
19 | 0 | return err; |
20 | 0 | } |
21 | 0 | } |
22 | | |
23 | 1.34M | if (c->alloc < (c->used + (b / MP_DIGIT_BIT) + 1)) { |
24 | 324k | if ((err = mp_grow(c, c->used + (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) { |
25 | 0 | return err; |
26 | 0 | } |
27 | 324k | } |
28 | | |
29 | | /* shift by as many digits in the bit count */ |
30 | 1.34M | if (b >= MP_DIGIT_BIT) { |
31 | 0 | if ((err = mp_lshd(c, b / MP_DIGIT_BIT)) != MP_OKAY) { |
32 | 0 | return err; |
33 | 0 | } |
34 | 0 | } |
35 | | |
36 | | /* shift any bit count < MP_DIGIT_BIT */ |
37 | 1.34M | d = (mp_digit)(b % MP_DIGIT_BIT); |
38 | 1.34M | if (d != 0u) { |
39 | 1.34M | mp_digit *tmpc, shift, mask, r, rr; |
40 | 1.34M | int x; |
41 | | |
42 | | /* bitmask for carries */ |
43 | 1.34M | mask = ((mp_digit)1 << d) - (mp_digit)1; |
44 | | |
45 | | /* shift for msbs */ |
46 | 1.34M | shift = (mp_digit)MP_DIGIT_BIT - d; |
47 | | |
48 | | /* alias */ |
49 | 1.34M | tmpc = c->dp; |
50 | | |
51 | | /* carry */ |
52 | 1.34M | r = 0; |
53 | 863M | for (x = 0; x < c->used; x++) { |
54 | | /* get the higher bits of the current word */ |
55 | 862M | rr = (*tmpc >> shift) & mask; |
56 | | |
57 | | /* shift the current word and OR in the carry */ |
58 | 862M | *tmpc = ((*tmpc << d) | r) & MP_MASK; |
59 | 862M | ++tmpc; |
60 | | |
61 | | /* set the carry to the carry bits of the current word */ |
62 | 862M | r = rr; |
63 | 862M | } |
64 | | |
65 | | /* set final carry */ |
66 | 1.34M | if (r != 0u) { |
67 | 2.42k | c->dp[(c->used)++] = r; |
68 | 2.42k | } |
69 | 1.34M | } |
70 | 1.34M | mp_clamp(c); |
71 | 1.34M | return MP_OKAY; |
72 | 1.34M | } |
73 | | #endif |