Merge pull request #578 from PX4/fix_mp_prime_strong_lucas_lefridge_compilation
[libtommath.git] / mp_div_2d.c
blobe523465afb93cb281350d5d7d8f36ddae6e05796
1 #include "tommath_private.h"
2 #ifdef MP_DIV_2D_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 /* SPDX-License-Identifier: Unlicense */
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)
9 mp_err err;
11 if (b < 0) {
12 return MP_VAL;
15 if ((err = mp_copy(a, c)) != MP_OKAY) {
16 return err;
19 /* 'a' should not be used after here - it might be the same as d */
21 /* get the remainder */
22 if (d != NULL) {
23 if ((err = mp_mod_2d(a, b, d)) != MP_OKAY) {
24 return err;
28 /* shift by as many digits in the bit count */
29 if (b >= MP_DIGIT_BIT) {
30 mp_rshd(c, b / MP_DIGIT_BIT);
33 /* shift any bit count < MP_DIGIT_BIT */
34 b %= MP_DIGIT_BIT;
35 if (b != 0u) {
36 int x;
37 mp_digit r, mask, shift;
39 /* mask */
40 mask = ((mp_digit)1 << b) - 1uL;
42 /* shift for lsb */
43 shift = (mp_digit)(MP_DIGIT_BIT - b);
45 /* carry */
46 r = 0;
47 for (x = c->used; x --> 0;) {
48 /* get the lower bits of this word in a temp */
49 mp_digit rr = c->dp[x] & mask;
51 /* shift the current word and mix in the carry bits from the previous word */
52 c->dp[x] = (c->dp[x] >> b) | (r << shift);
54 /* set the carry to the carry bits of the current word found above */
55 r = rr;
58 mp_clamp(c);
59 return MP_OKAY;
61 #endif