Line data Source code
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 49082 : mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d)
8 : {
9 : mp_digit D, r, rr;
10 : int x;
11 : mp_err err;
12 :
13 : /* if the shift count is <= 0 then we do no work */
14 49082 : if (b <= 0) {
15 0 : err = mp_copy(a, c);
16 0 : if (d != NULL) {
17 0 : mp_zero(d);
18 : }
19 0 : return err;
20 : }
21 :
22 : /* copy */
23 49082 : if ((err = mp_copy(a, c)) != MP_OKAY) {
24 0 : return err;
25 : }
26 : /* 'a' should not be used after here - it might be the same as d */
27 :
28 : /* get the remainder */
29 49082 : if (d != NULL) {
30 0 : if ((err = mp_mod_2d(a, b, d)) != MP_OKAY) {
31 0 : return err;
32 : }
33 : }
34 :
35 : /* shift by as many digits in the bit count */
36 49082 : if (b >= MP_DIGIT_BIT) {
37 0 : mp_rshd(c, b / MP_DIGIT_BIT);
38 : }
39 :
40 : /* shift any bit count < MP_DIGIT_BIT */
41 49082 : D = (mp_digit)(b % MP_DIGIT_BIT);
42 49082 : if (D != 0u) {
43 : mp_digit *tmpc, mask, shift;
44 :
45 : /* mask */
46 49082 : mask = ((mp_digit)1 << D) - 1uL;
47 :
48 : /* shift for lsb */
49 49082 : shift = (mp_digit)MP_DIGIT_BIT - D;
50 :
51 : /* alias */
52 49082 : tmpc = c->dp + (c->used - 1);
53 :
54 : /* carry */
55 49082 : r = 0;
56 1501357 : for (x = c->used - 1; x >= 0; x--) {
57 : /* get the lower bits of this word in a temp */
58 1452275 : rr = *tmpc & mask;
59 :
60 : /* shift the current word and mix in the carry bits from the previous word */
61 1452275 : *tmpc = (*tmpc >> D) | (r << shift);
62 1452275 : --tmpc;
63 :
64 : /* set the carry to the carry bits of the current word found above */
65 1452275 : r = rr;
66 : }
67 : }
68 49082 : mp_clamp(c);
69 49082 : return MP_OKAY;
70 : }
71 : #endif
|