bn_mp_add_d.c

Go to the documentation of this file.
00001 #include <tommath.h>
00002 #ifdef BN_MP_ADD_D_C
00003 /* LibTomMath, multiple-precision integer library -- Tom St Denis
00004  *
00005  * LibTomMath is a library that provides multiple-precision
00006  * integer arithmetic as well as number theoretic functionality.
00007  *
00008  * The library was designed directly after the MPI library by
00009  * Michael Fromberger but has been written from scratch with
00010  * additional optimizations in place.
00011  *
00012  * The library is free for all purposes without any express
00013  * guarantee it works.
00014  *
00015  * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
00016  */
00017 
00018 /* single digit addition */
00019 int
00020 mp_add_d (mp_int * a, mp_digit b, mp_int * c)
00021 {
00022   int     res, ix, oldused;
00023   mp_digit *tmpa, *tmpc, mu;
00024 
00025   /* grow c as required */
00026   if (c->alloc < a->used + 1) {
00027      if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
00028         return res;
00029      }
00030   }
00031 
00032   /* if a is negative and |a| >= b, call c = |a| - b */
00033   if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
00034      /* temporarily fix sign of a */
00035      a->sign = MP_ZPOS;
00036 
00037      /* c = |a| - b */
00038      res = mp_sub_d(a, b, c);
00039 
00040      /* fix signs  */
00041      a->sign = MP_NEG;
00042      c->sign = (c->used) ? MP_NEG : MP_ZPOS;
00043 
00044      /* clamp */
00045      mp_clamp(c);
00046 
00047      return res;
00048   }
00049 
00050   /* old number of used digits in c */
00051   oldused = c->used;
00052 
00053   /* sign always positive */
00054   c->sign = MP_ZPOS;
00055 
00056   /* source alias */
00057   tmpa    = a->dp;
00058 
00059   /* destination alias */
00060   tmpc    = c->dp;
00061 
00062   /* if a is positive */
00063   if (a->sign == MP_ZPOS) {
00064      /* add digit, after this we're propagating
00065       * the carry.
00066       */
00067      *tmpc   = *tmpa++ + b;
00068      mu      = *tmpc >> DIGIT_BIT;
00069      *tmpc++ &= MP_MASK;
00070 
00071      /* now handle rest of the digits */
00072      for (ix = 1; ix < a->used; ix++) {
00073         *tmpc   = *tmpa++ + mu;
00074         mu      = *tmpc >> DIGIT_BIT;
00075         *tmpc++ &= MP_MASK;
00076      }
00077      /* set final carry */
00078      ix++;
00079      *tmpc++  = mu;
00080 
00081      /* setup size */
00082      c->used = a->used + 1;
00083   } else {
00084      /* a was negative and |a| < b */
00085      c->used  = 1;
00086 
00087      /* the result is a single digit */
00088      if (a->used == 1) {
00089         *tmpc++  =  b - a->dp[0];
00090      } else {
00091         *tmpc++  =  b;
00092      }
00093 
00094      /* setup count so the clearing of oldused
00095       * can fall through correctly
00096       */
00097      ix       = 1;
00098   }
00099 
00100   /* now zero to oldused */
00101   while (ix++ < oldused) {
00102      *tmpc++ = 0;
00103   }
00104   mp_clamp(c);
00105 
00106   return MP_OKAY;
00107 }
00108 
00109 #endif
00110 
00111 /* $Source: /cvsroot/tcl/libtommath/bn_mp_add_d.c,v $ */
00112 /* Tom's revision is 1.2 */
00113 /* $Revision: 1.4 $ */
00114 /* $Date: 2006/12/01 00:31:32 $ */



Generated on Wed Mar 12 12:18:24 2008 by  doxygen 1.5.1