/src/dropbear/libtommath/bn_mp_div_2d.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "tommath_private.h" |
2 | | #ifdef BN_MP_DIV_2D_C |
3 | | /* LibTomMath, multiple-precision integer library -- Tom St Denis */ |
4 | | /* SPDX-License-Identifier: Unlicense */ |
5 | | |
6 | | /* shift right by a certain bit count (store quotient in c, optional remainder in d) */ |
7 | | mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) |
8 | 60.2k | { |
9 | 60.2k | mp_digit D, r, rr; |
10 | 60.2k | int x; |
11 | 60.2k | mp_err err; |
12 | | |
13 | | /* if the shift count is <= 0 then we do no work */ |
14 | 60.2k | if (b <= 0) { |
15 | 0 | err = mp_copy(a, c); |
16 | 0 | if (d != NULL) { |
17 | 0 | mp_zero(d); |
18 | 0 | } |
19 | 0 | return err; |
20 | 0 | } |
21 | | |
22 | | /* copy */ |
23 | 60.2k | if ((err = mp_copy(a, c)) != MP_OKAY) { |
24 | 0 | return err; |
25 | 0 | } |
26 | | /* 'a' should not be used after here - it might be the same as d */ |
27 | | |
28 | | /* get the remainder */ |
29 | 60.2k | if (d != NULL) { |
30 | 0 | if ((err = mp_mod_2d(a, b, d)) != MP_OKAY) { |
31 | 0 | return err; |
32 | 0 | } |
33 | 0 | } |
34 | | |
35 | | /* shift by as many digits in the bit count */ |
36 | 60.2k | if (b >= MP_DIGIT_BIT) { |
37 | 0 | mp_rshd(c, b / MP_DIGIT_BIT); |
38 | 0 | } |
39 | | |
40 | | /* shift any bit count < MP_DIGIT_BIT */ |
41 | 60.2k | D = (mp_digit)(b % MP_DIGIT_BIT); |
42 | 60.2k | if (D != 0u) { |
43 | 60.2k | mp_digit *tmpc, mask, shift; |
44 | | |
45 | | /* mask */ |
46 | 60.2k | mask = ((mp_digit)1 << D) - 1uL; |
47 | | |
48 | | /* shift for lsb */ |
49 | 60.2k | shift = (mp_digit)MP_DIGIT_BIT - D; |
50 | | |
51 | | /* alias */ |
52 | 60.2k | tmpc = c->dp + (c->used - 1); |
53 | | |
54 | | /* carry */ |
55 | 60.2k | r = 0; |
56 | 299k | for (x = c->used - 1; x >= 0; x--) { |
57 | | /* get the lower bits of this word in a temp */ |
58 | 239k | rr = *tmpc & mask; |
59 | | |
60 | | /* shift the current word and mix in the carry bits from the previous word */ |
61 | 239k | *tmpc = (*tmpc >> D) | (r << shift); |
62 | 239k | --tmpc; |
63 | | |
64 | | /* set the carry to the carry bits of the current word found above */ |
65 | 239k | r = rr; |
66 | 239k | } |
67 | 60.2k | } |
68 | 60.2k | mp_clamp(c); |
69 | 60.2k | return MP_OKAY; |
70 | 60.2k | } |
71 | | #endif |