bn_mp_sub_d.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include <tommath.h>
  2. #ifdef BN_MP_SUB_D_C
  3. /* LibTomMath, multiple-precision integer library -- Tom St Denis
  4. *
  5. * LibTomMath is a library that provides multiple-precision
  6. * integer arithmetic as well as number theoretic functionality.
  7. *
  8. * The library was designed directly after the MPI library by
  9. * Michael Fromberger but has been written from scratch with
  10. * additional optimizations in place.
  11. *
  12. * The library is free for all purposes without any express
  13. * guarantee it works.
  14. *
  15. * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
  16. */
  17. /* single digit subtraction */
  18. int
  19. mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
  20. {
  21. mp_digit *tmpa, *tmpc, mu;
  22. int res, ix, oldused;
  23. /* grow c as required */
  24. if (c->alloc < a->used + 1) {
  25. if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
  26. return res;
  27. }
  28. }
  29. /* if a is negative just do an unsigned
  30. * addition [with fudged signs]
  31. */
  32. if (a->sign == MP_NEG) {
  33. a->sign = MP_ZPOS;
  34. res = mp_add_d(a, b, c);
  35. a->sign = c->sign = MP_NEG;
  36. /* clamp */
  37. mp_clamp(c);
  38. return res;
  39. }
  40. /* setup regs */
  41. oldused = c->used;
  42. tmpa = a->dp;
  43. tmpc = c->dp;
  44. /* if a <= b simply fix the single digit */
  45. if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
  46. if (a->used == 1) {
  47. *tmpc++ = b - *tmpa;
  48. } else {
  49. *tmpc++ = b;
  50. }
  51. ix = 1;
  52. /* negative/1digit */
  53. c->sign = MP_NEG;
  54. c->used = 1;
  55. } else {
  56. /* positive/size */
  57. c->sign = MP_ZPOS;
  58. c->used = a->used;
  59. /* subtract first digit */
  60. *tmpc = *tmpa++ - b;
  61. mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
  62. *tmpc++ &= MP_MASK;
  63. /* handle rest of the digits */
  64. for (ix = 1; ix < a->used; ix++) {
  65. *tmpc = *tmpa++ - mu;
  66. mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
  67. *tmpc++ &= MP_MASK;
  68. }
  69. }
  70. /* zero excess digits */
  71. while (ix++ < oldused) {
  72. *tmpc++ = 0;
  73. }
  74. mp_clamp(c);
  75. return MP_OKAY;
  76. }
  77. #endif
  78. /* $Source: /cvs/libtom/libtommath/bn_mp_sub_d.c,v $ */
  79. /* $Revision: 1.5 $ */
  80. /* $Date: 2006/03/31 14:18:44 $ */