1
|
1 /* LibTomMath, multiple-precision integer library -- Tom St Denis |
|
2 * |
|
3 * LibTomMath is a library that provides multiple-precision |
|
4 * integer arithmetic as well as number theoretic functionality. |
|
5 * |
|
6 * The library was designed directly after the MPI library by |
|
7 * Michael Fromberger but has been written from scratch with |
|
8 * additional optimizations in place. |
|
9 * |
|
10 * The library is free for all purposes without any express |
|
11 * guarantee it works. |
|
12 * |
|
13 * Tom St Denis, [email protected], http://math.libtomcrypt.org |
|
14 */ |
|
15 #include <tommath.h> |
|
16 |
|
17 /* low level addition, based on HAC pp.594, Algorithm 14.7 */ |
|
18 int |
|
19 s_mp_add (mp_int * a, mp_int * b, mp_int * c) |
|
20 { |
|
21 mp_int *x; |
|
22 int olduse, res, min, max; |
|
23 |
|
24 /* find sizes, we let |a| <= |b| which means we have to sort |
|
25 * them. "x" will point to the input with the most digits |
|
26 */ |
|
27 if (a->used > b->used) { |
|
28 min = b->used; |
|
29 max = a->used; |
|
30 x = a; |
|
31 } else { |
|
32 min = a->used; |
|
33 max = b->used; |
|
34 x = b; |
|
35 } |
|
36 |
|
37 /* init result */ |
|
38 if (c->alloc < max + 1) { |
|
39 if ((res = mp_grow (c, max + 1)) != MP_OKAY) { |
|
40 return res; |
|
41 } |
|
42 } |
|
43 |
|
44 /* get old used digit count and set new one */ |
|
45 olduse = c->used; |
|
46 c->used = max + 1; |
|
47 |
|
48 { |
|
49 register mp_digit u, *tmpa, *tmpb, *tmpc; |
|
50 register int i; |
|
51 |
|
52 /* alias for digit pointers */ |
|
53 |
|
54 /* first input */ |
|
55 tmpa = a->dp; |
|
56 |
|
57 /* second input */ |
|
58 tmpb = b->dp; |
|
59 |
|
60 /* destination */ |
|
61 tmpc = c->dp; |
|
62 |
|
63 /* zero the carry */ |
|
64 u = 0; |
|
65 for (i = 0; i < min; i++) { |
|
66 /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ |
|
67 *tmpc = *tmpa++ + *tmpb++ + u; |
|
68 |
|
69 /* U = carry bit of T[i] */ |
|
70 u = *tmpc >> ((mp_digit)DIGIT_BIT); |
|
71 |
|
72 /* take away carry bit from T[i] */ |
|
73 *tmpc++ &= MP_MASK; |
|
74 } |
|
75 |
|
76 /* now copy higher words if any, that is in A+B |
|
77 * if A or B has more digits add those in |
|
78 */ |
|
79 if (min != max) { |
|
80 for (; i < max; i++) { |
|
81 /* T[i] = X[i] + U */ |
|
82 *tmpc = x->dp[i] + u; |
|
83 |
|
84 /* U = carry bit of T[i] */ |
|
85 u = *tmpc >> ((mp_digit)DIGIT_BIT); |
|
86 |
|
87 /* take away carry bit from T[i] */ |
|
88 *tmpc++ &= MP_MASK; |
|
89 } |
|
90 } |
|
91 |
|
92 /* add carry */ |
|
93 *tmpc++ = u; |
|
94 |
|
95 /* clear digits above oldused */ |
|
96 for (i = c->used; i < olduse; i++) { |
|
97 *tmpc++ = 0; |
|
98 } |
|
99 } |
|
100 |
|
101 mp_clamp (c); |
|
102 return MP_OKAY; |
|
103 } |