bn_s_mp_add.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include <tommath.h>
  2. #ifdef BN_S_MP_ADD_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. /* low level addition, based on HAC pp.594, Algorithm 14.7 */
  18. int
  19. s_mp_add (mp_int * a, mp_int * b, mp_int * c)
  20. {
  21. mp_int *x;
  22. int olduse, res, min, max;
  23. /* find sizes, we let |a| <= |b| which means we have to sort
  24. * them. "x" will point to the input with the most digits
  25. */
  26. if (a->used > b->used) {
  27. min = b->used;
  28. max = a->used;
  29. x = a;
  30. } else {
  31. min = a->used;
  32. max = b->used;
  33. x = b;
  34. }
  35. /* init result */
  36. if (c->alloc < max + 1) {
  37. if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
  38. return res;
  39. }
  40. }
  41. /* get old used digit count and set new one */
  42. olduse = c->used;
  43. c->used = max + 1;
  44. {
  45. register mp_digit u, *tmpa, *tmpb, *tmpc;
  46. register int i;
  47. /* alias for digit pointers */
  48. /* first input */
  49. tmpa = a->dp;
  50. /* second input */
  51. tmpb = b->dp;
  52. /* destination */
  53. tmpc = c->dp;
  54. /* zero the carry */
  55. u = 0;
  56. for (i = 0; i < min; i++) {
  57. /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
  58. *tmpc = *tmpa++ + *tmpb++ + u;
  59. /* U = carry bit of T[i] */
  60. u = *tmpc >> ((mp_digit)DIGIT_BIT);
  61. /* take away carry bit from T[i] */
  62. *tmpc++ &= MP_MASK;
  63. }
  64. /* now copy higher words if any, that is in A+B
  65. * if A or B has more digits add those in
  66. */
  67. if (min != max) {
  68. for (; i < max; i++) {
  69. /* T[i] = X[i] + U */
  70. *tmpc = x->dp[i] + u;
  71. /* U = carry bit of T[i] */
  72. u = *tmpc >> ((mp_digit)DIGIT_BIT);
  73. /* take away carry bit from T[i] */
  74. *tmpc++ &= MP_MASK;
  75. }
  76. }
  77. /* add carry */
  78. *tmpc++ = u;
  79. /* clear digits above oldused */
  80. for (i = c->used; i < olduse; i++) {
  81. *tmpc++ = 0;
  82. }
  83. }
  84. mp_clamp (c);
  85. return MP_OKAY;
  86. }
  87. #endif
  88. /* $Source: /cvs/libtom/libtommath/bn_s_mp_add.c,v $ */
  89. /* $Revision: 1.3 $ */
  90. /* $Date: 2006/03/31 14:18:44 $ */