bn_mp_add_d.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <tommath.h>
  2. #ifdef BN_MP_ADD_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 addition */
  18. int
  19. mp_add_d (mp_int * a, mp_digit b, mp_int * c)
  20. {
  21. int res, ix, oldused;
  22. mp_digit *tmpa, *tmpc, mu;
  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 and |a| >= b, call c = |a| - b */
  30. if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
  31. /* temporarily fix sign of a */
  32. a->sign = MP_ZPOS;
  33. /* c = |a| - b */
  34. res = mp_sub_d(a, b, c);
  35. /* fix sign */
  36. a->sign = c->sign = MP_NEG;
  37. /* clamp */
  38. mp_clamp(c);
  39. return res;
  40. }
  41. /* old number of used digits in c */
  42. oldused = c->used;
  43. /* sign always positive */
  44. c->sign = MP_ZPOS;
  45. /* source alias */
  46. tmpa = a->dp;
  47. /* destination alias */
  48. tmpc = c->dp;
  49. /* if a is positive */
  50. if (a->sign == MP_ZPOS) {
  51. /* add digit, after this we're propagating
  52. * the carry.
  53. */
  54. *tmpc = *tmpa++ + b;
  55. mu = *tmpc >> DIGIT_BIT;
  56. *tmpc++ &= MP_MASK;
  57. /* now handle rest of the digits */
  58. for (ix = 1; ix < a->used; ix++) {
  59. *tmpc = *tmpa++ + mu;
  60. mu = *tmpc >> DIGIT_BIT;
  61. *tmpc++ &= MP_MASK;
  62. }
  63. /* set final carry */
  64. ix++;
  65. *tmpc++ = mu;
  66. /* setup size */
  67. c->used = a->used + 1;
  68. } else {
  69. /* a was negative and |a| < b */
  70. c->used = 1;
  71. /* the result is a single digit */
  72. if (a->used == 1) {
  73. *tmpc++ = b - a->dp[0];
  74. } else {
  75. *tmpc++ = b;
  76. }
  77. /* setup count so the clearing of oldused
  78. * can fall through correctly
  79. */
  80. ix = 1;
  81. }
  82. /* now zero to oldused */
  83. while (ix++ < oldused) {
  84. *tmpc++ = 0;
  85. }
  86. mp_clamp(c);
  87. return MP_OKAY;
  88. }
  89. #endif
  90. /* $Source: /cvs/libtom/libtommath/bn_mp_add_d.c,v $ */
  91. /* $Revision: 1.4 $ */
  92. /* $Date: 2006/03/31 14:18:44 $ */