Home | History | Annotate | Download | only in libtommath
      1 #include <tommath.h>
      2 #ifdef BN_MP_SUB_D_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 /* single digit subtraction */
     19 int
     20 mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
     21 {
     22   mp_digit *tmpa, *tmpc, mu;
     23   int       res, ix, oldused;
     24 
     25   /* grow c as required */
     26   if (c->alloc < a->used + 1) {
     27      if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
     28         return res;
     29      }
     30   }
     31 
     32   /* if a is negative just do an unsigned
     33    * addition [with fudged signs]
     34    */
     35   if (a->sign == MP_NEG) {
     36      a->sign = MP_ZPOS;
     37      res     = mp_add_d(a, b, c);
     38      a->sign = c->sign = MP_NEG;
     39 
     40      /* clamp */
     41      mp_clamp(c);
     42 
     43      return res;
     44   }
     45 
     46   /* setup regs */
     47   oldused = c->used;
     48   tmpa    = a->dp;
     49   tmpc    = c->dp;
     50 
     51   /* if a <= b simply fix the single digit */
     52   if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
     53      if (a->used == 1) {
     54         *tmpc++ = b - *tmpa;
     55      } else {
     56         *tmpc++ = b;
     57      }
     58      ix      = 1;
     59 
     60      /* negative/1digit */
     61      c->sign = MP_NEG;
     62      c->used = 1;
     63   } else {
     64      /* positive/size */
     65      c->sign = MP_ZPOS;
     66      c->used = a->used;
     67 
     68      /* subtract first digit */
     69      *tmpc    = *tmpa++ - b;
     70      mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
     71      *tmpc++ &= MP_MASK;
     72 
     73      /* handle rest of the digits */
     74      for (ix = 1; ix < a->used; ix++) {
     75         *tmpc    = *tmpa++ - mu;
     76         mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
     77         *tmpc++ &= MP_MASK;
     78      }
     79   }
     80 
     81   /* zero excess digits */
     82   while (ix++ < oldused) {
     83      *tmpc++ = 0;
     84   }
     85   mp_clamp(c);
     86   return MP_OKAY;
     87 }
     88 
     89 #endif
     90 
     91 /* $Source: /cvs/libtom/libtommath/bn_mp_sub_d.c,v $ */
     92 /* $Revision: 1.5 $ */
     93 /* $Date: 2006/03/31 14:18:44 $ */
     94