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@gmail.com, http://libtom.org
16 */
17
18/* single digit addition */
19int
20mp_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.5 $ */
112/* $Date: 2006/12/28 01:25:13 $ */
113