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