bn_fast_s_mp_mul_digs.cGo to the documentation of this file.00001 #include <tommath.h> 00002 #ifdef BN_FAST_S_MP_MUL_DIGS_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 /* Fast (comba) multiplier 00019 * 00020 * This is the fast column-array [comba] multiplier. It is 00021 * designed to compute the columns of the product first 00022 * then handle the carries afterwards. This has the effect 00023 * of making the nested loops that compute the columns very 00024 * simple and schedulable on super-scalar processors. 00025 * 00026 * This has been modified to produce a variable number of 00027 * digits of output so if say only a half-product is required 00028 * you don't have to compute the upper half (a feature 00029 * required for fast Barrett reduction). 00030 * 00031 * Based on Algorithm 14.12 on pp.595 of HAC. 00032 * 00033 */ 00034 int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) 00035 { 00036 int olduse, res, pa, ix, iz; 00037 mp_digit W[MP_WARRAY]; 00038 register mp_word _W; 00039 00040 /* grow the destination as required */ 00041 if (c->alloc < digs) { 00042 if ((res = mp_grow (c, digs)) != MP_OKAY) { 00043 return res; 00044 } 00045 } 00046 00047 /* number of output digits to produce */ 00048 pa = MIN(digs, a->used + b->used); 00049 00050 /* clear the carry */ 00051 _W = 0; 00052 for (ix = 0; ix < pa; ix++) { 00053 int tx, ty; 00054 int iy; 00055 mp_digit *tmpx, *tmpy; 00056 00057 /* get offsets into the two bignums */ 00058 ty = MIN(b->used-1, ix); 00059 tx = ix - ty; 00060 00061 /* setup temp aliases */ 00062 tmpx = a->dp + tx; 00063 tmpy = b->dp + ty; 00064 00065 /* this is the number of times the loop will iterrate, essentially 00066 while (tx++ < a->used && ty-- >= 0) { ... } 00067 */ 00068 iy = MIN(a->used-tx, ty+1); 00069 00070 /* execute loop */ 00071 for (iz = 0; iz < iy; ++iz) { 00072 _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--); 00073 00074 } 00075 00076 /* store term */ 00077 W[ix] = ((mp_digit)_W) & MP_MASK; 00078 00079 /* make next carry */ 00080 _W = _W >> ((mp_word)DIGIT_BIT); 00081 } 00082 00083 /* setup dest */ 00084 olduse = c->used; 00085 c->used = pa; 00086 00087 { 00088 register mp_digit *tmpc; 00089 tmpc = c->dp; 00090 for (ix = 0; ix < pa+1; ix++) { 00091 /* now extract the previous digit [below the carry] */ 00092 *tmpc++ = W[ix]; 00093 } 00094 00095 /* clear unused digits [that existed in the old copy of c] */ 00096 for (; ix < olduse; ix++) { 00097 *tmpc++ = 0; 00098 } 00099 } 00100 mp_clamp (c); 00101 return MP_OKAY; 00102 } 00103 #endif 00104 00105 /* $Source: /cvsroot/tcl/libtommath/bn_fast_s_mp_mul_digs.c,v $ */ 00106 /* $Revision: 1.1.1.4 $ */ 00107 /* $Date: 2006/12/01 00:08:11 $ */
Generated on Wed Mar 12 12:18:24 2008 by 1.5.1 |