/* TomsFastMath, a fast ISO C bignum library. * * This project is meant to fill in where LibTomMath * falls short. That is speed ;-) * * This project is public domain and free for all purposes. * * Tom St Denis, tomstdenis@gmail.com */ #define TFM_DEFINES #include "fp_sqr_comba.c" /* generic comba squarer */ void fp_sqr_comba(fp_int *A, fp_int *B) { int pa, ix, iz; fp_digit c0, c1, c2; fp_int tmp, *dst; #ifdef TFM_ISO fp_word tt; #endif /* get size of output and trim */ pa = A->used + A->used; if (pa >= FP_SIZE) { pa = FP_SIZE-1; } /* number of output digits to produce */ COMBA_START; CLEAR_CARRY; if (A == B) { fp_zero(&tmp); dst = &tmp; } else { fp_zero(B); dst = B; } for (ix = 0; ix < pa; ix++) { int tx, ty, iy; fp_digit *tmpy, *tmpx; /* get offsets into the two bignums */ ty = MIN(A->used-1, ix); tx = ix - ty; /* setup temp aliases */ tmpx = A->dp + tx; tmpy = A->dp + ty; /* this is the number of times the loop will iterrate, while (tx++ < a->used && ty-- >= 0) { ... } */ iy = MIN(A->used-tx, ty+1); /* now for squaring tx can never equal ty * we halve the distance since they approach * at a rate of 2x and we have to round because * odd cases need to be executed */ iy = MIN(iy, (ty-tx+1)>>1); /* forward carries */ CARRY_FORWARD; /* execute loop */ for (iz = 0; iz < iy; iz++) { fp_digit _tmpx = *tmpx++; fp_digit _tmpy = *tmpy--; SQRADD2(_tmpx, _tmpy); } /* even columns have the square term in them */ if ((ix&1) == 0) { fp_digit _a_dp = A->dp[ix>>1]; SQRADD(_a_dp, A->dp[ix>>1]); } /* store it */ COMBA_STORE(dst->dp[ix]); } COMBA_FINI; /* setup dest */ dst->used = pa; fp_clamp (dst); if (dst != B) { fp_copy(dst, B); } } /* $Source$ */ /* $Revision$ */ /* $Date$ */