www.usr.com/support/gpl/USR9107_release.1.4.tar.gz
[bcm963xx.git] / userapps / opensource / sshd / libtommath / bn_mp_mul_2d.c
1 #include <tommath.h>
2 #ifdef BN_MP_MUL_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@iahu.ca, http://math.libtomcrypt.org
16  */
17
18 /* shift left by a certain bit count */
19 int mp_mul_2d (mp_int * a, int b, mp_int * c)
20 {
21   mp_digit d;
22   int      res;
23
24   /* copy */
25   if (a != c) {
26      if ((res = mp_copy (a, c)) != MP_OKAY) {
27        return res;
28      }
29   }
30
31   if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
32      if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
33        return res;
34      }
35   }
36
37   /* shift by as many digits in the bit count */
38   if (b >= (int)DIGIT_BIT) {
39     if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
40       return res;
41     }
42   }
43
44   /* shift any bit count < DIGIT_BIT */
45   d = (mp_digit) (b % DIGIT_BIT);
46   if (d != 0) {
47     register mp_digit *tmpc, shift, mask, r, rr;
48     register int x;
49
50     /* bitmask for carries */
51     mask = (((mp_digit)1) << d) - 1;
52
53     /* shift for msbs */
54     shift = DIGIT_BIT - d;
55
56     /* alias */
57     tmpc = c->dp;
58
59     /* carry */
60     r    = 0;
61     for (x = 0; x < c->used; x++) {
62       /* get the higher bits of the current word */
63       rr = (*tmpc >> shift) & mask;
64
65       /* shift the current word and OR in the carry */
66       *tmpc = ((*tmpc << d) | r) & MP_MASK;
67       ++tmpc;
68
69       /* set the carry to the carry bits of the current word */
70       r = rr;
71     }
72     
73     /* set final carry */
74     if (r != 0) {
75        c->dp[(c->used)++] = r;
76     }
77   }
78   mp_clamp (c);
79   return MP_OKAY;
80 }
81 #endif