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 340196 : mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) 8 : { 9 22715 : const mp_int *x; 10 22715 : mp_err err; 11 22715 : 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 340196 : if (a->used > b->used) { 17 4803 : min = b->used; 18 4803 : max = a->used; 19 4803 : x = a; 20 : } else { 21 335378 : min = a->used; 22 335378 : max = b->used; 23 335378 : x = b; 24 : } 25 : 26 : /* init result */ 27 340196 : if (c->alloc < (max + 1)) { 28 3819 : 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 340196 : olduse = c->used; 35 340196 : c->used = max + 1; 36 : 37 : { 38 22715 : mp_digit u, *tmpa, *tmpb, *tmpc; 39 22715 : int i; 40 : 41 : /* alias for digit pointers */ 42 : 43 : /* first input */ 44 340196 : tmpa = a->dp; 45 : 46 : /* second input */ 47 340196 : tmpb = b->dp; 48 : 49 : /* destination */ 50 340196 : tmpc = c->dp; 51 : 52 : /* zero the carry */ 53 340196 : u = 0; 54 22838700 : for (i = 0; i < min; i++) { 55 : /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */ 56 22498504 : *tmpc = *tmpa++ + *tmpb++ + u; 57 : 58 : /* U = carry bit of T[i] */ 59 22498504 : u = *tmpc >> (mp_digit)MP_DIGIT_BIT; 60 : 61 : /* take away carry bit from T[i] */ 62 22498504 : *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 340196 : if (min != max) { 69 534225 : for (; i < max; i++) { 70 : /* T[i] = X[i] + U */ 71 518064 : *tmpc = x->dp[i] + u; 72 : 73 : /* U = carry bit of T[i] */ 74 518064 : u = *tmpc >> (mp_digit)MP_DIGIT_BIT; 75 : 76 : /* take away carry bit from T[i] */ 77 518064 : *tmpc++ &= MP_MASK; 78 : } 79 : } 80 : 81 : /* add carry */ 82 340196 : *tmpc++ = u; 83 : 84 : /* clear digits above oldused */ 85 340196 : MP_ZERO_DIGITS(tmpc, olduse - c->used); 86 : } 87 : 88 340196 : mp_clamp(c); 89 340196 : return MP_OKAY; 90 : } 91 : #endif