Line data Source code
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 1107064 : mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) 8 : { 9 1107064 : mp_sign sa = a->sign, sb = b->sign; 10 73226 : mp_err err; 11 : 12 1107064 : 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 335418 : c->sign = sa; 18 335418 : err = s_mp_add(a, b, c); 19 : } 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 771646 : if (mp_cmp_mag(a, b) != MP_LT) { 25 : /* Copy the sign from the first */ 26 539548 : c->sign = sa; 27 : /* The first has a larger or equal magnitude */ 28 539548 : err = s_mp_sub(a, b, c); 29 : } else { 30 : /* The result has the *opposite* sign from */ 31 : /* the first number. */ 32 232098 : c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; 33 : /* The second has a larger magnitude */ 34 232098 : err = s_mp_sub(b, a, c); 35 : } 36 : } 37 1107064 : return err; 38 : } 39 : 40 : #endif