version 0.3.33
[fms.git] / libs / libtommath / bn_mp_div_2d.c
1 #include <tommath.h>
2 #ifdef BN_MP_DIV_2D_C
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis
4  *
5  * LibTomMath is a library that provides multiple-precision
6  * integer arithmetic as well as number theoretic functionality.
7  *
8  * The library was designed directly after the MPI library by
9  * Michael Fromberger but has been written from scratch with
10  * additional optimizations in place.
11  *
12  * The library is free for all purposes without any express
13  * guarantee it works.
14  *
15  * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
16  */
17
18 /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
19 int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
20 {
21   mp_digit D, r, rr;
22   int     x, res;
23   mp_int  t;
24
25
26   /* if the shift count is <= 0 then we do no work */
27   if (b <= 0) {
28     res = mp_copy (a, c);
29     if (d != NULL) {
30       mp_zero (d);
31     }
32     return res;
33   }
34
35   if ((res = mp_init (&t)) != MP_OKAY) {
36     return res;
37   }
38
39   /* get the remainder */
40   if (d != NULL) {
41     if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
42       mp_clear (&t);
43       return res;
44     }
45   }
46
47   /* copy */
48   if ((res = mp_copy (a, c)) != MP_OKAY) {
49     mp_clear (&t);
50     return res;
51   }
52
53   /* shift by as many digits in the bit count */
54   if (b >= (int)DIGIT_BIT) {
55     mp_rshd (c, b / DIGIT_BIT);
56   }
57
58   /* shift any bit count < DIGIT_BIT */
59   D = (mp_digit) (b % DIGIT_BIT);
60   if (D != 0) {
61     register mp_digit *tmpc, mask, shift;
62
63     /* mask */
64     mask = (((mp_digit)1) << D) - 1;
65
66     /* shift for lsb */
67     shift = DIGIT_BIT - D;
68
69     /* alias */
70     tmpc = c->dp + (c->used - 1);
71
72     /* carry */
73     r = 0;
74     for (x = c->used - 1; x >= 0; x--) {
75       /* get the lower  bits of this word in a temp */
76       rr = *tmpc & mask;
77
78       /* shift the current word and mix in the carry bits from the previous word */
79       *tmpc = (*tmpc >> D) | (r << shift);
80       --tmpc;
81
82       /* set the carry to the carry bits of the current word found above */
83       r = rr;
84     }
85   }
86   mp_clamp (c);
87   if (d != NULL) {
88     mp_exch (&t, d);
89   }
90   mp_clear (&t);
91   return MP_OKAY;
92 }
93 #endif
94
95 /* $Source: /cvs/libtom/libtommath/bn_mp_div_2d.c,v $ */
96 /* $Revision: 1.3 $ */
97 /* $Date: 2006/03/31 14:18:44 $ */