/src/dropbear/libtommath/bn_mp_add_d.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "tommath_private.h" |
2 | | #ifdef BN_MP_ADD_D_C |
3 | | /* LibTomMath, multiple-precision integer library -- Tom St Denis */ |
4 | | /* SPDX-License-Identifier: Unlicense */ |
5 | | |
6 | | /* single digit addition */ |
7 | | mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) |
8 | 256 | { |
9 | 256 | mp_err err; |
10 | 256 | int ix, oldused; |
11 | 256 | mp_digit *tmpa, *tmpc; |
12 | | |
13 | | /* grow c as required */ |
14 | 256 | if (c->alloc < (a->used + 1)) { |
15 | 0 | if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { |
16 | 0 | return err; |
17 | 0 | } |
18 | 0 | } |
19 | | |
20 | | /* if a is negative and |a| >= b, call c = |a| - b */ |
21 | 256 | if ((a->sign == MP_NEG) && ((a->used > 1) || (a->dp[0] >= b))) { |
22 | 0 | mp_int a_ = *a; |
23 | | /* temporarily fix sign of a */ |
24 | 0 | a_.sign = MP_ZPOS; |
25 | | |
26 | | /* c = |a| - b */ |
27 | 0 | err = mp_sub_d(&a_, b, c); |
28 | | |
29 | | /* fix sign */ |
30 | 0 | c->sign = MP_NEG; |
31 | | |
32 | | /* clamp */ |
33 | 0 | mp_clamp(c); |
34 | |
|
35 | 0 | return err; |
36 | 0 | } |
37 | | |
38 | | /* old number of used digits in c */ |
39 | 256 | oldused = c->used; |
40 | | |
41 | | /* source alias */ |
42 | 256 | tmpa = a->dp; |
43 | | |
44 | | /* destination alias */ |
45 | 256 | tmpc = c->dp; |
46 | | |
47 | | /* if a is positive */ |
48 | 256 | if (a->sign == MP_ZPOS) { |
49 | | /* add digits, mu is carry */ |
50 | 256 | mp_digit mu = b; |
51 | 932 | for (ix = 0; ix < a->used; ix++) { |
52 | 676 | *tmpc = *tmpa++ + mu; |
53 | 676 | mu = *tmpc >> MP_DIGIT_BIT; |
54 | 676 | *tmpc++ &= MP_MASK; |
55 | 676 | } |
56 | | /* set final carry */ |
57 | 256 | ix++; |
58 | 256 | *tmpc++ = mu; |
59 | | |
60 | | /* setup size */ |
61 | 256 | c->used = a->used + 1; |
62 | 256 | } else { |
63 | | /* a was negative and |a| < b */ |
64 | 0 | c->used = 1; |
65 | | |
66 | | /* the result is a single digit */ |
67 | 0 | if (a->used == 1) { |
68 | 0 | *tmpc++ = b - a->dp[0]; |
69 | 0 | } else { |
70 | 0 | *tmpc++ = b; |
71 | 0 | } |
72 | | |
73 | | /* setup count so the clearing of oldused |
74 | | * can fall through correctly |
75 | | */ |
76 | 0 | ix = 1; |
77 | 0 | } |
78 | | |
79 | | /* sign always positive */ |
80 | 256 | c->sign = MP_ZPOS; |
81 | | |
82 | | /* now zero to oldused */ |
83 | 256 | MP_ZERO_DIGITS(tmpc, oldused - ix); |
84 | 256 | mp_clamp(c); |
85 | | |
86 | 256 | return MP_OKAY; |
87 | 256 | } |
88 | | |
89 | | #endif |