/src/dropbear/libtommath/bn_mp_sub.c
Line | Count | Source |
1 | | #include "tommath_private.h" |
2 | | #ifdef BN_MP_SUB_C |
3 | | /* LibTomMath, multiple-precision integer library -- Tom St Denis */ |
4 | | /* SPDX-License-Identifier: Unlicense */ |
5 | | |
6 | | /* high level subtraction (handles signs) */ |
7 | | mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) |
8 | 1.77M | { |
9 | 1.77M | mp_sign sa = a->sign, sb = b->sign; |
10 | 1.77M | mp_err err; |
11 | | |
12 | 1.77M | if (sa != sb) { |
13 | | /* subtract a negative from a positive, OR */ |
14 | | /* subtract a positive from a negative. */ |
15 | | /* In either case, ADD their magnitudes, */ |
16 | | /* and use the sign of the first number. */ |
17 | 137k | c->sign = sa; |
18 | 137k | err = s_mp_add(a, b, c); |
19 | 1.63M | } else { |
20 | | /* subtract a positive from a positive, OR */ |
21 | | /* subtract a negative from a negative. */ |
22 | | /* First, take the difference between their */ |
23 | | /* magnitudes, then... */ |
24 | 1.63M | if (mp_cmp_mag(a, b) != MP_LT) { |
25 | | /* Copy the sign from the first */ |
26 | 1.20M | c->sign = sa; |
27 | | /* The first has a larger or equal magnitude */ |
28 | 1.20M | err = s_mp_sub(a, b, c); |
29 | 1.20M | } else { |
30 | | /* The result has the *opposite* sign from */ |
31 | | /* the first number. */ |
32 | 431k | c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; |
33 | | /* The second has a larger magnitude */ |
34 | 431k | err = s_mp_sub(b, a, c); |
35 | 431k | } |
36 | 1.63M | } |
37 | 1.77M | return err; |
38 | 1.77M | } |
39 | | |
40 | | #endif |