Commit 310d99dc authored by Dominique Dumont's avatar Dominique Dumont

Imported Upstream version 0.39

parents
/.log/1.1.1.1/Fri Mar 18 23:19:16 2005//
/LICENSE/1.1.1.1/Fri Mar 18 23:19:16 2005//
/bn.tex/1.5/Thu Jan 26 19:20:47 2006//
/booker.pl/1.3/Sun Oct 2 13:15:04 2005//
/callgraph.txt/1.1.1.1/Fri Mar 18 23:19:16 2005//
/dep.pl/1.1.1.1/Fri Mar 18 23:19:16 2005//
/gen.pl/1.1.1.1/Fri Mar 18 23:19:16 2005//
/makefile/1.12/Thu Jan 26 19:20:47 2006//
/makefile.bcc/1.2/Sun Oct 2 13:04:27 2005//
/makefile.icc/1.2/Fri Apr 8 21:52:47 2005//
/makefile.msvc/1.2/Sat Jul 30 04:58:09 2005//
/makefile.shared/1.15/Sat Mar 4 21:33:57 2006//
/mess.sh/1.1/Thu Jul 28 02:51:03 2005//
/poster.out/1.1.1.1/Fri Mar 18 23:19:16 2005//
/poster.tex/1.1.1.1/Fri Mar 18 23:19:16 2005//
/pretty.build/1.1.1.1/Fri Mar 18 23:19:16 2005//
/tommath.out/1.1.1.1/Fri Mar 18 23:19:16 2005//
D/demo////
D/etc////
D/logs////
D/mtest////
D/pics////
D/pre_gen////
D/tombc////
/bn_error.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_fast_mp_invmod.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_fast_mp_montgomery_reduce.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_fast_s_mp_mul_digs.c/1.7/Fri Mar 31 14:18:44 2006//
/bn_fast_s_mp_mul_high_digs.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_fast_s_mp_sqr.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_2expt.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_abs.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_add.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_add_d.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_addmod.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_and.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_clamp.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_clear.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_clear_multi.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_cmp.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_cmp_d.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_cmp_mag.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_cnt_lsb.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_copy.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_count_bits.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_div.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_div_2.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_div_2d.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_div_3.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_div_d.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_dr_is_modulus.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_dr_reduce.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_dr_setup.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_exch.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_expt_d.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_exptmod.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_exptmod_fast.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_exteuclid.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_fread.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_fwrite.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_gcd.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_get_int.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_grow.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_init.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_init_copy.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_init_multi.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_init_set.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_init_set_int.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_init_size.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_invmod.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_invmod_slow.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_is_square.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_jacobi.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_karatsuba_mul.c/1.5/Fri Mar 31 14:18:44 2006//
/bn_mp_karatsuba_sqr.c/1.5/Fri Mar 31 14:18:44 2006//
/bn_mp_lcm.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_lshd.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_mod.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_mod_2d.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_mod_d.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_montgomery_calc_normalization.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_montgomery_reduce.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_montgomery_setup.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_mul.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_mul_2.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_mul_2d.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_mul_d.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_mulmod.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_n_root.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_neg.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_or.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_prime_fermat.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_prime_is_divisible.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_prime_is_prime.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_prime_miller_rabin.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_prime_next_prime.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_prime_rabin_miller_trials.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_prime_random_ex.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_radix_size.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_radix_smap.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_rand.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_read_radix.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_read_signed_bin.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_read_unsigned_bin.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_reduce.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_reduce_2k.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_reduce_2k_l.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_reduce_2k_setup.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_reduce_2k_setup_l.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_reduce_is_2k.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_reduce_is_2k_l.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_reduce_setup.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_rshd.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_set.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_set_int.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_shrink.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_signed_bin_size.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_sqr.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_sqrmod.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_sqrt.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_sub.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_sub_d.c/1.5/Fri Mar 31 14:18:44 2006//
/bn_mp_submod.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_to_signed_bin.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_to_signed_bin_n.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_to_unsigned_bin.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_to_unsigned_bin_n.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_toom_mul.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_toom_sqr.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_toradix.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_toradix_n.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_mp_unsigned_bin_size.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_xor.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_mp_zero.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_prime_tab.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_reverse.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_s_mp_add.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_s_mp_exptmod.c/1.4/Fri Mar 31 14:18:44 2006//
/bn_s_mp_mul_digs.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_s_mp_mul_high_digs.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_s_mp_sqr.c/1.3/Fri Mar 31 14:18:44 2006//
/bn_s_mp_sub.c/1.3/Fri Mar 31 14:18:44 2006//
/bncore.c/1.4/Fri Mar 31 14:18:44 2006//
/changes.txt/1.27/Fri Mar 31 14:18:37 2006//
/tommath.h/1.8/Fri Mar 31 14:18:44 2006//
/tommath.src/1.13/Fri Mar 31 14:20:21 2006//
/makefile.cygwin_dll/1.2/Fri Mar 31 14:18:03 2006//
/tommath_class.h/1.3/Fri Mar 31 14:18:03 2006//
/tommath_superclass.h/1.3/Fri Mar 31 14:18:03 2006//
libtom/libtommath
LibTomMath is hereby released into the Public Domain.
-- Tom St Denis
This is makeindex, version 2.14 [02-Oct-2002] (kpathsea + Thai support).
Scanning input file bn.idx....done (79 entries accepted, 0 rejected).
Sorting entries....done (511 comparisons).
Generating output file bn.ind....done (82 lines written, 0 warnings).
Output written in bn.ind.
Transcript written in bn.ilg.
\begin{theindex}
\item mp\_add, \hyperpage{29}
\item mp\_add\_d, \hyperpage{52}
\item mp\_and, \hyperpage{29}
\item mp\_clear, \hyperpage{11}
\item mp\_clear\_multi, \hyperpage{12}
\item mp\_cmp, \hyperpage{24}
\item mp\_cmp\_d, \hyperpage{25}
\item mp\_cmp\_mag, \hyperpage{23}
\item mp\_div, \hyperpage{30}
\item mp\_div\_2, \hyperpage{26}
\item mp\_div\_2d, \hyperpage{28}
\item mp\_div\_d, \hyperpage{52}
\item mp\_dr\_reduce, \hyperpage{40}
\item mp\_dr\_setup, \hyperpage{40}
\item MP\_EQ, \hyperpage{22}
\item mp\_error\_to\_string, \hyperpage{10}
\item mp\_expt\_d, \hyperpage{43}
\item mp\_exptmod, \hyperpage{43}
\item mp\_exteuclid, \hyperpage{51}
\item mp\_gcd, \hyperpage{51}
\item mp\_get\_int, \hyperpage{20}
\item mp\_grow, \hyperpage{16}
\item MP\_GT, \hyperpage{22}
\item mp\_init, \hyperpage{11}
\item mp\_init\_copy, \hyperpage{13}
\item mp\_init\_multi, \hyperpage{12}
\item mp\_init\_set, \hyperpage{21}
\item mp\_init\_set\_int, \hyperpage{21}
\item mp\_init\_size, \hyperpage{14}
\item mp\_int, \hyperpage{10}
\item mp\_invmod, \hyperpage{52}
\item mp\_jacobi, \hyperpage{52}
\item mp\_lcm, \hyperpage{51}
\item mp\_lshd, \hyperpage{28}
\item MP\_LT, \hyperpage{22}
\item MP\_MEM, \hyperpage{9}
\item mp\_mod, \hyperpage{35}
\item mp\_mod\_d, \hyperpage{52}
\item mp\_montgomery\_calc\_normalization, \hyperpage{38}
\item mp\_montgomery\_reduce, \hyperpage{37}
\item mp\_montgomery\_setup, \hyperpage{37}
\item mp\_mul, \hyperpage{31}
\item mp\_mul\_2, \hyperpage{26}
\item mp\_mul\_2d, \hyperpage{28}
\item mp\_mul\_d, \hyperpage{52}
\item mp\_n\_root, \hyperpage{44}
\item mp\_neg, \hyperpage{29}
\item MP\_NO, \hyperpage{9}
\item MP\_OKAY, \hyperpage{9}
\item mp\_or, \hyperpage{29}
\item mp\_prime\_fermat, \hyperpage{45}
\item mp\_prime\_is\_divisible, \hyperpage{45}
\item mp\_prime\_is\_prime, \hyperpage{46}
\item mp\_prime\_miller\_rabin, \hyperpage{45}
\item mp\_prime\_next\_prime, \hyperpage{46}
\item mp\_prime\_rabin\_miller\_trials, \hyperpage{46}
\item mp\_prime\_random, \hyperpage{47}
\item mp\_prime\_random\_ex, \hyperpage{47}
\item mp\_radix\_size, \hyperpage{49}
\item mp\_read\_radix, \hyperpage{49}
\item mp\_read\_unsigned\_bin, \hyperpage{50}
\item mp\_reduce, \hyperpage{36}
\item mp\_reduce\_2k, \hyperpage{41}
\item mp\_reduce\_2k\_setup, \hyperpage{41}
\item mp\_reduce\_setup, \hyperpage{36}
\item mp\_rshd, \hyperpage{28}
\item mp\_set, \hyperpage{19}
\item mp\_set\_int, \hyperpage{20}
\item mp\_shrink, \hyperpage{15}
\item mp\_sqr, \hyperpage{33}
\item mp\_sub, \hyperpage{29}
\item mp\_sub\_d, \hyperpage{52}
\item mp\_to\_unsigned\_bin, \hyperpage{50}
\item mp\_toradix, \hyperpage{49}
\item mp\_unsigned\_bin\_size, \hyperpage{50}
\item MP\_VAL, \hyperpage{9}
\item mp\_xor, \hyperpage{29}
\item MP\_YES, \hyperpage{9}
\end{theindex}
File added
This diff is collapsed.
#include <tommath.h>
#ifdef BN_ERROR_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
*/
static const struct {
int code;
char *msg;
} msgs[] = {
{ MP_OKAY, "Successful" },
{ MP_MEM, "Out of heap" },
{ MP_VAL, "Value out of range" }
};
/* return a char * string for a given code */
char *mp_error_to_string(int code)
{
int x;
/* scan the lookup table for the given message */
for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
if (msgs[x].code == code) {
return msgs[x].msg;
}
}
/* generic reply for invalid code */
return "Invalid error code";
}
#endif
/* $Source: /cvs/libtom/libtommath/bn_error.c,v $ */
/* $Revision: 1.3 $ */
/* $Date: 2006/03/31 14:18:44 $ */
#include <tommath.h>
#ifdef BN_FAST_MP_INVMOD_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
*/
/* computes the modular inverse via binary extended euclidean algorithm,
* that is c = 1/a mod b
*
* Based on slow invmod except this is optimized for the case where b is
* odd as per HAC Note 14.64 on pp. 610
*/
int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
{
mp_int x, y, u, v, B, D;
int res, neg;
/* 2. [modified] b must be odd */
if (mp_iseven (b) == 1) {
return MP_VAL;
}
/* init all our temps */
if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
return res;
}
/* x == modulus, y == value to invert */
if ((res = mp_copy (b, &x)) != MP_OKAY) {
goto LBL_ERR;
}
/* we need y = |a| */
if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
goto LBL_ERR;
}
/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
if ((res = mp_copy (&x, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_copy (&y, &v)) != MP_OKAY) {
goto LBL_ERR;
}
mp_set (&D, 1);
top:
/* 4. while u is even do */
while (mp_iseven (&u) == 1) {
/* 4.1 u = u/2 */
if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
goto LBL_ERR;
}
/* 4.2 if B is odd then */
if (mp_isodd (&B) == 1) {
if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* B = B/2 */
if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* 5. while v is even do */
while (mp_iseven (&v) == 1) {
/* 5.1 v = v/2 */
if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
goto LBL_ERR;
}
/* 5.2 if D is odd then */
if (mp_isodd (&D) == 1) {
/* D = (D-x)/2 */
if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* D = D/2 */
if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* 6. if u >= v then */
if (mp_cmp (&u, &v) != MP_LT) {
/* u = u - v, B = B - D */
if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
goto LBL_ERR;
}
} else {
/* v - v - u, D = D - B */
if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* if not zero goto step 4 */
if (mp_iszero (&u) == 0) {
goto top;
}
/* now a = C, b = D, gcd == g*v */
/* if v != 1 then there is no inverse */
if (mp_cmp_d (&v, 1) != MP_EQ) {
res = MP_VAL;
goto LBL_ERR;
}
/* b is now the inverse */
neg = a->sign;
while (D.sign == MP_NEG) {
if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
mp_exch (&D, c);
c->sign = neg;
res = MP_OKAY;
LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
return res;
}
#endif
/* $Source: /cvs/libtom/libtommath/bn_fast_mp_invmod.c,v $ */
/* $Revision: 1.3 $ */
/* $Date: 2006/03/31 14:18:44 $ */
#include <tommath.h>
#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
*/
/* computes xR**-1 == x (mod N) via Montgomery Reduction
*
* This is an optimized implementation of montgomery_reduce
* which uses the comba method to quickly calculate the columns of the
* reduction.
*
* Based on Algorithm 14.32 on pp.601 of HAC.
*/
int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
{
int ix, res, olduse;
mp_word W[MP_WARRAY];
/* get old used count */
olduse = x->used;
/* grow a as required */
if (x->alloc < n->used + 1) {
if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
return res;
}
}
/* first we have to get the digits of the input into
* an array of double precision words W[...]
*/
{
register mp_word *_W;
register mp_digit *tmpx;
/* alias for the W[] array */
_W = W;
/* alias for the digits of x*/
tmpx = x->dp;
/* copy the digits of a into W[0..a->used-1] */
for (ix = 0; ix < x->used; ix++) {
*_W++ = *tmpx++;
}
/* zero the high words of W[a->used..m->used*2] */
for (; ix < n->used * 2 + 1; ix++) {
*_W++ = 0;
}
}
/* now we proceed to zero successive digits
* from the least significant upwards
*/
for (ix = 0; ix < n->used; ix++) {
/* mu = ai * m' mod b
*
* We avoid a double precision multiplication (which isn't required)
* by casting the value down to a mp_digit. Note this requires
* that W[ix-1] have the carry cleared (see after the inner loop)
*/
register mp_digit mu;
mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
/* a = a + mu * m * b**i
*
* This is computed in place and on the fly. The multiplication
* by b**i is handled by offseting which columns the results
* are added to.
*
* Note the comba method normally doesn't handle carries in the
* inner loop In this case we fix the carry from the previous
* column since the Montgomery reduction requires digits of the
* result (so far) [see above] to work. This is
* handled by fixing up one carry after the inner loop. The
* carry fixups are done in order so after these loops the
* first m->used words of W[] have the carries fixed
*/
{
register int iy;
register mp_digit *tmpn;
register mp_word *_W;
/* alias for the digits of the modulus */
tmpn = n->dp;
/* Alias for the columns set by an offset of ix */
_W = W + ix;
/* inner loop */
for (iy = 0; iy < n->used; iy++) {
*_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
}
}
/* now fix carry for next digit, W[ix+1] */
W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
}
/* now we have to propagate the carries and
* shift the words downward [all those least
* significant digits we zeroed].
*/
{
register mp_digit *tmpx;
register mp_word *_W, *_W1;
/* nox fix rest of carries */
/* alias for current word */
_W1 = W + ix;
/* alias for next word, where the carry goes */
_W = W + ++ix;
for (; ix <= n->used * 2 + 1; ix++) {
*_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
}
/* copy out, A = A/b**n
*
* The result is A/b**n but instead of converting from an
* array of mp_word to mp_digit than calling mp_rshd
* we just copy them in the right order
*/
/* alias for destination word */
tmpx = x->dp;
/* alias for shifted double precision result */
_W = W + n->used;
for (ix = 0; ix < n->used + 1; ix++) {
*tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
}
/* zero oldused digits, if the input a was larger than
* m->used+1 we'll have to clear the digits
*/
for (; ix < olduse; ix++) {
*tmpx++ = 0;
}
}
/* set the max used and clamp */
x->used = n->used + 1;
mp_clamp (x);
/* if A >= m then A = A - m */
if (mp_cmp_mag (x, n) != MP_LT) {
return s_mp_sub (x, n, x);
}
return MP_OKAY;
}
#endif
/* $Source: /cvs/libtom/libtommath/bn_fast_mp_montgomery_reduce.c,v $ */
/* $Revision: 1.3 $ */
/* $Date: 2006/03/31 14:18:44 $ */
#include <tommath.h>
#ifdef BN_FAST_S_MP_MUL_DIGS_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
*/
/* Fast (comba) multiplier
*
* This is the fast column-array [comba] multiplier. It is
* designed to compute the columns of the product first
* then handle the carries afterwards. This has the effect
* of making the nested loops that compute the columns very
* simple and schedulable on super-scalar processors.
*
* This has been modified to produce a variable number of
* digits of output so if say only a half-product is required
* you don't have to compute the upper half (a feature
* required for fast Barrett reduction).
*
* Based on Algorithm 14.12 on pp.595 of HAC.
*
*/
int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
{
int olduse, res, pa, ix, iz;
mp_digit W[MP_WARRAY];
register mp_word _W;
/* grow the destination as required */
if (c->alloc < digs) {
if ((res = mp_grow (c, digs)) != MP_OKAY) {
return res;
}
}