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 */
21 int
mp_add_d(mp_int * a,mp_digit b,mp_int * c)22 mp_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