1/*	$NetBSD: bn_mp_add_d.c,v 1.2 2017/01/28 21:31:47 christos Exp $	*/
2
3#include <tommath.h>
4#ifdef BN_MP_ADD_D_C
5/* LibTomMath, multiple-precision integer library -- Tom St Denis
6 *
7 * LibTomMath is a library that provides multiple-precision
8 * integer arithmetic as well as number theoretic functionality.
9 *
10 * The library was designed directly after the MPI library by
11 * Michael Fromberger but has been written from scratch with
12 * additional optimizations in place.
13 *
14 * The library is free for all purposes without any express
15 * guarantee it works.
16 *
17 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
18 */
19
20/* single digit addition */
21int
22mp_add_d (mp_int * a, mp_digit b, mp_int * c)
23{
24  int     res, ix, oldused;
25  mp_digit *tmpa, *tmpc, mu;
26
27  /* grow c as required */
28  if (c->alloc < a->used + 1) {
29     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
30        return res;
31     }
32  }
33
34  /* if a is negative and |a| >= b, call c = |a| - b */
35  if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
36     /* temporarily fix sign of a */
37     a->sign = MP_ZPOS;
38
39     /* c = |a| - b */
40     res = mp_sub_d(a, b, c);
41
42     /* fix sign  */
43     a->sign = c->sign = MP_NEG;
44
45     /* clamp */
46     mp_clamp(c);
47
48     return res;
49  }
50
51  /* old number of used digits in c */
52  oldused = c->used;
53
54  /* sign always positive */
55  c->sign = MP_ZPOS;
56
57  /* source alias */
58  tmpa    = a->dp;
59
60  /* destination alias */
61  tmpc    = c->dp;
62
63  /* if a is positive */
64  if (a->sign == MP_ZPOS) {
65     /* add digit, after this we're propagating
66      * the carry.
67      */
68     *tmpc   = *tmpa++ + b;
69     mu      = *tmpc >> DIGIT_BIT;
70     *tmpc++ &= MP_MASK;
71
72     /* now handle rest of the digits */
73     for (ix = 1; ix < a->used; ix++) {
74        *tmpc   = *tmpa++ + mu;
75        mu      = *tmpc >> DIGIT_BIT;
76        *tmpc++ &= MP_MASK;
77     }
78     /* set final carry */
79     ix++;
80     *tmpc++  = mu;
81
82     /* setup size */
83     c->used = a->used + 1;
84  } else {
85     /* a was negative and |a| < b */
86     c->used  = 1;
87
88     /* the result is a single digit */
89     if (a->used == 1) {
90        *tmpc++  =  b - a->dp[0];
91     } else {
92        *tmpc++  =  b;
93     }
94
95     /* setup count so the clearing of oldused
96      * can fall through correctly
97      */
98     ix       = 1;
99  }
100
101  /* now zero to oldused */
102  while (ix++ < oldused) {
103     *tmpc++ = 0;
104  }
105  mp_clamp(c);
106
107  return MP_OKAY;
108}
109
110#endif
111
112/* Source: /cvs/libtom/libtommath/bn_mp_add_d.c,v  */
113/* Revision: 1.5  */
114/* Date: 2006/12/28 01:25:13  */
115