bn_mp_sub.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  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. /* high level subtraction (handles signs) */
  6. mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
  7. {
  8. mp_sign sa = a->sign, sb = b->sign;
  9. mp_err err;
  10. if (sa != sb) {
  11. /* subtract a negative from a positive, OR */
  12. /* subtract a positive from a negative. */
  13. /* In either case, ADD their magnitudes, */
  14. /* and use the sign of the first number. */
  15. c->sign = sa;
  16. err = s_mp_add(a, b, c);
  17. } else {
  18. /* subtract a positive from a positive, OR */
  19. /* subtract a negative from a negative. */
  20. /* First, take the difference between their */
  21. /* magnitudes, then... */
  22. if (mp_cmp_mag(a, b) != MP_LT) {
  23. /* Copy the sign from the first */
  24. c->sign = sa;
  25. /* The first has a larger or equal magnitude */
  26. err = s_mp_sub(a, b, c);
  27. } else {
  28. /* The result has the *opposite* sign from */
  29. /* the first number. */
  30. c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
  31. /* The second has a larger magnitude */
  32. err = s_mp_sub(b, a, c);
  33. }
  34. }
  35. return err;
  36. }
  37. #endif