1 #include <tommath.h> 2 #ifdef BN_MP_ADD_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 addition */ 19 int 20 mp_add_d (mp_int * a, mp_digit b, mp_int * c) 21 { 22 int res, ix, oldused; 23 mp_digit *tmpa, *tmpc, mu; 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 and |a| >= b, call c = |a| - b */ 33 if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) { 34 /* temporarily fix sign of a */ 35 a->sign = MP_ZPOS; 36 37 /* c = |a| - b */ 38 res = mp_sub_d(a, b, c); 39 40 /* fix sign */ 41 a->sign = c->sign = MP_NEG; 42 43 /* clamp */ 44 mp_clamp(c); 45 46 return res; 47 } 48 49 /* old number of used digits in c */ 50 oldused = c->used; 51 52 /* sign always positive */ 53 c->sign = MP_ZPOS; 54 55 /* source alias */ 56 tmpa = a->dp; 57 58 /* destination alias */ 59 tmpc = c->dp; 60 61 /* if a is positive */ 62 if (a->sign == MP_ZPOS) { 63 /* add digit, after this we're propagating 64 * the carry. 65 */ 66 *tmpc = *tmpa++ + b; 67 mu = *tmpc >> DIGIT_BIT; 68 *tmpc++ &= MP_MASK; 69 70 /* now handle rest of the digits */ 71 for (ix = 1; ix < a->used; ix++) { 72 *tmpc = *tmpa++ + mu; 73 mu = *tmpc >> DIGIT_BIT; 74 *tmpc++ &= MP_MASK; 75 } 76 /* set final carry */ 77 ix++; 78 *tmpc++ = mu; 79 80 /* setup size */ 81 c->used = a->used + 1; 82 } else { 83 /* a was negative and |a| < b */ 84 c->used = 1; 85 86 /* the result is a single digit */ 87 if (a->used == 1) { 88 *tmpc++ = b - a->dp[0]; 89 } else { 90 *tmpc++ = b; 91 } 92 93 /* setup count so the clearing of oldused 94 * can fall through correctly 95 */ 96 ix = 1; 97 } 98 99 /* now zero to oldused */ 100 while (ix++ < oldused) { 101 *tmpc++ = 0; 102 } 103 mp_clamp(c); 104 105 return MP_OKAY; 106 } 107 108 #endif 109 110 /* $Source: /cvs/libtom/libtommath/bn_mp_add_d.c,v $ */ 111 /* $Revision: 1.4 $ */ 112 /* $Date: 2006/03/31 14:18:44 $ */ 113