/src/dropbear/libtommath/bn_mp_sub_d.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "tommath_private.h" |
2 | | #ifdef BN_MP_SUB_D_C |
3 | | /* LibTomMath, multiple-precision integer library -- Tom St Denis */ |
4 | | /* SPDX-License-Identifier: Unlicense */ |
5 | | |
6 | | /* single digit subtraction */ |
7 | | mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) |
8 | 22.8k | { |
9 | 22.8k | mp_digit *tmpa, *tmpc; |
10 | 22.8k | mp_err err; |
11 | 22.8k | int ix, oldused; |
12 | | |
13 | | /* grow c as required */ |
14 | 22.8k | if (c->alloc < (a->used + 1)) { |
15 | 22.8k | if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { |
16 | 0 | return err; |
17 | 0 | } |
18 | 22.8k | } |
19 | | |
20 | | /* if a is negative just do an unsigned |
21 | | * addition [with fudged signs] |
22 | | */ |
23 | 22.8k | if (a->sign == MP_NEG) { |
24 | 0 | mp_int a_ = *a; |
25 | 0 | a_.sign = MP_ZPOS; |
26 | 0 | err = mp_add_d(&a_, b, c); |
27 | 0 | c->sign = MP_NEG; |
28 | | |
29 | | /* clamp */ |
30 | 0 | mp_clamp(c); |
31 | |
|
32 | 0 | return err; |
33 | 0 | } |
34 | | |
35 | | /* setup regs */ |
36 | 22.8k | oldused = c->used; |
37 | 22.8k | tmpa = a->dp; |
38 | 22.8k | tmpc = c->dp; |
39 | | |
40 | | /* if a <= b simply fix the single digit */ |
41 | 22.8k | if (((a->used == 1) && (a->dp[0] <= b)) || (a->used == 0)) { |
42 | 0 | if (a->used == 1) { |
43 | 0 | *tmpc++ = b - *tmpa; |
44 | 0 | } else { |
45 | 0 | *tmpc++ = b; |
46 | 0 | } |
47 | 0 | ix = 1; |
48 | | |
49 | | /* negative/1digit */ |
50 | 0 | c->sign = MP_NEG; |
51 | 0 | c->used = 1; |
52 | 22.8k | } else { |
53 | 22.8k | mp_digit mu = b; |
54 | | |
55 | | /* positive/size */ |
56 | 22.8k | c->sign = MP_ZPOS; |
57 | 22.8k | c->used = a->used; |
58 | | |
59 | | /* subtract digits, mu is carry */ |
60 | 759k | for (ix = 0; ix < a->used; ix++) { |
61 | 736k | *tmpc = *tmpa++ - mu; |
62 | 736k | mu = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); |
63 | 736k | *tmpc++ &= MP_MASK; |
64 | 736k | } |
65 | 22.8k | } |
66 | | |
67 | | /* zero excess digits */ |
68 | 22.8k | MP_ZERO_DIGITS(tmpc, oldused - ix); |
69 | | |
70 | 22.8k | mp_clamp(c); |
71 | 22.8k | return MP_OKAY; |
72 | 22.8k | } |
73 | | |
74 | | #endif |