bn_s_mp_sub.c

Go to the documentation of this file.
00001 #include <tommath.h>
00002 #ifdef BN_S_MP_SUB_C
00003 /* LibTomMath, multiple-precision integer library -- Tom St Denis
00004  *
00005  * LibTomMath is a library that provides multiple-precision
00006  * integer arithmetic as well as number theoretic functionality.
00007  *
00008  * The library was designed directly after the MPI library by
00009  * Michael Fromberger but has been written from scratch with
00010  * additional optimizations in place.
00011  *
00012  * The library is free for all purposes without any express
00013  * guarantee it works.
00014  *
00015  * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
00016  */
00017 
00018 /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
00019 int
00020 s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
00021 {
00022   int     olduse, res, min, max;
00023 
00024   /* find sizes */
00025   min = b->used;
00026   max = a->used;
00027 
00028   /* init result */
00029   if (c->alloc < max) {
00030     if ((res = mp_grow (c, max)) != MP_OKAY) {
00031       return res;
00032     }
00033   }
00034   olduse = c->used;
00035   c->used = max;
00036 
00037   {
00038     register mp_digit u, *tmpa, *tmpb, *tmpc;
00039     register int i;
00040 
00041     /* alias for digit pointers */
00042     tmpa = a->dp;
00043     tmpb = b->dp;
00044     tmpc = c->dp;
00045 
00046     /* set carry to zero */
00047     u = 0;
00048     for (i = 0; i < min; i++) {
00049       /* T[i] = A[i] - B[i] - U */
00050       *tmpc = *tmpa++ - *tmpb++ - u;
00051 
00052       /* U = carry bit of T[i]
00053        * Note this saves performing an AND operation since
00054        * if a carry does occur it will propagate all the way to the
00055        * MSB.  As a result a single shift is enough to get the carry
00056        */
00057       u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
00058 
00059       /* Clear carry from T[i] */
00060       *tmpc++ &= MP_MASK;
00061     }
00062 
00063     /* now copy higher words if any, e.g. if A has more digits than B  */
00064     for (; i < max; i++) {
00065       /* T[i] = A[i] - U */
00066       *tmpc = *tmpa++ - u;
00067 
00068       /* U = carry bit of T[i] */
00069       u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
00070 
00071       /* Clear carry from T[i] */
00072       *tmpc++ &= MP_MASK;
00073     }
00074 
00075     /* clear digits above used (since we may not have grown result above) */
00076     for (i = c->used; i < olduse; i++) {
00077       *tmpc++ = 0;
00078     }
00079   }
00080 
00081   mp_clamp (c);
00082   return MP_OKAY;
00083 }
00084 
00085 #endif
00086 
00087 /* $Source: /cvsroot/tcl/libtommath/bn_s_mp_sub.c,v $ */
00088 /* $Revision: 1.1.1.3 $ */
00089 /* $Date: 2006/12/01 00:08:11 $ */



Generated on Wed Mar 12 12:18:25 2008 by  doxygen 1.5.1