/* LibTomMath, multiple-precision integer library -- Tom St Denis * * LibTomMath is library that provides for multiple-precision * integer arithmetic as well as number theoretic functionality. * * The library is designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@iahu.ca, http://libtommath.iahu.ca */ #include /* shift right by a certain bit count (store quotient in c, remainder in d) */ int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) { mp_digit D, r, rr; int x, res; mp_int t; /* if the shift count is <= 0 then we do no work */ if (b <= 0) { res = mp_copy (a, c); if (d != NULL) { mp_zero (d); } return res; } if ((res = mp_init (&t)) != MP_OKAY) { return res; } /* get the remainder */ if (d != NULL) { if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) { mp_clear (&t); return res; } } /* copy */ if ((res = mp_copy (a, c)) != MP_OKAY) { mp_clear (&t); return res; } /* shift by as many digits in the bit count */ mp_rshd (c, b / DIGIT_BIT); /* shift any bit count < DIGIT_BIT */ D = (mp_digit) (b % DIGIT_BIT); if (D != 0) { r = 0; for (x = c->used - 1; x >= 0; x--) { /* get the lower bits of this word in a temp */ rr = c->dp[x] & ((mp_digit) ((1U << D) - 1U)); /* shift the current word and mix in the carry bits from the previous word */ c->dp[x] = (c->dp[x] >> D) | (r << (DIGIT_BIT - D)); /* set the carry to the carry bits of the current word found above */ r = rr; } } mp_clamp (c); res = MP_OKAY; if (d != NULL) { mp_exch (&t, d); } mp_clear (&t); return MP_OKAY; }