bn_s_mp_sqr.c

Go to the documentation of this file.
00001 #include <tommath.h>
00002 #ifdef BN_S_MP_SQR_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 squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
00019 int s_mp_sqr (mp_int * a, mp_int * b)
00020 {
00021   mp_int  t;
00022   int     res, ix, iy, pa;
00023   mp_word r;
00024   mp_digit u, tmpx, *tmpt;
00025 
00026   pa = a->used;
00027   if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
00028     return res;
00029   }
00030 
00031   /* default used is maximum possible size */
00032   t.used = 2*pa + 1;
00033 
00034   for (ix = 0; ix < pa; ix++) {
00035     /* first calculate the digit at 2*ix */
00036     /* calculate double precision result */
00037     r = ((mp_word) t.dp[2*ix]) +
00038         ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
00039 
00040     /* store lower part in result */
00041     t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
00042 
00043     /* get the carry */
00044     u           = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
00045 
00046     /* left hand side of A[ix] * A[iy] */
00047     tmpx        = a->dp[ix];
00048 
00049     /* alias for where to store the results */
00050     tmpt        = t.dp + (2*ix + 1);
00051     
00052     for (iy = ix + 1; iy < pa; iy++) {
00053       /* first calculate the product */
00054       r       = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
00055 
00056       /* now calculate the double precision result, note we use
00057        * addition instead of *2 since it's easier to optimize
00058        */
00059       r       = ((mp_word) *tmpt) + r + r + ((mp_word) u);
00060 
00061       /* store lower part */
00062       *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
00063 
00064       /* get carry */
00065       u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
00066     }
00067     /* propagate upwards */
00068     while (u != ((mp_digit) 0)) {
00069       r       = ((mp_word) *tmpt) + ((mp_word) u);
00070       *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
00071       u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
00072     }
00073   }
00074 
00075   mp_clamp (&t);
00076   mp_exch (&t, b);
00077   mp_clear (&t);
00078   return MP_OKAY;
00079 }
00080 #endif
00081 
00082 /* $Source: /cvsroot/tcl/libtommath/bn_s_mp_sqr.c,v $ */
00083 /* $Revision: 1.1.1.4 $ */
00084 /* $Date: 2006/12/01 00:08:11 $ */



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