110 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <tommath.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.
 | 
						|
 *
 | 
						|
 * The library is free for all purposes without any express
 | 
						|
 * guarantee it works.
 | 
						|
 *
 | 
						|
 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
 | 
						|
 */
 | 
						|
 | 
						|
/* low level addition, based on HAC pp.594, Algorithm 14.7 */
 | 
						|
int
 | 
						|
s_mp_add (mp_int * a, mp_int * b, mp_int * c)
 | 
						|
{
 | 
						|
  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;
 | 
						|
 | 
						|
  {
 | 
						|
    register mp_digit u, *tmpa, *tmpb, *tmpc;
 | 
						|
    register 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
 | 
						|
 | 
						|
/* $Source: /cvs/libtom/libtommath/bn_s_mp_add.c,v $ */
 | 
						|
/* $Revision: 1.4 $ */
 | 
						|
/* $Date: 2006/12/28 01:25:13 $ */
 |