bn_s_mp_add.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include "tommath_private.h"
  2. #ifdef BN_S_MP_ADD_C
  3. /* LibTomMath, multiple-precision integer library -- Tom St Denis */
  4. /* SPDX-License-Identifier: Unlicense */
  5. /* low level addition, based on HAC pp.594, Algorithm 14.7 */
  6. mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
  7. {
  8. const mp_int *x;
  9. mp_err err;
  10. int olduse, min, max;
  11. /* find sizes, we let |a| <= |b| which means we have to sort
  12. * them. "x" will point to the input with the most digits
  13. */
  14. if (a->used > b->used) {
  15. min = b->used;
  16. max = a->used;
  17. x = a;
  18. } else {
  19. min = a->used;
  20. max = b->used;
  21. x = b;
  22. }
  23. /* init result */
  24. if (c->alloc < (max + 1)) {
  25. if ((err = mp_grow(c, max + 1)) != MP_OKAY) {
  26. return err;
  27. }
  28. }
  29. /* get old used digit count and set new one */
  30. olduse = c->used;
  31. c->used = max + 1;
  32. {
  33. mp_digit u, *tmpa, *tmpb, *tmpc;
  34. int i;
  35. /* alias for digit pointers */
  36. /* first input */
  37. tmpa = a->dp;
  38. /* second input */
  39. tmpb = b->dp;
  40. /* destination */
  41. tmpc = c->dp;
  42. /* zero the carry */
  43. u = 0;
  44. for (i = 0; i < min; i++) {
  45. /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
  46. *tmpc = *tmpa++ + *tmpb++ + u;
  47. /* U = carry bit of T[i] */
  48. u = *tmpc >> (mp_digit)MP_DIGIT_BIT;
  49. /* take away carry bit from T[i] */
  50. *tmpc++ &= MP_MASK;
  51. }
  52. /* now copy higher words if any, that is in A+B
  53. * if A or B has more digits add those in
  54. */
  55. if (min != max) {
  56. for (; i < max; i++) {
  57. /* T[i] = X[i] + U */
  58. *tmpc = x->dp[i] + u;
  59. /* U = carry bit of T[i] */
  60. u = *tmpc >> (mp_digit)MP_DIGIT_BIT;
  61. /* take away carry bit from T[i] */
  62. *tmpc++ &= MP_MASK;
  63. }
  64. }
  65. /* add carry */
  66. *tmpc++ = u;
  67. /* clear digits above oldused */
  68. MP_ZERO_DIGITS(tmpc, olduse - c->used);
  69. }
  70. mp_clamp(c);
  71. return MP_OKAY;
  72. }
  73. #endif