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