106 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "tommath_private.h"
 | |
| #ifdef BN_S_MP_ADD_C
 | |
| /* LibTomMath, multiple-precision integer library -- Tom St Denis
 | |
|  *
 | |
|  * LibTomMath is a library that provides multiple-precision
 | |
|  * integer arithmetic as well as number theoretic functionality.
 | |
|  *
 | |
|  * The library was designed directly after the MPI library by
 | |
|  * Michael Fromberger but has been written from scratch with
 | |
|  * additional optimizations in place.
 | |
|  *
 | |
|  * SPDX-License-Identifier: Unlicense
 | |
|  */
 | |
| 
 | |
| /* low level addition, based on HAC pp.594, Algorithm 14.7 */
 | |
| int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
 | |
| {
 | |
|    const mp_int *x;
 | |
|    int     olduse, res, min, max;
 | |
| 
 | |
|    /* find sizes, we let |a| <= |b| which means we have to sort
 | |
|     * them.  "x" will point to the input with the most digits
 | |
|     */
 | |
|    if (a->used > b->used) {
 | |
|       min = b->used;
 | |
|       max = a->used;
 | |
|       x = a;
 | |
|    } else {
 | |
|       min = a->used;
 | |
|       max = b->used;
 | |
|       x = b;
 | |
|    }
 | |
| 
 | |
|    /* init result */
 | |
|    if (c->alloc < (max + 1)) {
 | |
|       if ((res = mp_grow(c, max + 1)) != MP_OKAY) {
 | |
|          return res;
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    /* get old used digit count and set new one */
 | |
|    olduse = c->used;
 | |
|    c->used = max + 1;
 | |
| 
 | |
|    {
 | |
|       mp_digit u, *tmpa, *tmpb, *tmpc;
 | |
|       int i;
 | |
| 
 | |
|       /* alias for digit pointers */
 | |
| 
 | |
|       /* first input */
 | |
|       tmpa = a->dp;
 | |
| 
 | |
|       /* second input */
 | |
|       tmpb = b->dp;
 | |
| 
 | |
|       /* destination */
 | |
|       tmpc = c->dp;
 | |
| 
 | |
|       /* zero the carry */
 | |
|       u = 0;
 | |
|       for (i = 0; i < min; i++) {
 | |
|          /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
 | |
|          *tmpc = *tmpa++ + *tmpb++ + u;
 | |
| 
 | |
|          /* U = carry bit of T[i] */
 | |
|          u = *tmpc >> (mp_digit)DIGIT_BIT;
 | |
| 
 | |
|          /* take away carry bit from T[i] */
 | |
|          *tmpc++ &= MP_MASK;
 | |
|       }
 | |
| 
 | |
|       /* now copy higher words if any, that is in A+B
 | |
|        * if A or B has more digits add those in
 | |
|        */
 | |
|       if (min != max) {
 | |
|          for (; i < max; i++) {
 | |
|             /* T[i] = X[i] + U */
 | |
|             *tmpc = x->dp[i] + u;
 | |
| 
 | |
|             /* U = carry bit of T[i] */
 | |
|             u = *tmpc >> (mp_digit)DIGIT_BIT;
 | |
| 
 | |
|             /* take away carry bit from T[i] */
 | |
|             *tmpc++ &= MP_MASK;
 | |
|          }
 | |
|       }
 | |
| 
 | |
|       /* add carry */
 | |
|       *tmpc++ = u;
 | |
| 
 | |
|       /* clear digits above oldused */
 | |
|       for (i = c->used; i < olduse; i++) {
 | |
|          *tmpc++ = 0;
 | |
|       }
 | |
|    }
 | |
| 
 | |
|    mp_clamp(c);
 | |
|    return MP_OKAY;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /* ref:         $Format:%D$ */
 | |
| /* git commit:  $Format:%H$ */
 | |
| /* commit time: $Format:%ai$ */
 |