Line data Source code
1 : #include "tommath_private.h"
2 : #ifdef BN_S_MP_ADD_C
3 : /* LibTomMath, multiple-precision integer library -- Tom St Denis */
4 : /* SPDX-License-Identifier: Unlicense */
5 :
6 : /* low level addition, based on HAC pp.594, Algorithm 14.7 */
7 107488 : mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
8 : {
9 : const mp_int *x;
10 : mp_err err;
11 : int olduse, min, max;
12 :
13 : /* find sizes, we let |a| <= |b| which means we have to sort
14 : * them. "x" will point to the input with the most digits
15 : */
16 107488 : if (a->used > b->used) {
17 50 : min = b->used;
18 50 : max = a->used;
19 50 : x = a;
20 : } else {
21 107438 : min = a->used;
22 107438 : max = b->used;
23 107438 : x = b;
24 : }
25 :
26 : /* init result */
27 107488 : if (c->alloc < (max + 1)) {
28 114 : if ((err = mp_grow(c, max + 1)) != MP_OKAY) {
29 0 : return err;
30 : }
31 : }
32 :
33 : /* get old used digit count and set new one */
34 107488 : olduse = c->used;
35 107488 : c->used = max + 1;
36 :
37 : {
38 : mp_digit u, *tmpa, *tmpb, *tmpc;
39 : int i;
40 :
41 : /* alias for digit pointers */
42 :
43 : /* first input */
44 107488 : tmpa = a->dp;
45 :
46 : /* second input */
47 107488 : tmpb = b->dp;
48 :
49 : /* destination */
50 107488 : tmpc = c->dp;
51 :
52 : /* zero the carry */
53 107488 : u = 0;
54 7518223 : for (i = 0; i < min; i++) {
55 : /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
56 7410735 : *tmpc = *tmpa++ + *tmpb++ + u;
57 :
58 : /* U = carry bit of T[i] */
59 7410735 : u = *tmpc >> (mp_digit)MP_DIGIT_BIT;
60 :
61 : /* take away carry bit from T[i] */
62 7410735 : *tmpc++ &= MP_MASK;
63 : }
64 :
65 : /* now copy higher words if any, that is in A+B
66 : * if A or B has more digits add those in
67 : */
68 107488 : if (min != max) {
69 6044 : for (; i < max; i++) {
70 : /* T[i] = X[i] + U */
71 5937 : *tmpc = x->dp[i] + u;
72 :
73 : /* U = carry bit of T[i] */
74 5937 : u = *tmpc >> (mp_digit)MP_DIGIT_BIT;
75 :
76 : /* take away carry bit from T[i] */
77 5937 : *tmpc++ &= MP_MASK;
78 : }
79 : }
80 :
81 : /* add carry */
82 107488 : *tmpc++ = u;
83 :
84 : /* clear digits above oldused */
85 107488 : MP_ZERO_DIGITS(tmpc, olduse - c->used);
86 : }
87 :
88 107488 : mp_clamp(c);
89 107488 : return MP_OKAY;
90 : }
91 : #endif
|