bn_mp_karatsuba_sqr.c

Go to the documentation of this file.
00001 #include <tommath.h>
00002 #ifdef BN_MP_KARATSUBA_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 /* Karatsuba squaring, computes b = a*a using three 
00019  * half size squarings
00020  *
00021  * See comments of karatsuba_mul for details.  It 
00022  * is essentially the same algorithm but merely 
00023  * tuned to perform recursive squarings.
00024  */
00025 int mp_karatsuba_sqr (mp_int * a, mp_int * b)
00026 {
00027   mp_int  x0, x1, t1, t2, x0x0, x1x1;
00028   int     B, err;
00029 
00030   err = MP_MEM;
00031 
00032   /* min # of digits */
00033   B = a->used;
00034 
00035   /* now divide in two */
00036   B = B >> 1;
00037 
00038   /* init copy all the temps */
00039   if (mp_init_size (&x0, B) != MP_OKAY)
00040     goto ERR;
00041   if (mp_init_size (&x1, a->used - B) != MP_OKAY)
00042     goto X0;
00043 
00044   /* init temps */
00045   if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
00046     goto X1;
00047   if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
00048     goto T1;
00049   if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
00050     goto T2;
00051   if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
00052     goto X0X0;
00053 
00054   {
00055     register int x;
00056     register mp_digit *dst, *src;
00057 
00058     src = a->dp;
00059 
00060     /* now shift the digits */
00061     dst = x0.dp;
00062     for (x = 0; x < B; x++) {
00063       *dst++ = *src++;
00064     }
00065 
00066     dst = x1.dp;
00067     for (x = B; x < a->used; x++) {
00068       *dst++ = *src++;
00069     }
00070   }
00071 
00072   x0.used = B;
00073   x1.used = a->used - B;
00074 
00075   mp_clamp (&x0);
00076 
00077   /* now calc the products x0*x0 and x1*x1 */
00078   if (mp_sqr (&x0, &x0x0) != MP_OKAY)
00079     goto X1X1;           /* x0x0 = x0*x0 */
00080   if (mp_sqr (&x1, &x1x1) != MP_OKAY)
00081     goto X1X1;           /* x1x1 = x1*x1 */
00082 
00083   /* now calc (x1+x0)**2 */
00084   if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
00085     goto X1X1;           /* t1 = x1 - x0 */
00086   if (mp_sqr (&t1, &t1) != MP_OKAY)
00087     goto X1X1;           /* t1 = (x1 - x0) * (x1 - x0) */
00088 
00089   /* add x0y0 */
00090   if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
00091     goto X1X1;           /* t2 = x0x0 + x1x1 */
00092   if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
00093     goto X1X1;           /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
00094 
00095   /* shift by B */
00096   if (mp_lshd (&t1, B) != MP_OKAY)
00097     goto X1X1;           /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
00098   if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
00099     goto X1X1;           /* x1x1 = x1x1 << 2*B */
00100 
00101   if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
00102     goto X1X1;           /* t1 = x0x0 + t1 */
00103   if (mp_add (&t1, &x1x1, b) != MP_OKAY)
00104     goto X1X1;           /* t1 = x0x0 + t1 + x1x1 */
00105 
00106   err = MP_OKAY;
00107 
00108 X1X1:mp_clear (&x1x1);
00109 X0X0:mp_clear (&x0x0);
00110 T2:mp_clear (&t2);
00111 T1:mp_clear (&t1);
00112 X1:mp_clear (&x1);
00113 X0:mp_clear (&x0);
00114 ERR:
00115   return err;
00116 }
00117 #endif
00118 
00119 /* $Source: /cvsroot/tcl/libtommath/bn_mp_karatsuba_sqr.c,v $ */
00120 /* $Revision: 1.1.1.3 $ */
00121 /* $Date: 2006/12/01 00:08:11 $ */



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