Home | History | Annotate | Download | only in libtommath
      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 (at) 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 $ */
     98