Edit

kc3-lang/libtommath/bn_s_mp_add.c

Branch :

  • Show log

    Commit

  • Author : Tom St Denis
    Date : 2007-04-18 09:58:18
    Hash : 333aebc8
    Message : added libtommath-0.41

  • bn_s_mp_add.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$ */
    /* $Revision$ */
    /* $Date$ */