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 303683 : mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) 8 : { 9 8258 : mp_digit D, r, rr; 10 8258 : int x; 11 8258 : mp_err err; 12 : 13 : /* if the shift count is <= 0 then we do no work */ 14 303683 : 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 303683 : 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 303683 : 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 303683 : 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 303683 : D = (mp_digit)(b % MP_DIGIT_BIT); 42 303683 : if (D != 0u) { 43 8258 : mp_digit *tmpc, mask, shift; 44 : 45 : /* mask */ 46 303683 : mask = ((mp_digit)1 << D) - 1uL; 47 : 48 : /* shift for lsb */ 49 303683 : shift = (mp_digit)MP_DIGIT_BIT - D; 50 : 51 : /* alias */ 52 303683 : tmpc = c->dp + (c->used - 1); 53 : 54 : /* carry */ 55 303683 : r = 0; 56 14852489 : for (x = c->used - 1; x >= 0; x--) { 57 : /* get the lower bits of this word in a temp */ 58 14548806 : rr = *tmpc & mask; 59 : 60 : /* shift the current word and mix in the carry bits from the previous word */ 61 14548806 : *tmpc = (*tmpc >> D) | (r << shift); 62 14548806 : --tmpc; 63 : 64 : /* set the carry to the carry bits of the current word found above */ 65 14548806 : r = rr; 66 : } 67 : } 68 303683 : mp_clamp(c); 69 303683 : return MP_OKAY; 70 : } 71 : #endif