/src/dropbear/libtommath/bn_s_mp_add.c
Line | Count | Source (jump to first uncovered line) |
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 | | mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) |
8 | 1.53M | { |
9 | 1.53M | const mp_int *x; |
10 | 1.53M | mp_err err; |
11 | 1.53M | 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 | 1.53M | if (a->used > b->used) { |
17 | 709 | min = b->used; |
18 | 709 | max = a->used; |
19 | 709 | x = a; |
20 | 1.53M | } else { |
21 | 1.53M | min = a->used; |
22 | 1.53M | max = b->used; |
23 | 1.53M | x = b; |
24 | 1.53M | } |
25 | | |
26 | | /* init result */ |
27 | 1.53M | if (c->alloc < (max + 1)) { |
28 | 0 | if ((err = mp_grow(c, max + 1)) != MP_OKAY) { |
29 | 0 | return err; |
30 | 0 | } |
31 | 0 | } |
32 | | |
33 | | /* get old used digit count and set new one */ |
34 | 1.53M | olduse = c->used; |
35 | 1.53M | c->used = max + 1; |
36 | | |
37 | 1.53M | { |
38 | 1.53M | mp_digit u, *tmpa, *tmpb, *tmpc; |
39 | 1.53M | int i; |
40 | | |
41 | | /* alias for digit pointers */ |
42 | | |
43 | | /* first input */ |
44 | 1.53M | tmpa = a->dp; |
45 | | |
46 | | /* second input */ |
47 | 1.53M | tmpb = b->dp; |
48 | | |
49 | | /* destination */ |
50 | 1.53M | tmpc = c->dp; |
51 | | |
52 | | /* zero the carry */ |
53 | 1.53M | u = 0; |
54 | 13.0M | for (i = 0; i < min; i++) { |
55 | | /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ |
56 | 11.5M | *tmpc = *tmpa++ + *tmpb++ + u; |
57 | | |
58 | | /* U = carry bit of T[i] */ |
59 | 11.5M | u = *tmpc >> (mp_digit)MP_DIGIT_BIT; |
60 | | |
61 | | /* take away carry bit from T[i] */ |
62 | 11.5M | *tmpc++ &= MP_MASK; |
63 | 11.5M | } |
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 | 1.53M | if (min != max) { |
69 | 10.9k | for (; i < max; i++) { |
70 | | /* T[i] = X[i] + U */ |
71 | 9.36k | *tmpc = x->dp[i] + u; |
72 | | |
73 | | /* U = carry bit of T[i] */ |
74 | 9.36k | u = *tmpc >> (mp_digit)MP_DIGIT_BIT; |
75 | | |
76 | | /* take away carry bit from T[i] */ |
77 | 9.36k | *tmpc++ &= MP_MASK; |
78 | 9.36k | } |
79 | 1.61k | } |
80 | | |
81 | | /* add carry */ |
82 | 1.53M | *tmpc++ = u; |
83 | | |
84 | | /* clear digits above oldused */ |
85 | 1.53M | MP_ZERO_DIGITS(tmpc, olduse - c->used); |
86 | 1.53M | } |
87 | | |
88 | 1.53M | mp_clamp(c); |
89 | 1.53M | return MP_OKAY; |
90 | 1.53M | } |
91 | | #endif |