diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5baa792 --- /dev/null +++ b/LICENSE @@ -0,0 +1,4 @@ +LibTomMath is hereby released into the Public Domain. + +-- Tom St Denis + diff --git a/bn.pdf b/bn.pdf index a6c3d07..a0cde68 100644 Binary files a/bn.pdf and b/bn.pdf differ diff --git a/bn.tex b/bn.tex index 9beddda..60f6d50 100644 --- a/bn.tex +++ b/bn.tex @@ -1,7 +1,7 @@ \documentclass[]{article} \begin{document} -\title{LibTomMath v0.24 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org } +\title{LibTomMath v0.25 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org } \author{Tom St Denis \\ tomstdenis@iahu.ca} \maketitle \newpage diff --git a/bn_error.c b/bn_error.c new file mode 100644 index 0000000..7cac649 --- /dev/null +++ b/bn_error.c @@ -0,0 +1,41 @@ +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +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"; +} + diff --git a/bn_fast_mp_invmod.c b/bn_fast_mp_invmod.c index e32c1ae..2b86ce4 100644 --- a/bn_fast_mp_invmod.c +++ b/bn_fast_mp_invmod.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -26,6 +26,14 @@ 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] if a,b are both even then return an error! + * + * That is if gcd(a,b) = 2**k * q then obviously there is no inverse. + */ + if (mp_iseven (a) == 1 && 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; @@ -41,15 +49,6 @@ fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) goto __ERR; } - /* 2. [modified] if x,y are both even then return an error! - * - * That is if gcd(x,y) = 2 * k then obviously there is no inverse. - */ - if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { - res = MP_VAL; - goto __ERR; - } - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ if ((res = mp_copy (&x, &u)) != MP_OKAY) { goto __ERR; diff --git a/bn_fast_mp_montgomery_reduce.c b/bn_fast_mp_montgomery_reduce.c index 7017455..b6a8645 100644 --- a/bn_fast_mp_montgomery_reduce.c +++ b/bn_fast_mp_montgomery_reduce.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -38,6 +38,9 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } } + /* 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; @@ -56,6 +59,9 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } } + /* now we proceed to zero successive digits + * from the least significant upwards + */ for (ix = 0; ix < n->used; ix++) { /* mu = ai * m' mod b * @@ -101,12 +107,20 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) 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++) { @@ -119,7 +133,11 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) * 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++) { @@ -127,7 +145,8 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits */ + * m->used+1 we'll have to clear the digits + */ for (; ix < olduse; ix++) { *tmpx++ = 0; } diff --git a/bn_fast_s_mp_mul_digs.c b/bn_fast_s_mp_mul_digs.c index bca2a71..75fa706 100644 --- a/bn_fast_s_mp_mul_digs.c +++ b/bn_fast_s_mp_mul_digs.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_fast_s_mp_mul_high_digs.c b/bn_fast_s_mp_mul_high_digs.c index e0e9281..779aa14 100644 --- a/bn_fast_s_mp_mul_high_digs.c +++ b/bn_fast_s_mp_mul_high_digs.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -12,7 +12,7 @@ * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include + #include /* this is a modified version of fast_s_mp_mul_digs that only produces * output digits *above* digs. See the comments for fast_s_mp_mul_digs diff --git a/bn_fast_s_mp_sqr.c b/bn_fast_s_mp_sqr.c index 2c01cd0..0a68d42 100644 --- a/bn_fast_s_mp_sqr.c +++ b/bn_fast_s_mp_sqr.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -48,14 +48,14 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) /* zero temp buffer (columns) * Note that there are two buffers. Since squaring requires - * a outter and inner product and the inner product requires + * a outer and inner product and the inner product requires * computing a product and doubling it (a relatively expensive * op to perform n**2 times if you don't have to) the inner and * outer products are computed in different buffers. This way * the inner product can be doubled using n doublings instead of * n**2 */ - memset (W, 0, newused * sizeof (mp_word)); + memset (W, 0, newused * sizeof (mp_word)); memset (W2, 0, newused * sizeof (mp_word)); /* This computes the inner product. To simplify the inner N**2 loop @@ -67,6 +67,7 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) * Note that every outer product is computed * for a particular column only once which means that * there is no need todo a double precision addition + * into the W2[] array. */ W2[ix + ix] = ((mp_word)a->dp[ix]) * ((mp_word)a->dp[ix]); @@ -95,7 +96,12 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) olduse = b->used; b->used = newused; - /* now compute digits */ + /* now compute digits + * + * We have to double the inner product sums, add in the + * outer product sums, propagate carries and convert + * to single precision. + */ { register mp_digit *tmpb; @@ -109,16 +115,21 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) /* double/add next digit */ W[ix] += W[ix] + W2[ix]; + /* propagate carry forwards [from the previous digit] */ W[ix] = W[ix] + (W[ix - 1] >> ((mp_word) DIGIT_BIT)); + + /* store the current digit now that the carry isn't + * needed + */ *tmpb++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); } - /* set the last value. Note even if the carry is zero - * this is required since the next step will not zero + /* set the last value. Note even if the carry is zero + * this is required since the next step will not zero * it if b originally had a value at b->dp[2*a.used] */ *tmpb++ = (mp_digit) (W[(newused) - 1] & ((mp_word) MP_MASK)); - /* clear high digits */ + /* clear high digits of b if there were any originally */ for (; ix < olduse; ix++) { *tmpb++ = 0; } diff --git a/bn_mp_2expt.c b/bn_mp_2expt.c index 96cf84e..5c4e256 100644 --- a/bn_mp_2expt.c +++ b/bn_mp_2expt.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -24,11 +24,18 @@ mp_2expt (mp_int * a, int b) { int res; + /* zero a as per default */ mp_zero (a); + + /* grow a to accomodate the single bit */ if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { return res; } + + /* set the used count of where the bit will go */ a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ a->dp[b / DIGIT_BIT] = 1 << (b % DIGIT_BIT); return MP_OKAY; diff --git a/bn_mp_abs.c b/bn_mp_abs.c index 60a3470..a5e9ab0 100644 --- a/bn_mp_abs.c +++ b/bn_mp_abs.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -22,9 +22,16 @@ int mp_abs (mp_int * a, mp_int * b) { int res; - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } } + + /* force the sign of b to positive */ b->sign = MP_ZPOS; + return MP_OKAY; } diff --git a/bn_mp_add.c b/bn_mp_add.c index 43a08ab..b144a8e 100644 --- a/bn_mp_add.c +++ b/bn_mp_add.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_add_d.c b/bn_mp_add_d.c index 9703ad3..11b2ecd 100644 --- a/bn_mp_add_d.c +++ b/bn_mp_add_d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -82,7 +82,11 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c) c->used = 1; /* the result is a single digit */ - *tmpc++ = b - a->dp[0]; + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } /* setup count so the clearing of oldused * can fall through correctly diff --git a/bn_mp_addmod.c b/bn_mp_addmod.c index 4ad89e0..691dc50 100644 --- a/bn_mp_addmod.c +++ b/bn_mp_addmod.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_and.c b/bn_mp_and.c index 8c18fdc..9abb618 100644 --- a/bn_mp_and.c +++ b/bn_mp_and.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_clamp.c b/bn_mp_clamp.c index c349f7c..c6285ce 100644 --- a/bn_mp_clamp.c +++ b/bn_mp_clamp.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -24,9 +24,14 @@ void mp_clamp (mp_int * a) { + /* decrease used while the most significant digit is + * zero. + */ while (a->used > 0 && a->dp[a->used - 1] == 0) { --(a->used); } + + /* reset the sign flag if used == 0 */ if (a->used == 0) { a->sign = MP_ZPOS; } diff --git a/bn_mp_clear.c b/bn_mp_clear.c index bc31c42..be2562e 100644 --- a/bn_mp_clear.c +++ b/bn_mp_clear.c @@ -1,10 +1,10 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with + * 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 @@ -18,6 +18,7 @@ void mp_clear (mp_int * a) { + /* only do anything if a hasn't been freed previously */ if (a->dp != NULL) { /* first zero the digits */ memset (a->dp, 0, sizeof (mp_digit) * a->used); @@ -28,5 +29,6 @@ mp_clear (mp_int * a) /* reset members to make debugging easier */ a->dp = NULL; a->alloc = a->used = 0; + a->sign = MP_ZPOS; } } diff --git a/bn_mp_clear_multi.c b/bn_mp_clear_multi.c new file mode 100644 index 0000000..d262b2f --- /dev/null +++ b/bn_mp_clear_multi.c @@ -0,0 +1,28 @@ +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include +#include + +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} diff --git a/bn_mp_cmp.c b/bn_mp_cmp.c index 4bf8082..995e4c4 100644 --- a/bn_mp_cmp.c +++ b/bn_mp_cmp.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_cmp_d.c b/bn_mp_cmp_d.c index f2725cf..600438f 100644 --- a/bn_mp_cmp_d.c +++ b/bn_mp_cmp_d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -18,15 +18,17 @@ int mp_cmp_d (mp_int * a, mp_digit b) { - + /* compare based on sign */ if (a->sign == MP_NEG) { return MP_LT; } + /* compare based on magnitude */ if (a->used > 1) { return MP_GT; } + /* compare the only digit of a to b */ if (a->dp[0] > b) { return MP_GT; } else if (a->dp[0] < b) { diff --git a/bn_mp_cmp_mag.c b/bn_mp_cmp_mag.c index 87b56d6..c52d725 100644 --- a/bn_mp_cmp_mag.c +++ b/bn_mp_cmp_mag.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_cnt_lsb.c b/bn_mp_cnt_lsb.c index df0846f..e46161b 100644 --- a/bn_mp_cnt_lsb.c +++ b/bn_mp_cnt_lsb.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -20,6 +20,7 @@ int mp_cnt_lsb(mp_int *a) int x; mp_digit q; + /* easy out */ if (mp_iszero(a) == 1) { return 0; } diff --git a/bn_mp_copy.c b/bn_mp_copy.c index 4e3eef8..1c45f3e 100644 --- a/bn_mp_copy.c +++ b/bn_mp_copy.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -26,8 +26,10 @@ mp_copy (mp_int * a, mp_int * b) } /* grow dest */ - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } } /* zero b and copy the parameters over */ @@ -35,7 +37,11 @@ mp_copy (mp_int * a, mp_int * b) register mp_digit *tmpa, *tmpb; /* pointer aliases */ + + /* source */ tmpa = a->dp; + + /* destination */ tmpb = b->dp; /* copy all the digits */ @@ -48,6 +54,8 @@ mp_copy (mp_int * a, mp_int * b) *tmpb++ = 0; } } + + /* copy used count and sign */ b->used = a->used; b->sign = a->sign; return MP_OKAY; diff --git a/bn_mp_count_bits.c b/bn_mp_count_bits.c index e48bda1..33b971b 100644 --- a/bn_mp_count_bits.c +++ b/bn_mp_count_bits.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_div.c b/bn_mp_div.c index 4e0f353..b211cf4 100644 --- a/bn_mp_div.c +++ b/bn_mp_div.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_div_2.c b/bn_mp_div_2.c index 1ade93c..1c545f1 100644 --- a/bn_mp_div_2.c +++ b/bn_mp_div_2.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_div_2d.c b/bn_mp_div_2d.c index 9bc1fd6..66db765 100644 --- a/bn_mp_div_2d.c +++ b/bn_mp_div_2d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_div_3.c b/bn_mp_div_3.c index d82f29f..0c41db6 100644 --- a/bn_mp_div_3.c +++ b/bn_mp_div_3.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -35,10 +35,17 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) w = 0; for (ix = a->used - 1; ix >= 0; ix--) { w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - + if (w >= 3) { + /* multiply w by [1/3] */ t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ w -= (t << ((mp_word)1)) + t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ while (w >= 3) { t += 1; w -= 3; @@ -48,11 +55,13 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) } q.dp[ix] = (mp_digit)t; } - + + /* [optional] store the remainder */ if (d != NULL) { *d = (mp_digit)w; } - + + /* [optional] store the quotient */ if (c != NULL) { mp_clamp(&q); mp_exch(&q, c); diff --git a/bn_mp_div_d.c b/bn_mp_div_d.c index 0f683a5..2502341 100644 --- a/bn_mp_div_d.c +++ b/bn_mp_div_d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_dr_is_modulus.c b/bn_mp_dr_is_modulus.c index 381af17..0206e0e 100644 --- a/bn_mp_dr_is_modulus.c +++ b/bn_mp_dr_is_modulus.c @@ -1,34 +1,37 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* determines if a number is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a) -{ - int ix; - - /* must be at least two digits */ - if (a->used < 2) { - return 0; - } - - for (ix = 1; ix < a->used; ix++) { - if (a->dp[ix] != MP_MASK) { - return 0; - } - } - return 1; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines if a number is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a) +{ + int ix; + + /* must be at least two digits */ + if (a->used < 2) { + return 0; + } + + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ + for (ix = 1; ix < a->used; ix++) { + if (a->dp[ix] != MP_MASK) { + return 0; + } + } + return 1; +} + diff --git a/bn_mp_dr_reduce.c b/bn_mp_dr_reduce.c index 7d7259e..500f558 100644 --- a/bn_mp_dr_reduce.c +++ b/bn_mp_dr_reduce.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -57,7 +57,7 @@ top: /* set carry to zero */ mu = 0; - /* compute (x mod B**m) + mp * [x/B**m] inline and inplace */ + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ for (i = 0; i < m; i++) { r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; *tmpx1++ = (mp_digit)(r & MP_MASK); diff --git a/bn_mp_dr_setup.c b/bn_mp_dr_setup.c index c1dbbbb..f269436 100644 --- a/bn_mp_dr_setup.c +++ b/bn_mp_dr_setup.c @@ -1,26 +1,26 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* determines the setup value */ -void mp_dr_setup(mp_int *a, mp_digit *d) -{ - /* the casts are required if DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] - */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - - ((mp_word)a->dp[0])); -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines the setup value */ +void mp_dr_setup(mp_int *a, mp_digit *d) +{ + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + */ + *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - + ((mp_word)a->dp[0])); +} + diff --git a/bn_mp_exch.c b/bn_mp_exch.c index b2cdab7..71f6e04 100644 --- a/bn_mp_exch.c +++ b/bn_mp_exch.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -22,7 +22,7 @@ mp_exch (mp_int * a, mp_int * b) { mp_int t; - t = *a; + t = *a; *a = *b; *b = t; } diff --git a/bn_mp_expt_d.c b/bn_mp_expt_d.c index cf5c8ed..49594f8 100644 --- a/bn_mp_expt_d.c +++ b/bn_mp_expt_d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_exptmod.c b/bn_mp_exptmod.c index e94e658..2da394b 100644 --- a/bn_mp_exptmod.c +++ b/bn_mp_exptmod.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -60,7 +60,10 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) return err; } + /* is it a DR modulus? */ dr = mp_dr_is_modulus(P); + + /* if not, is it a uDR modulus? */ if (dr == 0) { dr = mp_reduce_is_2k(P) << 1; } @@ -69,6 +72,7 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if (mp_isodd (P) == 1 || dr != 0) { return mp_exptmod_fast (G, X, P, Y, dr); } else { + /* otherwise use the generic Barrett reduction technique */ return s_mp_exptmod (G, X, P, Y); } } diff --git a/bn_mp_exptmod_fast.c b/bn_mp_exptmod_fast.c index 8a5e565..1fe9df6 100644 --- a/bn_mp_exptmod_fast.c +++ b/bn_mp_exptmod_fast.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -94,15 +94,15 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { redux = fast_mp_montgomery_reduce; } else { - /* use slower baselien method */ + /* use slower baseline Montgomery method */ redux = mp_montgomery_reduce; } } else if (redmode == 1) { - /* setup DR reduction */ + /* setup DR reduction for moduli of the form B**k - b */ mp_dr_setup(P, &mp); redux = mp_dr_reduce; } else { - /* setup 2k reduction */ + /* setup DR reduction for moduli of the form 2**k - b */ if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { goto __M; } @@ -111,7 +111,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* setup result */ if ((err = mp_init (&res)) != MP_OKAY) { - goto __RES; + goto __M; } /* create M table @@ -173,15 +173,17 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) for (;;) { /* grab next digit as required */ if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ if (digidx == -1) { break; } - buf = X->dp[digidx--]; - bitcnt = (int) DIGIT_BIT; + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; } /* grab the next msb from the exponent */ - y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; buf <<= (mp_digit)1; /* if the bit is zero and mode == 0 then we ignore it @@ -206,7 +208,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* else we add it to the window */ bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; + mode = 2; if (bitcpy == winsize) { /* ok window is filled so square as required and multiply */ @@ -231,7 +233,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* empty window and reset */ bitcpy = 0; bitbuf = 0; - mode = 1; + mode = 1; } } @@ -246,6 +248,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) goto __RES; } + /* get next bit of the window */ bitbuf <<= 1; if ((bitbuf & (1 << winsize)) != 0) { /* then multiply */ @@ -260,12 +263,18 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) } if (redmode == 0) { - /* fixup result if Montgomery reduction is used */ + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { goto __RES; } } + /* swap res with Y */ mp_exch (&res, Y); err = MP_OKAY; __RES:mp_clear (&res); diff --git a/bn_mp_fread.c b/bn_mp_fread.c index 004b0f1..ef665e5 100644 --- a/bn_mp_fread.c +++ b/bn_mp_fread.c @@ -1,61 +1,61 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* read a bigint from a file stream in ASCII */ -int mp_fread(mp_int *a, int radix, FILE *stream) -{ - int err, ch, neg, y; - - /* clear a */ - mp_zero(a); - - /* if first digit is - then set negative */ - ch = fgetc(stream); - if (ch == '-') { - neg = MP_NEG; - ch = fgetc(stream); - } else { - neg = MP_ZPOS; - } - - for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } - } - if (y == radix) { - break; - } - - /* shift up and add */ - if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { - return err; - } - if ((err = mp_add_d(a, y, a)) != MP_OKAY) { - return err; - } - - ch = fgetc(stream); - } - if (mp_cmp_d(a, 0) != MP_EQ) { - a->sign = neg; - } - - return MP_OKAY; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* read a bigint from a file stream in ASCII */ +int mp_fread(mp_int *a, int radix, FILE *stream) +{ + int err, ch, neg, y; + + /* clear a */ + mp_zero(a); + + /* if first digit is - then set negative */ + ch = fgetc(stream); + if (ch == '-') { + neg = MP_NEG; + ch = fgetc(stream); + } else { + neg = MP_ZPOS; + } + + for (;;) { + /* find y in the radix map */ + for (y = 0; y < radix; y++) { + if (mp_s_rmap[y] == ch) { + break; + } + } + if (y == radix) { + break; + } + + /* shift up and add */ + if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + return err; + } + if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + return err; + } + + ch = fgetc(stream); + } + if (mp_cmp_d(a, 0) != MP_EQ) { + a->sign = neg; + } + + return MP_OKAY; +} + diff --git a/bn_mp_fwrite.c b/bn_mp_fwrite.c index 93d51fd..a1fe564 100644 --- a/bn_mp_fwrite.c +++ b/bn_mp_fwrite.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_gcd.c b/bn_mp_gcd.c index b73657c..d46d468 100644 --- a/bn_mp_gcd.c +++ b/bn_mp_gcd.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -23,16 +23,21 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) /* either zero than gcd is the largest */ if (mp_iszero (a) == 1 && mp_iszero (b) == 0) { - return mp_copy (b, c); + return mp_abs (b, c); } if (mp_iszero (a) == 0 && mp_iszero (b) == 1) { - return mp_copy (a, c); + return mp_abs (a, c); } - if (mp_iszero (a) == 1 && mp_iszero (b) == 1) { + + /* optimized. At this point if a == 0 then + * b must equal zero too + */ + if (mp_iszero (a) == 1) { mp_zero(c); return MP_OKAY; } + /* get copies of a and b we can modify */ if ((res = mp_init_copy (&u, a)) != MP_OKAY) { return res; } @@ -49,12 +54,15 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) v_lsb = mp_cnt_lsb(&v); k = MIN(u_lsb, v_lsb); - if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { - goto __V; - } + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto __V; + } - if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { - goto __V; + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto __V; + } } /* divide any remaining factors of two out */ @@ -69,10 +77,11 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) goto __V; } } - + while (mp_iszero(&v) == 0) { /* make sure v is the largest */ if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ mp_exch(&u, &v); } @@ -86,10 +95,10 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) goto __V; } } - - /* multiply by 2**k which we divided out at the beginning */ + + /* multiply by 2**k which we divided out at the beginning */ if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { - goto __V; + goto __V; } c->sign = MP_ZPOS; res = MP_OKAY; diff --git a/bn_mp_grow.c b/bn_mp_grow.c index 2a8249c..e6ae02f 100644 --- a/bn_mp_grow.c +++ b/bn_mp_grow.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -23,7 +23,7 @@ mp_grow (mp_int * a, int size) /* if the alloc size is smaller alloc more ram */ if (a->alloc < size) { /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size & (MP_PREC - 1)); + size += (MP_PREC * 2) - (size % MP_PREC); a->dp = OPT_CAST realloc (a->dp, sizeof (mp_digit) * size); if (a->dp == NULL) { diff --git a/bn_mp_init.c b/bn_mp_init.c index 2cfa002..f39b5cd 100644 --- a/bn_mp_init.c +++ b/bn_mp_init.c @@ -1,10 +1,10 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with + * 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 @@ -18,7 +18,7 @@ int mp_init (mp_int * a) { - /* allocate ram required and clear it */ + /* allocate memory required and clear it */ a->dp = OPT_CAST calloc (sizeof (mp_digit), MP_PREC); if (a->dp == NULL) { return MP_MEM; diff --git a/bn_mp_init_copy.c b/bn_mp_init_copy.c index f87ad16..f0f3590 100644 --- a/bn_mp_init_copy.c +++ b/bn_mp_init_copy.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_multi.c b/bn_mp_init_multi.c similarity index 81% rename from bn_mp_multi.c rename to bn_mp_init_multi.c index ef96dc6..1989b55 100644 --- a/bn_mp_multi.c +++ b/bn_mp_init_multi.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -49,16 +49,4 @@ int mp_init_multi(mp_int *mp, ...) } va_end(args); return res; /* Assumed ok, if error flagged above. */ -} - -void mp_clear_multi(mp_int *mp, ...) -{ - mp_int* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - mp_clear(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); -} +} \ No newline at end of file diff --git a/bn_mp_init_size.c b/bn_mp_init_size.c index 2408c1a..6e15ec0 100644 --- a/bn_mp_init_size.c +++ b/bn_mp_init_size.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -14,22 +14,21 @@ */ #include -/* init a mp_init and grow it to a given size */ +/* init an mp_init for a given size */ int mp_init_size (mp_int * a, int size) { - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size & (MP_PREC - 1)); + size += (MP_PREC * 2) - (size % MP_PREC); /* alloc mem */ a->dp = OPT_CAST calloc (sizeof (mp_digit), size); if (a->dp == NULL) { return MP_MEM; } - a->used = 0; + a->used = 0; a->alloc = size; - a->sign = MP_ZPOS; + a->sign = MP_ZPOS; return MP_OKAY; } diff --git a/bn_mp_invmod.c b/bn_mp_invmod.c index 2dd7a0c..ecfc167 100644 --- a/bn_mp_invmod.c +++ b/bn_mp_invmod.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_jacobi.c b/bn_mp_jacobi.c index eb0c47b..4c49eb5 100644 --- a/bn_mp_jacobi.c +++ b/bn_mp_jacobi.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -24,6 +24,11 @@ mp_jacobi (mp_int * a, mp_int * p, int *c) int k, s, r, res; mp_digit residue; + /* if p <= 0 return MP_VAL */ + if (mp_cmp_d(p, 0) != MP_GT) { + return MP_VAL; + } + /* step 1. if a == 0, return 0 */ if (mp_iszero (a) == 1) { *c = 0; @@ -37,7 +42,7 @@ mp_jacobi (mp_int * a, mp_int * p, int *c) } /* default */ - k = s = 0; + s = 0; /* step 3. write a = a1 * 2**k */ if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { @@ -48,11 +53,10 @@ mp_jacobi (mp_int * a, mp_int * p, int *c) goto __A1; } - while (mp_iseven (&a1) == 1) { - k = k + 1; - if ((res = mp_div_2 (&a1, &a1)) != MP_OKAY) { - goto __P1; - } + /* divide out larger power of two */ + k = mp_cnt_lsb(&a1); + if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { + goto __P1; } /* step 4. if e is even set s=1 */ diff --git a/bn_mp_karatsuba_mul.c b/bn_mp_karatsuba_mul.c index bda2f1e..95353ea 100644 --- a/bn_mp_karatsuba_mul.c +++ b/bn_mp_karatsuba_mul.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_karatsuba_sqr.c b/bn_mp_karatsuba_sqr.c index c9e3e67..04dd286 100644 --- a/bn_mp_karatsuba_sqr.c +++ b/bn_mp_karatsuba_sqr.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_lcm.c b/bn_mp_lcm.c index 75b5829..0c0c237 100644 --- a/bn_mp_lcm.c +++ b/bn_mp_lcm.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_lshd.c b/bn_mp_lshd.c index 1ac185c..15fca0e 100644 --- a/bn_mp_lshd.c +++ b/bn_mp_lshd.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_mod.c b/bn_mp_mod.c index e6027ce..d5ebb16 100644 --- a/bn_mp_mod.c +++ b/bn_mp_mod.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_mod_2d.c b/bn_mp_mod_2d.c index fda6335..c25212d 100644 --- a/bn_mp_mod_2d.c +++ b/bn_mp_mod_2d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -20,7 +20,6 @@ mp_mod_2d (mp_int * a, int b, mp_int * c) { int x, res; - /* if b is <= 0 then zero the int */ if (b <= 0) { mp_zero (c); diff --git a/bn_mp_mod_d.c b/bn_mp_mod_d.c index 7ebb61e..c5dbe46 100644 --- a/bn_mp_mod_d.c +++ b/bn_mp_mod_d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_montgomery_calc_normalization.c b/bn_mp_montgomery_calc_normalization.c index a1ff2cd..a38555c 100644 --- a/bn_mp_montgomery_calc_normalization.c +++ b/bn_mp_montgomery_calc_normalization.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_montgomery_reduce.c b/bn_mp_montgomery_reduce.c index 99a8a55..3fabaf9 100644 --- a/bn_mp_montgomery_reduce.c +++ b/bn_mp_montgomery_reduce.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_montgomery_setup.c b/bn_mp_montgomery_setup.c index 29aead7..36253af 100644 --- a/bn_mp_montgomery_setup.c +++ b/bn_mp_montgomery_setup.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_mul.c b/bn_mp_mul.c index 6b00235..8153169 100644 --- a/bn_mp_mul.c +++ b/bn_mp_mul.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -20,13 +20,14 @@ mp_mul (mp_int * a, mp_int * b, mp_int * c) { int res, neg; neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - + + /* use Toom-Cook? */ if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { res = mp_toom_mul(a, b, c); + /* use Karatsuba? */ } else if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { res = mp_karatsuba_mul (a, b, c); } else { - /* can we use the fast multiplier? * * The fast multiplier can be used if the output will diff --git a/bn_mp_mul_2.c b/bn_mp_mul_2.c index 2bfc939..6a5b4a7 100644 --- a/bn_mp_mul_2.c +++ b/bn_mp_mul_2.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -61,7 +61,7 @@ mp_mul_2 (mp_int * a, mp_int * b) if (r != 0) { /* add a MSB which is always 1 at this point */ *tmpb = 1; - ++b->used; + ++(b->used); } /* now zero any excess digits on the destination diff --git a/bn_mp_mul_2d.c b/bn_mp_mul_2d.c index 450f619..072ba33 100644 --- a/bn_mp_mul_2d.c +++ b/bn_mp_mul_2d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -72,7 +72,7 @@ mp_mul_2d (mp_int * a, int b, mp_int * c) /* set final carry */ if (r != 0) { - c->dp[c->used++] = r; + c->dp[(c->used)++] = r; } } mp_clamp (c); diff --git a/bn_mp_mul_d.c b/bn_mp_mul_d.c index 8379035..ae665bc 100644 --- a/bn_mp_mul_d.c +++ b/bn_mp_mul_d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_mulmod.c b/bn_mp_mulmod.c index 2e3400a..4b14b24 100644 --- a/bn_mp_mulmod.c +++ b/bn_mp_mulmod.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_n_root.c b/bn_mp_n_root.c index 0f1bb56..d91f469 100644 --- a/bn_mp_n_root.c +++ b/bn_mp_n_root.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -48,7 +48,7 @@ mp_n_root (mp_int * a, mp_digit b, mp_int * c) } /* if a is negative fudge the sign but keep track */ - neg = a->sign; + neg = a->sign; a->sign = MP_ZPOS; /* t2 = 2 */ diff --git a/bn_mp_neg.c b/bn_mp_neg.c index 73f948a..e710790 100644 --- a/bn_mp_neg.c +++ b/bn_mp_neg.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_or.c b/bn_mp_or.c index 466a171..786a9e5 100644 --- a/bn_mp_or.c +++ b/bn_mp_or.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_prime_fermat.c b/bn_mp_prime_fermat.c index b0e9746..de19676 100644 --- a/bn_mp_prime_fermat.c +++ b/bn_mp_prime_fermat.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -28,7 +28,7 @@ mp_prime_fermat (mp_int * a, mp_int * b, int *result) mp_int t; int err; - /* default to fail */ + /* default to composite */ *result = 0; /* ensure b > 1 */ diff --git a/bn_mp_prime_is_divisible.c b/bn_mp_prime_is_divisible.c index fcad869..cea3d98 100644 --- a/bn_mp_prime_is_divisible.c +++ b/bn_mp_prime_is_divisible.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_prime_is_prime.c b/bn_mp_prime_is_prime.c index f9cece9..21c8619 100644 --- a/bn_mp_prime_is_prime.c +++ b/bn_mp_prime_is_prime.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_prime_miller_rabin.c b/bn_mp_prime_miller_rabin.c index c85136b..ef89125 100644 --- a/bn_mp_prime_miller_rabin.c +++ b/bn_mp_prime_miller_rabin.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_prime_next_prime.c b/bn_mp_prime_next_prime.c index 2072ff2..7dc0e51 100644 --- a/bn_mp_prime_next_prime.c +++ b/bn_mp_prime_next_prime.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -31,9 +31,7 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) } /* force positive */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - } + a->sign = MP_ZPOS; /* simple algo if a is less than the largest prime in the table */ if (mp_cmp_d(a, __prime_tab[PRIME_SIZE-1]) == MP_LT) { @@ -137,8 +135,8 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) goto __ERR; } - /* if step == MAX then skip test */ - if (step >= ((((mp_digit)1)<= ((((mp_digit)1)< - -/* returns size of ASCII reprensentation */ -int -mp_radix_size (mp_int * a, int radix) -{ - int res, digs; - mp_int t; - mp_digit d; - - /* special case for binary */ - if (radix == 2) { - return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; - } - - if (radix < 2 || radix > 64) { - return 0; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return 0; - } - - digs = 0; - if (t.sign == MP_NEG) { - ++digs; - t.sign = MP_ZPOS; - } - - while (mp_iszero (&t) == 0) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return 0; - } - ++digs; - } - mp_clear (&t); - return digs + 1; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* returns size of ASCII reprensentation */ +int +mp_radix_size (mp_int * a, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + + /* special case for binary */ + if (radix == 2) { + return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; + } + + if (radix < 2 || radix > 64) { + return 0; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return 0; + } + + digs = 0; + if (t.sign == MP_NEG) { + ++digs; + t.sign = MP_ZPOS; + } + + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return 0; + } + ++digs; + } + mp_clear (&t); + return digs + 1; +} + diff --git a/bn_mp_radix_smap.c b/bn_mp_radix_smap.c index 45d02aa..2c4d966 100644 --- a/bn_mp_radix_smap.c +++ b/bn_mp_radix_smap.c @@ -1,18 +1,18 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* chars used in radix conversions */ -const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* chars used in radix conversions */ +const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; diff --git a/bn_mp_rand.c b/bn_mp_rand.c index b944d57..c744994 100644 --- a/bn_mp_rand.c +++ b/bn_mp_rand.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_read_radix.c b/bn_mp_read_radix.c index e32823f..ac87993 100644 --- a/bn_mp_read_radix.c +++ b/bn_mp_read_radix.c @@ -1,77 +1,77 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* read a string [ASCII] in a given radix */ -int -mp_read_radix (mp_int * a, char *str, int radix) -{ - int y, res, neg; - char ch; - - /* make sure the radix is ok */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = MP_NEG; - } else { - neg = MP_ZPOS; - } - - /* set the integer to the default of zero */ - mp_zero (a); - - /* process each digit of the string */ - while (*str) { - /* if the radix < 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (char) ((radix < 36) ? toupper (*str) : *str); - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } - } - - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { - return res; - } - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (mp_iszero(a) != 1) { - a->sign = neg; - } - return MP_OKAY; -} +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* read a string [ASCII] in a given radix */ +int +mp_read_radix (mp_int * a, char *str, int radix) +{ + int y, res, neg; + char ch; + + /* make sure the radix is ok */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero (a); + + /* process each digit of the string */ + while (*str) { + /* if the radix < 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (char) ((radix < 36) ? toupper (*str) : *str); + for (y = 0; y < 64; y++) { + if (ch == mp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { + return res; + } + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (mp_iszero(a) != 1) { + a->sign = neg; + } + return MP_OKAY; +} diff --git a/bn_mp_read_signed_bin.c b/bn_mp_read_signed_bin.c index 448e327..7817243 100644 --- a/bn_mp_read_signed_bin.c +++ b/bn_mp_read_signed_bin.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_read_unsigned_bin.c b/bn_mp_read_unsigned_bin.c index 8ca2c11..3b4f5cb 100644 --- a/bn_mp_read_unsigned_bin.c +++ b/bn_mp_read_unsigned_bin.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_reduce.c b/bn_mp_reduce.c index 38689e8..d4c5b10 100644 --- a/bn_mp_reduce.c +++ b/bn_mp_reduce.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_reduce_2k.c b/bn_mp_reduce_2k.c index 91d5f6f..f73d3b9 100644 --- a/bn_mp_reduce_2k.c +++ b/bn_mp_reduce_2k.c @@ -1,56 +1,56 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* reduces a modulo n where n is of the form 2**p - k */ -int -mp_reduce_2k(mp_int *a, mp_int *n, mp_digit k) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (k != 1) { - /* q = q * k */ - if ((res = mp_mul_d(&q, k, &q)) != MP_OKAY) { - goto ERR; - } - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* reduces a modulo n where n is of the form 2**p - k */ +int +mp_reduce_2k(mp_int *a, mp_int *n, mp_digit k) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (k != 1) { + /* q = q * k */ + if ((res = mp_mul_d(&q, k, &q)) != MP_OKAY) { + goto ERR; + } + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + diff --git a/bn_mp_reduce_2k_setup.c b/bn_mp_reduce_2k_setup.c index 7308c32..6bdfe7f 100644 --- a/bn_mp_reduce_2k_setup.c +++ b/bn_mp_reduce_2k_setup.c @@ -1,42 +1,42 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* determines the setup value */ -int -mp_reduce_2k_setup(mp_int *a, mp_digit *d) -{ - int res, p; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(a); - if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - *d = tmp.dp[0]; - mp_clear(&tmp); - return MP_OKAY; -} +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines the setup value */ +int +mp_reduce_2k_setup(mp_int *a, mp_digit *d) +{ + int res, p; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(a); + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + *d = tmp.dp[0]; + mp_clear(&tmp); + return MP_OKAY; +} diff --git a/bn_mp_reduce_is_2k.c b/bn_mp_reduce_is_2k.c index 3e4a757..117a8fa 100644 --- a/bn_mp_reduce_is_2k.c +++ b/bn_mp_reduce_is_2k.c @@ -1,38 +1,38 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* determines if mp_reduce_2k can be used */ -int -mp_reduce_is_2k(mp_int *a) -{ - int ix, iy; - - if (a->used == 0) { - return 0; - } else if (a->used == 1) { - return 1; - } else if (a->used > 1) { - iy = mp_count_bits(a); - for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[ix/DIGIT_BIT] & - ((mp_digit)1 << (mp_digit)(ix % DIGIT_BIT))) == 0) { - return 0; - } - } - } - return 1; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines if mp_reduce_2k can be used */ +int +mp_reduce_is_2k(mp_int *a) +{ + int ix, iy; + + if (a->used == 0) { + return 0; + } else if (a->used == 1) { + return 1; + } else if (a->used > 1) { + iy = mp_count_bits(a); + for (ix = DIGIT_BIT; ix < iy; ix++) { + if ((a->dp[ix/DIGIT_BIT] & + ((mp_digit)1 << (mp_digit)(ix % DIGIT_BIT))) == 0) { + return 0; + } + } + } + return 1; +} + diff --git a/bn_mp_reduce_setup.c b/bn_mp_reduce_setup.c index 6f2b8eb..1ba69e9 100644 --- a/bn_mp_reduce_setup.c +++ b/bn_mp_reduce_setup.c @@ -1,29 +1,29 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* pre-calculate the value required for Barrett reduction - * For a given modulus "b" it calulates the value required in "a" - */ -int -mp_reduce_setup (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { - return res; - } - return mp_div (a, b, a, NULL); -} +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +int +mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} diff --git a/bn_mp_rshd.c b/bn_mp_rshd.c index f657ec0..f246a93 100644 --- a/bn_mp_rshd.c +++ b/bn_mp_rshd.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_set.c b/bn_mp_set.c index d749463..dab437f 100644 --- a/bn_mp_set.c +++ b/bn_mp_set.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -20,5 +20,5 @@ mp_set (mp_int * a, mp_digit b) { mp_zero (a); a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; + a->used = (a->dp[0] != 0) ? 1 : 0; } diff --git a/bn_mp_set_int.c b/bn_mp_set_int.c index a9a37f1..26611aa 100644 --- a/bn_mp_set_int.c +++ b/bn_mp_set_int.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_shrink.c b/bn_mp_shrink.c index 023a46b..ef83aee 100644 --- a/bn_mp_shrink.c +++ b/bn_mp_shrink.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_signed_bin_size.c b/bn_mp_signed_bin_size.c index fe8f499..d392ebc 100644 --- a/bn_mp_signed_bin_size.c +++ b/bn_mp_signed_bin_size.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_sqr.c b/bn_mp_sqr.c index 77539fc..d354c0b 100644 --- a/bn_mp_sqr.c +++ b/bn_mp_sqr.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -19,13 +19,14 @@ int mp_sqr (mp_int * a, mp_int * b) { int res; + /* use Toom-Cook? */ if (a->used >= TOOM_SQR_CUTOFF) { res = mp_toom_sqr(a, b); + /* Karatsuba? */ } else if (a->used >= KARATSUBA_SQR_CUTOFF) { res = mp_karatsuba_sqr (a, b); } else { - - /* can we use the fast multiplier? */ + /* can we use the fast comba multiplier? */ if ((a->used * 2 + 1) < MP_WARRAY && a->used < (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { diff --git a/bn_mp_sqrmod.c b/bn_mp_sqrmod.c index c32d562..778b68e 100644 --- a/bn_mp_sqrmod.c +++ b/bn_mp_sqrmod.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -21,7 +21,6 @@ mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) int res; mp_int t; - if ((res = mp_init (&t)) != MP_OKAY) { return res; } diff --git a/bn_mp_sub.c b/bn_mp_sub.c index 2bc4123..eb99583 100644 --- a/bn_mp_sub.c +++ b/bn_mp_sub.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_sub_d.c b/bn_mp_sub_d.c index 2fd8bdb..d9938f4 100644 --- a/bn_mp_sub_d.c +++ b/bn_mp_sub_d.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -45,7 +45,11 @@ mp_sub_d (mp_int * a, mp_digit b, mp_int * c) /* if a <= b simply fix the single digit */ if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { - *tmpc++ = b - *tmpa; + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } ix = 1; /* negative/1digit */ diff --git a/bn_mp_submod.c b/bn_mp_submod.c index 1606ff0..868dd2f 100644 --- a/bn_mp_submod.c +++ b/bn_mp_submod.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_to_signed_bin.c b/bn_mp_to_signed_bin.c index 023c80f..1e21667 100644 --- a/bn_mp_to_signed_bin.c +++ b/bn_mp_to_signed_bin.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_to_unsigned_bin.c b/bn_mp_to_unsigned_bin.c index 54e0739..f7cae69 100644 --- a/bn_mp_to_unsigned_bin.c +++ b/bn_mp_to_unsigned_bin.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_toom_mul.c b/bn_mp_toom_mul.c index 63f253c..2ba4624 100644 --- a/bn_mp_toom_mul.c +++ b/bn_mp_toom_mul.c @@ -1,273 +1,273 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* multiplication using the Toom-Cook 3-way algorithm */ -int -mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = MIN(a->used, b->used) / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* b = b2 * B**2 + b1 * B + b0 */ - if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(b, &b1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b1, B); - mp_mod_2d(&b1, DIGIT_BIT * B, &b1); - - if ((res = mp_copy(b, &b2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b2, B*2); - - /* w0 = a0*b0 */ - if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * b2 */ - if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, - 2 small divisions and 1 small multiplication - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL); - return res; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* multiplication using the Toom-Cook 3-way algorithm */ +int +mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = MIN(a->used, b->used) / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* b = b2 * B**2 + b1 * B + b0 */ + if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(b, &b1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b1, B); + mp_mod_2d(&b1, DIGIT_BIT * B, &b1); + + if ((res = mp_copy(b, &b2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b2, B*2); + + /* w0 = a0*b0 */ + if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * b2 */ + if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, + 2 small divisions and 1 small multiplication + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL); + return res; +} + diff --git a/bn_mp_toom_sqr.c b/bn_mp_toom_sqr.c index bccf709..7db1592 100644 --- a/bn_mp_toom_sqr.c +++ b/bn_mp_toom_sqr.c @@ -1,220 +1,220 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* squaring using Toom-Cook 3-way algorithm */ -int -mp_toom_sqr(mp_int *a, mp_int *b) -{ - mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = a->used / 3; - - /* a = a2 * B^2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* w0 = a0*a0 */ - if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * a2 */ - if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))**2 */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))**2 */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)**2 */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); - return res; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* squaring using Toom-Cook 3-way algorithm */ +int +mp_toom_sqr(mp_int *a, mp_int *b) +{ + mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = a->used / 3; + + /* a = a2 * B^2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* w0 = a0*a0 */ + if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * a2 */ + if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))**2 */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))**2 */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)**2 */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); + return res; +} + diff --git a/bn_mp_toradix.c b/bn_mp_toradix.c index 52097b1..2c52dd6 100644 --- a/bn_mp_toradix.c +++ b/bn_mp_toradix.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_unsigned_bin_size.c b/bn_mp_unsigned_bin_size.c index 558efb0..47bbc64 100644 --- a/bn_mp_unsigned_bin_size.c +++ b/bn_mp_unsigned_bin_size.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_xor.c b/bn_mp_xor.c index 6622074..36e6733 100644 --- a/bn_mp_xor.c +++ b/bn_mp_xor.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_mp_zero.c b/bn_mp_zero.c index c86cabd..a888589 100644 --- a/bn_mp_zero.c +++ b/bn_mp_zero.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_prime_tab.c b/bn_prime_tab.c index 83c5469..7dfdc8c 100644 --- a/bn_prime_tab.c +++ b/bn_prime_tab.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_reverse.c b/bn_reverse.c index 4e785c4..89cbbb7 100644 --- a/bn_reverse.c +++ b/bn_reverse.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_s_mp_add.c b/bn_s_mp_add.c index cf677d8..e07931a 100644 --- a/bn_s_mp_add.c +++ b/bn_s_mp_add.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_s_mp_exptmod.c b/bn_s_mp_exptmod.c index 931d49f..68c91e7 100644 --- a/bn_s_mp_exptmod.c +++ b/bn_s_mp_exptmod.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -105,7 +105,9 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) } } - /* create upper table */ + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { goto __MU; @@ -132,15 +134,17 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) for (;;) { /* grab next digit as required */ if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ if (digidx == -1) { break; } - buf = X->dp[digidx--]; + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; bitcnt = (int) DIGIT_BIT; } /* grab the next msb from the exponent */ - y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; buf <<= (mp_digit)1; /* if the bit is zero and mode == 0 then we ignore it @@ -148,8 +152,9 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) * in the exponent. Technically this opt is not required but it * does lower the # of trivial squaring/reductions used */ - if (mode == 0 && y == 0) + if (mode == 0 && y == 0) { continue; + } /* if the bit is zero and mode == 1 then we square */ if (mode == 1 && y == 0) { @@ -164,7 +169,7 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) /* else we add it to the window */ bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; + mode = 2; if (bitcpy == winsize) { /* ok window is filled so square as required and multiply */ @@ -189,7 +194,7 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) /* empty window and reset */ bitcpy = 0; bitbuf = 0; - mode = 1; + mode = 1; } } diff --git a/bn_s_mp_mul_digs.c b/bn_s_mp_mul_digs.c index cb3dbd7..2d78a2d 100644 --- a/bn_s_mp_mul_digs.c +++ b/bn_s_mp_mul_digs.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_s_mp_mul_high_digs.c b/bn_s_mp_mul_high_digs.c index a0c2c0e..4e4d536 100644 --- a/bn_s_mp_mul_high_digs.c +++ b/bn_s_mp_mul_high_digs.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_s_mp_sqr.c b/bn_s_mp_sqr.c index d45a00e..9bf3ef1 100644 --- a/bn_s_mp_sqr.c +++ b/bn_s_mp_sqr.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bn_s_mp_sub.c b/bn_s_mp_sub.c index 32a01d9..4381af8 100644 --- a/bn_s_mp_sub.c +++ b/bn_s_mp_sub.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/bncore.c b/bncore.c index 8ca206a..acb78a0 100644 --- a/bncore.c +++ b/bncore.c @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/changes.txt b/changes.txt index 8508424..fbbd0a2 100644 --- a/changes.txt +++ b/changes.txt @@ -1,3 +1,16 @@ +Aug 4th, 2003 +v0.25 -- Fix to mp_gcd again... oops (0,-a) == (-a, 0) == a + -- Fix to mp_clear which didn't reset the sign [Greg Rose] + -- Added mp_error_to_string() to convert return codes to strings. [Greg Rose] + -- Optimized fast_mp_invmod() to do the test for invalid inputs [both even] + first so temps don't have to be initialized if it's going to fail. + -- Optimized mp_gcd() by removing mp_div_2d calls for when one of the inputs + is odd. + -- Tons of new comments, some indentation fixups, etc. + -- mp_jacobi() returns MP_VAL if the modulus is less than or equal to zero. + -- fixed two typos in the header of each file :-) + -- LibTomMath is officially Public Domain [see LICENSE] + July 15th, 2003 v0.24 -- Optimized mp_add_d and mp_sub_d to not allocate temporary variables -- Fixed mp_gcd() so the gcd of 0,0 is 0. Allows the gcd operation to be chained diff --git a/demo/demo.c b/demo/demo.c index 0691efb..7da356c 100644 --- a/demo/demo.c +++ b/demo/demo.c @@ -181,7 +181,6 @@ int main(void) #ifdef TIMER /* temp. turn off TOOM */ TOOM_MUL_CUTOFF = TOOM_SQR_CUTOFF = 100000; - printf("CLOCKS_PER_SEC == %lu\n", CLOCKS_PER_SEC); log = fopen("logs/add.log", "w"); @@ -225,21 +224,6 @@ int main(void) KARATSUBA_MUL_CUTOFF = (ix==0)?9999:old_kara_m; KARATSUBA_SQR_CUTOFF = (ix==0)?9999:old_kara_s; - log = fopen((ix==0)?"logs/sqr.log":"logs/sqr_kara.log", "w"); - for (cnt = 32; cnt <= 288; cnt += 16) { - mp_rand(&a, cnt); - reset(); - rr = 0; - do { - DO(mp_sqr(&a, &b)); - rr += 16; - } while (rdtsc() < (CLOCKS_PER_SEC * 2)); - tt = rdtsc(); - printf("Squaring\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt, tt); - fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt); - } - fclose(log); - log = fopen((ix==0)?"logs/mult.log":"logs/mult_kara.log", "w"); for (cnt = 32; cnt <= 288; cnt += 16) { mp_rand(&a, cnt); @@ -255,6 +239,22 @@ int main(void) fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt); } fclose(log); + + log = fopen((ix==0)?"logs/sqr.log":"logs/sqr_kara.log", "w"); + for (cnt = 32; cnt <= 288; cnt += 16) { + mp_rand(&a, cnt); + reset(); + rr = 0; + do { + DO(mp_sqr(&a, &b)); + rr += 16; + } while (rdtsc() < (CLOCKS_PER_SEC * 2)); + tt = rdtsc(); + printf("Squaring\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt, tt); + fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt); + } + fclose(log); + } { char *primes[] = { diff --git a/etc/2kprime.1 b/etc/2kprime.1 index e1384db..c41ded1 100644 --- a/etc/2kprime.1 +++ b/etc/2kprime.1 @@ -1 +1,2 @@ -259-bits (k = 17745) = 926336713898529563388567880069503262826159877325124512315660672063305037101743 +256-bits (k = 36113) = 115792089237316195423570985008687907853269984665640564039457584007913129603823 +512-bits (k = 38117) = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006045979 diff --git a/etc/pprime.c b/etc/pprime.c index 9360a09..389e1fa 100644 --- a/etc/pprime.c +++ b/etc/pprime.c @@ -59,7 +59,6 @@ static void gen_prime (void) r += 2; /* next candidate */ r &= MP_MASK; if (r < 31) break; - if (!((r>>1)&65535)) sleep(1); /* update sqrt ? */ if (next <= r) { diff --git a/logs/mult.log b/logs/mult.log index 4b1bff3..e69de29 100644 --- a/logs/mult.log +++ b/logs/mult.log @@ -1,17 +0,0 @@ -896 322904 -1344 151592 -1792 90472 -2240 59984 -2688 42624 -3136 31872 -3584 24704 -4032 19704 -4480 16096 -4928 13376 -5376 11272 -5824 9616 -6272 8360 -6720 7304 -7168 1664 -7616 1472 -8064 1328 diff --git a/makefile b/makefile index c939c8b..9de5e56 100644 --- a/makefile +++ b/makefile @@ -1,9 +1,12 @@ #Makefile for GCC # #Tom St Denis -CFLAGS += -I./ -Wall -W -Wshadow -O3 -fomit-frame-pointer -funroll-loops +CFLAGS += -I./ -Wall -W -Wshadow -O3 -funroll-loops -VERSION=0.24 +#x86 optimizations [should be valid for any GCC install though] +CFLAGS += -fomit-frame-pointer + +VERSION=0.25 default: libtommath.a @@ -35,12 +38,13 @@ bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_un bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \ bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \ bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \ -bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o bn_mp_multi.o \ +bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \ bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \ bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \ bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \ bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \ -bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o +bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \ +bn_mp_init_multi.o bn_mp_clear_multi.o libtommath.a: $(OBJECTS) $(AR) $(ARFLAGS) libtommath.a $(OBJECTS) @@ -106,6 +110,6 @@ clean: zipup: clean manual poster perl gen.pl ; mv mpi.c pre_gen/ ; \ cd .. ; rm -rf ltm* libtommath-$(VERSION) ; mkdir libtommath-$(VERSION) ; \ - cp -R ./libtommath/* ./libtommath-$(VERSION)/ ; cp tdcal.pdf ./libtommath-$(VERSION)/ ; cd ./libtommath-$(VERSION) ; rm -f tommath.src tommath.tex tommath.out ; cd pics ; rm -f *.tif *.ps *.pdf ; cd .. ; cd .. ; ls ; \ + cp -R ./libtommath/* ./libtommath-$(VERSION)/ ; cd ./libtommath-$(VERSION) ; rm -f tommath.src tommath.tex tommath.out ; cd pics ; rm -f *.tif *.ps *.pdf ; cd .. ; cd .. ; ls ; \ tar -c libtommath-$(VERSION)/* > ltm-$(VERSION).tar ; \ bzip2 -9vv ltm-$(VERSION).tar ; zip -9 -r ltm-$(VERSION).zip libtommath-$(VERSION)/* diff --git a/makefile.bcc b/makefile.bcc index b227e8d..2a6b0b5 100644 --- a/makefile.bcc +++ b/makefile.bcc @@ -23,17 +23,18 @@ bn_mp_count_bits.obj bn_mp_read_unsigned_bin.obj bn_mp_read_signed_bin.obj bn_mp bn_mp_to_signed_bin.obj bn_mp_unsigned_bin_size.obj bn_mp_signed_bin_size.obj \ bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj \ bn_mp_prime_is_divisible.obj bn_prime_tab.obj bn_mp_prime_fermat.obj bn_mp_prime_miller_rabin.obj \ -bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj bn_mp_multi.obj \ +bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj \ bn_mp_dr_is_modulus.obj bn_mp_dr_setup.obj bn_mp_reduce_setup.obj \ bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \ bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \ bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \ -bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj +bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \ +bn_mp_init_multi.obj bn_mp_clear_multi.obj TARGET = libtommath.lib $(TARGET): $(OBJECTS) -.c.obj: +.c.objbj: $(CC) $(CFLAGS) $< - $(LIB) $(TARGET) -+$@ \ No newline at end of file + $(LIB) $(TARGET) -+$@ diff --git a/makefile.msvc b/makefile.msvc index 0af7c89..df655dd 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -22,12 +22,13 @@ bn_mp_count_bits.obj bn_mp_read_unsigned_bin.obj bn_mp_read_signed_bin.obj bn_mp bn_mp_to_signed_bin.obj bn_mp_unsigned_bin_size.obj bn_mp_signed_bin_size.obj \ bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj \ bn_mp_prime_is_divisible.obj bn_prime_tab.obj bn_mp_prime_fermat.obj bn_mp_prime_miller_rabin.obj \ -bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj bn_mp_multi.obj \ +bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj \ bn_mp_dr_is_modulus.obj bn_mp_dr_setup.obj bn_mp_reduce_setup.obj \ bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \ bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \ bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \ -bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj +bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \ +bn_mp_init_multi.obj bn_mp_clear_multi.obj library: $(OBJECTS) lib /out:tommath.lib $(OBJECTS) diff --git a/pics/design_process.sxd b/pics/design_process.sxd new file mode 100644 index 0000000..7414dbb Binary files /dev/null and b/pics/design_process.sxd differ diff --git a/pics/makefile b/pics/makefile index 07bbca9..18c3d44 100644 --- a/pics/makefile +++ b/pics/makefile @@ -1,30 +1,35 @@ -# makes the images... yeah - -default: pses - - -sliding_window.ps: sliding_window.tif - tiff2ps -c -e sliding_window.tif > sliding_window.ps - -expt_state.ps: expt_state.tif - tiff2ps -c -e expt_state.tif > expt_state.ps - -primality.ps: primality.tif - tiff2ps -c -e primality.tif > primality.ps - -sliding_window.pdf: sliding_window.ps - epstopdf sliding_window.ps - -expt_state.pdf: expt_state.ps - epstopdf expt_state.ps - -primality.pdf: primality.ps - epstopdf primality.ps - - -pses: sliding_window.ps expt_state.ps primality.ps -pdfes: sliding_window.pdf expt_state.pdf primality.pdf - -clean: - rm -rf *.ps *.pdf .xvpics +# makes the images... yeah + +default: pses + +design_process.ps: design_process.tif + tiff2ps -c -e design_process.tif > design_process.ps + +sliding_window.ps: sliding_window.tif + tiff2ps -c -e sliding_window.tif > sliding_window.ps + +expt_state.ps: expt_state.tif + tiff2ps -c -e expt_state.tif > expt_state.ps + +primality.ps: primality.tif + tiff2ps -c -e primality.tif > primality.ps + +design_process.pdf: design_process.ps + epstopdf design_process.ps + +sliding_window.pdf: sliding_window.ps + epstopdf sliding_window.ps + +expt_state.pdf: expt_state.ps + epstopdf expt_state.ps + +primality.pdf: primality.ps + epstopdf primality.ps + + +pses: sliding_window.ps expt_state.ps primality.ps design_process.ps +pdfes: sliding_window.pdf expt_state.pdf primality.pdf design_process.pdf + +clean: + rm -rf *.ps *.pdf .xvpics \ No newline at end of file diff --git a/poster.pdf b/poster.pdf index 1b6ce6e..1d25593 100644 Binary files a/poster.pdf and b/poster.pdf differ diff --git a/pre_gen/mpi.c b/pre_gen/mpi.c index 2f7a853..4e748f8 100644 --- a/pre_gen/mpi.c +++ b/pre_gen/mpi.c @@ -1,10 +1,55 @@ +/* Start: 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +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"; +} + + +/* End: bn_error.c */ + /* Start: bn_fast_mp_invmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -27,6 +72,14 @@ 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] if a,b are both even then return an error! + * + * That is if gcd(a,b) = 2**k * q then obviously there is no inverse. + */ + if (mp_iseven (a) == 1 && 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; @@ -42,15 +95,6 @@ fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c) goto __ERR; } - /* 2. [modified] if x,y are both even then return an error! - * - * That is if gcd(x,y) = 2 * k then obviously there is no inverse. - */ - if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) { - res = MP_VAL; - goto __ERR; - } - /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ if ((res = mp_copy (&x, &u)) != MP_OKAY) { goto __ERR; @@ -152,10 +196,10 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL); /* Start: bn_fast_mp_montgomery_reduce.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -190,6 +234,9 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } } + /* 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; @@ -208,6 +255,9 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } } + /* now we proceed to zero successive digits + * from the least significant upwards + */ for (ix = 0; ix < n->used; ix++) { /* mu = ai * m' mod b * @@ -253,12 +303,20 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) 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++) { @@ -271,7 +329,11 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) * 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++) { @@ -279,7 +341,8 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) } /* zero oldused digits, if the input a was larger than - * m->used+1 we'll have to clear the digits */ + * m->used+1 we'll have to clear the digits + */ for (; ix < olduse; ix++) { *tmpx++ = 0; } @@ -301,10 +364,10 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* Start: bn_fast_s_mp_mul_digs.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -435,10 +498,10 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) /* Start: bn_fast_s_mp_mul_high_digs.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -447,7 +510,7 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) * * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org */ -#include + #include /* this is a modified version of fast_s_mp_mul_digs that only produces * output digits *above* digs. See the comments for fast_s_mp_mul_digs @@ -537,10 +600,10 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) /* Start: bn_fast_s_mp_sqr.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -585,14 +648,14 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) /* zero temp buffer (columns) * Note that there are two buffers. Since squaring requires - * a outter and inner product and the inner product requires + * a outer and inner product and the inner product requires * computing a product and doubling it (a relatively expensive * op to perform n**2 times if you don't have to) the inner and * outer products are computed in different buffers. This way * the inner product can be doubled using n doublings instead of * n**2 */ - memset (W, 0, newused * sizeof (mp_word)); + memset (W, 0, newused * sizeof (mp_word)); memset (W2, 0, newused * sizeof (mp_word)); /* This computes the inner product. To simplify the inner N**2 loop @@ -604,6 +667,7 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) * Note that every outer product is computed * for a particular column only once which means that * there is no need todo a double precision addition + * into the W2[] array. */ W2[ix + ix] = ((mp_word)a->dp[ix]) * ((mp_word)a->dp[ix]); @@ -632,7 +696,12 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) olduse = b->used; b->used = newused; - /* now compute digits */ + /* now compute digits + * + * We have to double the inner product sums, add in the + * outer product sums, propagate carries and convert + * to single precision. + */ { register mp_digit *tmpb; @@ -646,16 +715,21 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) /* double/add next digit */ W[ix] += W[ix] + W2[ix]; + /* propagate carry forwards [from the previous digit] */ W[ix] = W[ix] + (W[ix - 1] >> ((mp_word) DIGIT_BIT)); + + /* store the current digit now that the carry isn't + * needed + */ *tmpb++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK)); } - /* set the last value. Note even if the carry is zero - * this is required since the next step will not zero + /* set the last value. Note even if the carry is zero + * this is required since the next step will not zero * it if b originally had a value at b->dp[2*a.used] */ *tmpb++ = (mp_digit) (W[(newused) - 1] & ((mp_word) MP_MASK)); - /* clear high digits */ + /* clear high digits of b if there were any originally */ for (; ix < olduse; ix++) { *tmpb++ = 0; } @@ -670,10 +744,10 @@ fast_s_mp_sqr (mp_int * a, mp_int * b) /* Start: bn_mp_2expt.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -694,11 +768,18 @@ mp_2expt (mp_int * a, int b) { int res; + /* zero a as per default */ mp_zero (a); + + /* grow a to accomodate the single bit */ if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) { return res; } + + /* set the used count of where the bit will go */ a->used = b / DIGIT_BIT + 1; + + /* put the single bit in its place */ a->dp[b / DIGIT_BIT] = 1 << (b % DIGIT_BIT); return MP_OKAY; @@ -709,10 +790,10 @@ mp_2expt (mp_int * a, int b) /* Start: bn_mp_abs.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -731,10 +812,17 @@ int mp_abs (mp_int * a, mp_int * b) { int res; - if ((res = mp_copy (a, b)) != MP_OKAY) { - return res; + + /* copy a to b */ + if (a != b) { + if ((res = mp_copy (a, b)) != MP_OKAY) { + return res; + } } + + /* force the sign of b to positive */ b->sign = MP_ZPOS; + return MP_OKAY; } @@ -743,10 +831,10 @@ mp_abs (mp_int * a, mp_int * b) /* Start: bn_mp_add.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -795,10 +883,10 @@ mp_add (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_add_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -877,7 +965,11 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c) c->used = 1; /* the result is a single digit */ - *tmpc++ = b - a->dp[0]; + if (a->used == 1) { + *tmpc++ = b - a->dp[0]; + } else { + *tmpc++ = b; + } /* setup count so the clearing of oldused * can fall through correctly @@ -900,10 +992,10 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c) /* Start: bn_mp_addmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -939,10 +1031,10 @@ mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) /* Start: bn_mp_and.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -994,10 +1086,10 @@ mp_and (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_clamp.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1018,9 +1110,14 @@ mp_and (mp_int * a, mp_int * b, mp_int * c) void mp_clamp (mp_int * a) { + /* decrease used while the most significant digit is + * zero. + */ while (a->used > 0 && a->dp[a->used - 1] == 0) { --(a->used); } + + /* reset the sign flag if used == 0 */ if (a->used == 0) { a->sign = MP_ZPOS; } @@ -1031,11 +1128,11 @@ mp_clamp (mp_int * a) /* Start: bn_mp_clear.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with + * 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 @@ -1049,6 +1146,7 @@ mp_clamp (mp_int * a) void mp_clear (mp_int * a) { + /* only do anything if a hasn't been freed previously */ if (a->dp != NULL) { /* first zero the digits */ memset (a->dp, 0, sizeof (mp_digit) * a->used); @@ -1059,18 +1157,51 @@ mp_clear (mp_int * a) /* reset members to make debugging easier */ a->dp = NULL; a->alloc = a->used = 0; + a->sign = MP_ZPOS; } } /* End: bn_mp_clear.c */ +/* Start: bn_mp_clear_multi.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@iahu.ca, http://math.libtomcrypt.org + */ +#include +#include + +void mp_clear_multi(mp_int *mp, ...) +{ + mp_int* next_mp = mp; + va_list args; + va_start(args, mp); + while (next_mp != NULL) { + mp_clear(next_mp); + next_mp = va_arg(args, mp_int*); + } + va_end(args); +} + +/* End: bn_mp_clear_multi.c */ + /* Start: bn_mp_cmp.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1108,10 +1239,10 @@ mp_cmp (mp_int * a, mp_int * b) /* Start: bn_mp_cmp_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1126,15 +1257,17 @@ mp_cmp (mp_int * a, mp_int * b) int mp_cmp_d (mp_int * a, mp_digit b) { - + /* compare based on sign */ if (a->sign == MP_NEG) { return MP_LT; } + /* compare based on magnitude */ if (a->used > 1) { return MP_GT; } + /* compare the only digit of a to b */ if (a->dp[0] > b) { return MP_GT; } else if (a->dp[0] < b) { @@ -1149,10 +1282,10 @@ mp_cmp_d (mp_int * a, mp_digit b) /* Start: bn_mp_cmp_mag.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1196,10 +1329,10 @@ mp_cmp_mag (mp_int * a, mp_int * b) /* Start: bn_mp_cnt_lsb.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1216,6 +1349,7 @@ int mp_cnt_lsb(mp_int *a) int x; mp_digit q; + /* easy out */ if (mp_iszero(a) == 1) { return 0; } @@ -1240,10 +1374,10 @@ int mp_cnt_lsb(mp_int *a) /* Start: bn_mp_copy.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1266,8 +1400,10 @@ mp_copy (mp_int * a, mp_int * b) } /* grow dest */ - if ((res = mp_grow (b, a->used)) != MP_OKAY) { - return res; + if (b->alloc < a->used) { + if ((res = mp_grow (b, a->used)) != MP_OKAY) { + return res; + } } /* zero b and copy the parameters over */ @@ -1275,7 +1411,11 @@ mp_copy (mp_int * a, mp_int * b) register mp_digit *tmpa, *tmpb; /* pointer aliases */ + + /* source */ tmpa = a->dp; + + /* destination */ tmpb = b->dp; /* copy all the digits */ @@ -1288,6 +1428,8 @@ mp_copy (mp_int * a, mp_int * b) *tmpb++ = 0; } } + + /* copy used count and sign */ b->used = a->used; b->sign = a->sign; return MP_OKAY; @@ -1298,10 +1440,10 @@ mp_copy (mp_int * a, mp_int * b) /* Start: bn_mp_count_bits.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1341,10 +1483,10 @@ mp_count_bits (mp_int * a) /* Start: bn_mp_div.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1556,10 +1698,10 @@ __Q:mp_clear (&q); /* Start: bn_mp_div_2.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1623,10 +1765,10 @@ mp_div_2 (mp_int * a, mp_int * b) /* Start: bn_mp_div_2d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1719,10 +1861,10 @@ mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) /* Start: bn_mp_div_3.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1754,10 +1896,17 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) w = 0; for (ix = a->used - 1; ix >= 0; ix--) { w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); - + if (w >= 3) { + /* multiply w by [1/3] */ t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT); + + /* now subtract 3 * [w/3] from w, to get the remainder */ w -= (t << ((mp_word)1)) + t; + + /* fixup the remainder as required since + * the optimization is not exact. + */ while (w >= 3) { t += 1; w -= 3; @@ -1767,11 +1916,13 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) } q.dp[ix] = (mp_digit)t; } - + + /* [optional] store the remainder */ if (d != NULL) { *d = (mp_digit)w; } - + + /* [optional] store the quotient */ if (c != NULL) { mp_clamp(&q); mp_exch(&q, c); @@ -1787,10 +1938,10 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) /* Start: bn_mp_div_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1892,50 +2043,53 @@ mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) /* End: bn_mp_div_d.c */ /* Start: bn_mp_dr_is_modulus.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* determines if a number is a valid DR modulus */ -int mp_dr_is_modulus(mp_int *a) -{ - int ix; - - /* must be at least two digits */ - if (a->used < 2) { - return 0; - } - - for (ix = 1; ix < a->used; ix++) { - if (a->dp[ix] != MP_MASK) { - return 0; - } - } - return 1; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines if a number is a valid DR modulus */ +int mp_dr_is_modulus(mp_int *a) +{ + int ix; + + /* must be at least two digits */ + if (a->used < 2) { + return 0; + } + + /* must be of the form b**k - a [a <= b] so all + * but the first digit must be equal to -1 (mod b). + */ + for (ix = 1; ix < a->used; ix++) { + if (a->dp[ix] != MP_MASK) { + return 0; + } + } + return 1; +} + /* End: bn_mp_dr_is_modulus.c */ /* Start: bn_mp_dr_reduce.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -1989,7 +2143,7 @@ top: /* set carry to zero */ mu = 0; - /* compute (x mod B**m) + mp * [x/B**m] inline and inplace */ + /* compute (x mod B**m) + k * [x/B**m] inline and inplace */ for (i = 0; i < m; i++) { r = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu; *tmpx1++ = (mp_digit)(r & MP_MASK); @@ -2020,42 +2174,42 @@ top: /* End: bn_mp_dr_reduce.c */ /* Start: bn_mp_dr_setup.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* determines the setup value */ -void mp_dr_setup(mp_int *a, mp_digit *d) -{ - /* the casts are required if DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] - */ - *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - - ((mp_word)a->dp[0])); -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines the setup value */ +void mp_dr_setup(mp_int *a, mp_digit *d) +{ + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] + */ + *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - + ((mp_word)a->dp[0])); +} + /* End: bn_mp_dr_setup.c */ /* Start: bn_mp_exch.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2074,7 +2228,7 @@ mp_exch (mp_int * a, mp_int * b) { mp_int t; - t = *a; + t = *a; *a = *b; *b = t; } @@ -2084,10 +2238,10 @@ mp_exch (mp_int * a, mp_int * b) /* Start: bn_mp_expt_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2140,10 +2294,10 @@ mp_expt_d (mp_int * a, mp_digit b, mp_int * c) /* Start: bn_mp_exptmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2200,7 +2354,10 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) return err; } + /* is it a DR modulus? */ dr = mp_dr_is_modulus(P); + + /* if not, is it a uDR modulus? */ if (dr == 0) { dr = mp_reduce_is_2k(P) << 1; } @@ -2209,6 +2366,7 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) if (mp_isodd (P) == 1 || dr != 0) { return mp_exptmod_fast (G, X, P, Y, dr); } else { + /* otherwise use the generic Barrett reduction technique */ return s_mp_exptmod (G, X, P, Y); } } @@ -2219,10 +2377,10 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) /* Start: bn_mp_exptmod_fast.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2313,15 +2471,15 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { redux = fast_mp_montgomery_reduce; } else { - /* use slower baselien method */ + /* use slower baseline Montgomery method */ redux = mp_montgomery_reduce; } } else if (redmode == 1) { - /* setup DR reduction */ + /* setup DR reduction for moduli of the form B**k - b */ mp_dr_setup(P, &mp); redux = mp_dr_reduce; } else { - /* setup 2k reduction */ + /* setup DR reduction for moduli of the form 2**k - b */ if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) { goto __M; } @@ -2330,7 +2488,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* setup result */ if ((err = mp_init (&res)) != MP_OKAY) { - goto __RES; + goto __M; } /* create M table @@ -2392,15 +2550,17 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) for (;;) { /* grab next digit as required */ if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits so break */ if (digidx == -1) { break; } - buf = X->dp[digidx--]; - bitcnt = (int) DIGIT_BIT; + /* read next digit and reset bitcnt */ + buf = X->dp[digidx--]; + bitcnt = (int)DIGIT_BIT; } /* grab the next msb from the exponent */ - y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; buf <<= (mp_digit)1; /* if the bit is zero and mode == 0 then we ignore it @@ -2425,7 +2585,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* else we add it to the window */ bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; + mode = 2; if (bitcpy == winsize) { /* ok window is filled so square as required and multiply */ @@ -2450,7 +2610,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) /* empty window and reset */ bitcpy = 0; bitbuf = 0; - mode = 1; + mode = 1; } } @@ -2465,6 +2625,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) goto __RES; } + /* get next bit of the window */ bitbuf <<= 1; if ((bitbuf & (1 << winsize)) != 0) { /* then multiply */ @@ -2479,12 +2640,18 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) } if (redmode == 0) { - /* fixup result if Montgomery reduction is used */ + /* fixup result if Montgomery reduction is used + * recall that any value in a Montgomery system is + * actually multiplied by R mod n. So we have + * to reduce one more time to cancel out the factor + * of R. + */ if ((err = mp_montgomery_reduce (&res, P, mp)) != MP_OKAY) { goto __RES; } } + /* swap res with Y */ mp_exch (&res, Y); err = MP_OKAY; __RES:mp_clear (&res); @@ -2499,77 +2666,77 @@ __M: /* End: bn_mp_exptmod_fast.c */ /* Start: bn_mp_fread.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* read a bigint from a file stream in ASCII */ -int mp_fread(mp_int *a, int radix, FILE *stream) -{ - int err, ch, neg, y; - - /* clear a */ - mp_zero(a); - - /* if first digit is - then set negative */ - ch = fgetc(stream); - if (ch == '-') { - neg = MP_NEG; - ch = fgetc(stream); - } else { - neg = MP_ZPOS; - } - - for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } - } - if (y == radix) { - break; - } - - /* shift up and add */ - if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { - return err; - } - if ((err = mp_add_d(a, y, a)) != MP_OKAY) { - return err; - } - - ch = fgetc(stream); - } - if (mp_cmp_d(a, 0) != MP_EQ) { - a->sign = neg; - } - - return MP_OKAY; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* read a bigint from a file stream in ASCII */ +int mp_fread(mp_int *a, int radix, FILE *stream) +{ + int err, ch, neg, y; + + /* clear a */ + mp_zero(a); + + /* if first digit is - then set negative */ + ch = fgetc(stream); + if (ch == '-') { + neg = MP_NEG; + ch = fgetc(stream); + } else { + neg = MP_ZPOS; + } + + for (;;) { + /* find y in the radix map */ + for (y = 0; y < radix; y++) { + if (mp_s_rmap[y] == ch) { + break; + } + } + if (y == radix) { + break; + } + + /* shift up and add */ + if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) { + return err; + } + if ((err = mp_add_d(a, y, a)) != MP_OKAY) { + return err; + } + + ch = fgetc(stream); + } + if (mp_cmp_d(a, 0) != MP_EQ) { + a->sign = neg; + } + + return MP_OKAY; +} + /* End: bn_mp_fread.c */ /* Start: bn_mp_fwrite.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2617,10 +2784,10 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream) /* Start: bn_mp_gcd.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2640,16 +2807,21 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) /* either zero than gcd is the largest */ if (mp_iszero (a) == 1 && mp_iszero (b) == 0) { - return mp_copy (b, c); + return mp_abs (b, c); } if (mp_iszero (a) == 0 && mp_iszero (b) == 1) { - return mp_copy (a, c); + return mp_abs (a, c); } - if (mp_iszero (a) == 1 && mp_iszero (b) == 1) { + + /* optimized. At this point if a == 0 then + * b must equal zero too + */ + if (mp_iszero (a) == 1) { mp_zero(c); return MP_OKAY; } + /* get copies of a and b we can modify */ if ((res = mp_init_copy (&u, a)) != MP_OKAY) { return res; } @@ -2666,12 +2838,15 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) v_lsb = mp_cnt_lsb(&v); k = MIN(u_lsb, v_lsb); - if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { - goto __V; - } + if (k > 0) { + /* divide the power of two out */ + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + goto __V; + } - if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { - goto __V; + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + goto __V; + } } /* divide any remaining factors of two out */ @@ -2686,10 +2861,11 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) goto __V; } } - + while (mp_iszero(&v) == 0) { /* make sure v is the largest */ if (mp_cmp_mag(&u, &v) == MP_GT) { + /* swap u and v to make sure v is >= u */ mp_exch(&u, &v); } @@ -2703,10 +2879,10 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c) goto __V; } } - - /* multiply by 2**k which we divided out at the beginning */ + + /* multiply by 2**k which we divided out at the beginning */ if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) { - goto __V; + goto __V; } c->sign = MP_ZPOS; res = MP_OKAY; @@ -2720,10 +2896,10 @@ __U:mp_clear (&v); /* Start: bn_mp_grow.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2743,7 +2919,7 @@ mp_grow (mp_int * a, int size) /* if the alloc size is smaller alloc more ram */ if (a->alloc < size) { /* ensure there are always at least MP_PREC digits extra on top */ - size += (MP_PREC * 2) - (size & (MP_PREC - 1)); + size += (MP_PREC * 2) - (size % MP_PREC); a->dp = OPT_CAST realloc (a->dp, sizeof (mp_digit) * size); if (a->dp == NULL) { @@ -2765,11 +2941,11 @@ mp_grow (mp_int * a, int size) /* Start: bn_mp_init.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with + * 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 @@ -2783,7 +2959,7 @@ mp_grow (mp_int * a, int size) int mp_init (mp_int * a) { - /* allocate ram required and clear it */ + /* allocate memory required and clear it */ a->dp = OPT_CAST calloc (sizeof (mp_digit), MP_PREC); if (a->dp == NULL) { return MP_MEM; @@ -2803,10 +2979,10 @@ mp_init (mp_int * a) /* Start: bn_mp_init_copy.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2831,13 +3007,68 @@ mp_init_copy (mp_int * a, mp_int * b) /* End: bn_mp_init_copy.c */ +/* Start: bn_mp_init_multi.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@iahu.ca, http://math.libtomcrypt.org + */ +#include +#include + +int mp_init_multi(mp_int *mp, ...) +{ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ + int n = 0; /* Number of ok inits */ + mp_int* cur_arg = mp; + va_list args; + + va_start(args, mp); /* init args to next argument from caller */ + while (cur_arg != NULL) { + if (mp_init(cur_arg) != MP_OKAY) { + /* Oops - error! Back-track and mp_clear what we already + succeeded in init-ing, then return error. + */ + va_list clean_args; + + /* end the current list */ + va_end(args); + + /* now start cleaning up */ + cur_arg = mp; + va_start(clean_args, mp); + while (n--) { + mp_clear(cur_arg); + cur_arg = va_arg(clean_args, mp_int*); + } + va_end(clean_args); + res = MP_MEM; + break; + } + n++; + cur_arg = va_arg(args, mp_int*); + } + va_end(args); + return res; /* Assumed ok, if error flagged above. */ +} +/* End: bn_mp_init_multi.c */ + /* Start: bn_mp_init_size.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -2848,22 +3079,21 @@ mp_init_copy (mp_int * a, mp_int * b) */ #include -/* init a mp_init and grow it to a given size */ +/* init an mp_init for a given size */ int mp_init_size (mp_int * a, int size) { - /* pad size so there are always extra digits */ - size += (MP_PREC * 2) - (size & (MP_PREC - 1)); + size += (MP_PREC * 2) - (size % MP_PREC); /* alloc mem */ a->dp = OPT_CAST calloc (sizeof (mp_digit), size); if (a->dp == NULL) { return MP_MEM; } - a->used = 0; + a->used = 0; a->alloc = size; - a->sign = MP_ZPOS; + a->sign = MP_ZPOS; return MP_OKAY; } @@ -2873,10 +3103,10 @@ mp_init_size (mp_int * a, int size) /* Start: bn_mp_invmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3052,10 +3282,10 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL); /* Start: bn_mp_jacobi.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3076,6 +3306,11 @@ mp_jacobi (mp_int * a, mp_int * p, int *c) int k, s, r, res; mp_digit residue; + /* if p <= 0 return MP_VAL */ + if (mp_cmp_d(p, 0) != MP_GT) { + return MP_VAL; + } + /* step 1. if a == 0, return 0 */ if (mp_iszero (a) == 1) { *c = 0; @@ -3089,7 +3324,7 @@ mp_jacobi (mp_int * a, mp_int * p, int *c) } /* default */ - k = s = 0; + s = 0; /* step 3. write a = a1 * 2**k */ if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { @@ -3100,11 +3335,10 @@ mp_jacobi (mp_int * a, mp_int * p, int *c) goto __A1; } - while (mp_iseven (&a1) == 1) { - k = k + 1; - if ((res = mp_div_2 (&a1, &a1)) != MP_OKAY) { - goto __P1; - } + /* divide out larger power of two */ + k = mp_cnt_lsb(&a1); + if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { + goto __P1; } /* step 4. if e is even set s=1 */ @@ -3152,10 +3386,10 @@ __A1:mp_clear (&a1); /* Start: bn_mp_karatsuba_mul.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3321,10 +3555,10 @@ ERR: /* Start: bn_mp_karatsuba_sqr.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3441,10 +3675,10 @@ ERR: /* Start: bn_mp_lcm.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3487,10 +3721,10 @@ mp_lcm (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_lshd.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3553,10 +3787,10 @@ mp_lshd (mp_int * a, int b) /* Start: bn_mp_mod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3600,10 +3834,10 @@ mp_mod (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_mod_2d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3620,7 +3854,6 @@ mp_mod_2d (mp_int * a, int b, mp_int * c) { int x, res; - /* if b is <= 0 then zero the int */ if (b <= 0) { mp_zero (c); @@ -3654,10 +3887,10 @@ mp_mod_2d (mp_int * a, int b, mp_int * c) /* Start: bn_mp_mod_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3679,10 +3912,10 @@ mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) /* Start: bn_mp_montgomery_calc_normalization.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3736,10 +3969,10 @@ mp_montgomery_calc_normalization (mp_int * a, mp_int * b) /* Start: bn_mp_montgomery_reduce.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3828,10 +4061,10 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho) /* Start: bn_mp_montgomery_setup.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3885,10 +4118,10 @@ mp_montgomery_setup (mp_int * n, mp_digit * rho) /* Start: bn_mp_mul.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3905,13 +4138,14 @@ mp_mul (mp_int * a, mp_int * b, mp_int * c) { int res, neg; neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; - + + /* use Toom-Cook? */ if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) { res = mp_toom_mul(a, b, c); + /* use Karatsuba? */ } else if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { res = mp_karatsuba_mul (a, b, c); } else { - /* can we use the fast multiplier? * * The fast multiplier can be used if the output will @@ -3938,10 +4172,10 @@ mp_mul (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_mul_2.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -3999,7 +4233,7 @@ mp_mul_2 (mp_int * a, mp_int * b) if (r != 0) { /* add a MSB which is always 1 at this point */ *tmpb = 1; - ++b->used; + ++(b->used); } /* now zero any excess digits on the destination @@ -4019,10 +4253,10 @@ mp_mul_2 (mp_int * a, mp_int * b) /* Start: bn_mp_mul_2d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4091,7 +4325,7 @@ mp_mul_2d (mp_int * a, int b, mp_int * c) /* set final carry */ if (r != 0) { - c->dp[c->used++] = r; + c->dp[(c->used)++] = r; } } mp_clamp (c); @@ -4103,10 +4337,10 @@ mp_mul_2d (mp_int * a, int b, mp_int * c) /* Start: bn_mp_mul_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4179,10 +4413,10 @@ mp_mul_d (mp_int * a, mp_digit b, mp_int * c) /* Start: bn_mp_mulmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4216,81 +4450,13 @@ mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) /* End: bn_mp_mulmod.c */ -/* Start: bn_mp_multi.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include -#include - -int mp_init_multi(mp_int *mp, ...) -{ - mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ - int n = 0; /* Number of ok inits */ - mp_int* cur_arg = mp; - va_list args; - - va_start(args, mp); /* init args to next argument from caller */ - while (cur_arg != NULL) { - if (mp_init(cur_arg) != MP_OKAY) { - /* Oops - error! Back-track and mp_clear what we already - succeeded in init-ing, then return error. - */ - va_list clean_args; - - /* end the current list */ - va_end(args); - - /* now start cleaning up */ - cur_arg = mp; - va_start(clean_args, mp); - while (n--) { - mp_clear(cur_arg); - cur_arg = va_arg(clean_args, mp_int*); - } - va_end(clean_args); - res = MP_MEM; - break; - } - n++; - cur_arg = va_arg(args, mp_int*); - } - va_end(args); - return res; /* Assumed ok, if error flagged above. */ -} - -void mp_clear_multi(mp_int *mp, ...) -{ - mp_int* next_mp = mp; - va_list args; - va_start(args, mp); - while (next_mp != NULL) { - mp_clear(next_mp); - next_mp = va_arg(args, mp_int*); - } - va_end(args); -} - -/* End: bn_mp_multi.c */ - /* Start: bn_mp_n_root.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4335,7 +4501,7 @@ mp_n_root (mp_int * a, mp_digit b, mp_int * c) } /* if a is negative fudge the sign but keep track */ - neg = a->sign; + neg = a->sign; a->sign = MP_ZPOS; /* t2 = 2 */ @@ -4418,10 +4584,10 @@ __T1:mp_clear (&t1); /* Start: bn_mp_neg.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4449,10 +4615,10 @@ mp_neg (mp_int * a, mp_int * b) /* Start: bn_mp_or.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4498,10 +4664,10 @@ mp_or (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_prime_fermat.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4526,7 +4692,7 @@ mp_prime_fermat (mp_int * a, mp_int * b, int *result) mp_int t; int err; - /* default to fail */ + /* default to composite */ *result = 0; /* ensure b > 1 */ @@ -4559,10 +4725,10 @@ __T:mp_clear (&t); /* Start: bn_mp_prime_is_divisible.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4608,10 +4774,10 @@ mp_prime_is_divisible (mp_int * a, int *result) /* Start: bn_mp_prime_is_prime.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4690,10 +4856,10 @@ __B:mp_clear (&b); /* Start: bn_mp_prime_miller_rabin.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4792,10 +4958,10 @@ __N1:mp_clear (&n1); /* Start: bn_mp_prime_next_prime.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -4823,9 +4989,7 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) } /* force positive */ - if (a->sign == MP_NEG) { - a->sign = MP_ZPOS; - } + a->sign = MP_ZPOS; /* simple algo if a is less than the largest prime in the table */ if (mp_cmp_d(a, __prime_tab[PRIME_SIZE-1]) == MP_LT) { @@ -4929,8 +5093,8 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style) goto __ERR; } - /* if step == MAX then skip test */ - if (step >= ((((mp_digit)1)<= ((((mp_digit)1)< - -/* returns size of ASCII reprensentation */ -int -mp_radix_size (mp_int * a, int radix) -{ - int res, digs; - mp_int t; - mp_digit d; - - /* special case for binary */ - if (radix == 2) { - return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; - } - - if (radix < 2 || radix > 64) { - return 0; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return 0; - } - - digs = 0; - if (t.sign == MP_NEG) { - ++digs; - t.sign = MP_ZPOS; - } - - while (mp_iszero (&t) == 0) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return 0; - } - ++digs; - } - mp_clear (&t); - return digs + 1; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* returns size of ASCII reprensentation */ +int +mp_radix_size (mp_int * a, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + + /* special case for binary */ + if (radix == 2) { + return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; + } + + if (radix < 2 || radix > 64) { + return 0; + } + + if ((res = mp_init_copy (&t, a)) != MP_OKAY) { + return 0; + } + + digs = 0; + if (t.sign == MP_NEG) { + ++digs; + t.sign = MP_ZPOS; + } + + while (mp_iszero (&t) == 0) { + if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { + mp_clear (&t); + return 0; + } + ++digs; + } + mp_clear (&t); + return digs + 1; +} + /* End: bn_mp_radix_size.c */ /* Start: bn_mp_radix_smap.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* chars used in radix conversions */ -const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* chars used in radix conversions */ +const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; /* End: bn_mp_radix_smap.c */ /* Start: bn_mp_rand.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5093,93 +5257,93 @@ mp_rand (mp_int * a, int digits) /* End: bn_mp_rand.c */ /* Start: bn_mp_read_radix.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* read a string [ASCII] in a given radix */ -int -mp_read_radix (mp_int * a, char *str, int radix) -{ - int y, res, neg; - char ch; - - /* make sure the radix is ok */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = MP_NEG; - } else { - neg = MP_ZPOS; - } - - /* set the integer to the default of zero */ - mp_zero (a); - - /* process each digit of the string */ - while (*str) { - /* if the radix < 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (char) ((radix < 36) ? toupper (*str) : *str); - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } - } - - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { - return res; - } - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (mp_iszero(a) != 1) { - a->sign = neg; - } - return MP_OKAY; -} +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* read a string [ASCII] in a given radix */ +int +mp_read_radix (mp_int * a, char *str, int radix) +{ + int y, res, neg; + char ch; + + /* make sure the radix is ok */ + if (radix < 2 || radix > 64) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero (a); + + /* process each digit of the string */ + while (*str) { + /* if the radix < 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (char) ((radix < 36) ? toupper (*str) : *str); + for (y = 0; y < 64; y++) { + if (ch == mp_s_rmap[y]) { + break; + } + } + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if (y < radix) { + if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { + return res; + } + } else { + break; + } + ++str; + } + + /* set the sign only if a != 0 */ + if (mp_iszero(a) != 1) { + a->sign = neg; + } + return MP_OKAY; +} /* End: bn_mp_read_radix.c */ /* Start: bn_mp_read_signed_bin.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5208,10 +5372,10 @@ mp_read_signed_bin (mp_int * a, unsigned char *b, int c) /* Start: bn_mp_read_unsigned_bin.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5251,10 +5415,10 @@ mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c) /* Start: bn_mp_reduce.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5337,193 +5501,193 @@ CLEANUP: /* End: bn_mp_reduce.c */ /* Start: bn_mp_reduce_2k.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* reduces a modulo n where n is of the form 2**p - k */ -int -mp_reduce_2k(mp_int *a, mp_int *n, mp_digit k) -{ - mp_int q; - int p, res; - - if ((res = mp_init(&q)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(n); -top: - /* q = a/2**p, a = a mod 2**p */ - if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (k != 1) { - /* q = q * k */ - if ((res = mp_mul_d(&q, k, &q)) != MP_OKAY) { - goto ERR; - } - } - - /* a = a + q */ - if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { - goto ERR; - } - - if (mp_cmp_mag(a, n) != MP_LT) { - s_mp_sub(a, n, a); - goto top; - } - -ERR: - mp_clear(&q); - return res; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* reduces a modulo n where n is of the form 2**p - k */ +int +mp_reduce_2k(mp_int *a, mp_int *n, mp_digit k) +{ + mp_int q; + int p, res; + + if ((res = mp_init(&q)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(n); +top: + /* q = a/2**p, a = a mod 2**p */ + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (k != 1) { + /* q = q * k */ + if ((res = mp_mul_d(&q, k, &q)) != MP_OKAY) { + goto ERR; + } + } + + /* a = a + q */ + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { + goto ERR; + } + + if (mp_cmp_mag(a, n) != MP_LT) { + s_mp_sub(a, n, a); + goto top; + } + +ERR: + mp_clear(&q); + return res; +} + /* End: bn_mp_reduce_2k.c */ /* Start: bn_mp_reduce_2k_setup.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* determines the setup value */ -int -mp_reduce_2k_setup(mp_int *a, mp_digit *d) -{ - int res, p; - mp_int tmp; - - if ((res = mp_init(&tmp)) != MP_OKAY) { - return res; - } - - p = mp_count_bits(a); - if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { - mp_clear(&tmp); - return res; - } - - *d = tmp.dp[0]; - mp_clear(&tmp); - return MP_OKAY; -} +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines the setup value */ +int +mp_reduce_2k_setup(mp_int *a, mp_digit *d) +{ + int res, p; + mp_int tmp; + + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; + } + + p = mp_count_bits(a); + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + *d = tmp.dp[0]; + mp_clear(&tmp); + return MP_OKAY; +} /* End: bn_mp_reduce_2k_setup.c */ /* Start: bn_mp_reduce_is_2k.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* determines if mp_reduce_2k can be used */ -int -mp_reduce_is_2k(mp_int *a) -{ - int ix, iy; - - if (a->used == 0) { - return 0; - } else if (a->used == 1) { - return 1; - } else if (a->used > 1) { - iy = mp_count_bits(a); - for (ix = DIGIT_BIT; ix < iy; ix++) { - if ((a->dp[ix/DIGIT_BIT] & - ((mp_digit)1 << (mp_digit)(ix % DIGIT_BIT))) == 0) { - return 0; - } - } - } - return 1; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* determines if mp_reduce_2k can be used */ +int +mp_reduce_is_2k(mp_int *a) +{ + int ix, iy; + + if (a->used == 0) { + return 0; + } else if (a->used == 1) { + return 1; + } else if (a->used > 1) { + iy = mp_count_bits(a); + for (ix = DIGIT_BIT; ix < iy; ix++) { + if ((a->dp[ix/DIGIT_BIT] & + ((mp_digit)1 << (mp_digit)(ix % DIGIT_BIT))) == 0) { + return 0; + } + } + } + return 1; +} + /* End: bn_mp_reduce_is_2k.c */ /* Start: bn_mp_reduce_setup.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* pre-calculate the value required for Barrett reduction - * For a given modulus "b" it calulates the value required in "a" - */ -int -mp_reduce_setup (mp_int * a, mp_int * b) -{ - int res; - - if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { - return res; - } - return mp_div (a, b, a, NULL); -} +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* pre-calculate the value required for Barrett reduction + * For a given modulus "b" it calulates the value required in "a" + */ +int +mp_reduce_setup (mp_int * a, mp_int * b) +{ + int res; + + if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; + } + return mp_div (a, b, a, NULL); +} /* End: bn_mp_reduce_setup.c */ /* Start: bn_mp_rshd.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5591,10 +5755,10 @@ mp_rshd (mp_int * a, int b) /* Start: bn_mp_set.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5611,7 +5775,7 @@ mp_set (mp_int * a, mp_digit b) { mp_zero (a); a->dp[0] = b & MP_MASK; - a->used = (a->dp[0] != 0) ? 1 : 0; + a->used = (a->dp[0] != 0) ? 1 : 0; } /* End: bn_mp_set.c */ @@ -5619,10 +5783,10 @@ mp_set (mp_int * a, mp_digit b) /* Start: bn_mp_set_int.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5665,10 +5829,10 @@ mp_set_int (mp_int * a, unsigned int b) /* Start: bn_mp_shrink.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5697,10 +5861,10 @@ mp_shrink (mp_int * a) /* Start: bn_mp_signed_bin_size.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5723,10 +5887,10 @@ mp_signed_bin_size (mp_int * a) /* Start: bn_mp_sqr.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5742,13 +5906,14 @@ int mp_sqr (mp_int * a, mp_int * b) { int res; + /* use Toom-Cook? */ if (a->used >= TOOM_SQR_CUTOFF) { res = mp_toom_sqr(a, b); + /* Karatsuba? */ } else if (a->used >= KARATSUBA_SQR_CUTOFF) { res = mp_karatsuba_sqr (a, b); } else { - - /* can we use the fast multiplier? */ + /* can we use the fast comba multiplier? */ if ((a->used * 2 + 1) < MP_WARRAY && a->used < (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) { @@ -5766,10 +5931,10 @@ mp_sqr (mp_int * a, mp_int * b) /* Start: bn_mp_sqrmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5787,7 +5952,6 @@ mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) int res; mp_int t; - if ((res = mp_init (&t)) != MP_OKAY) { return res; } @@ -5806,10 +5970,10 @@ mp_sqrmod (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_sub.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5863,10 +6027,10 @@ mp_sub (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_sub_d.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5908,7 +6072,11 @@ mp_sub_d (mp_int * a, mp_digit b, mp_int * c) /* if a <= b simply fix the single digit */ if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) { - *tmpc++ = b - *tmpa; + if (a->used == 1) { + *tmpc++ = b - *tmpa; + } else { + *tmpc++ = b; + } ix = 1; /* negative/1digit */ @@ -5945,10 +6113,10 @@ mp_sub_d (mp_int * a, mp_digit b, mp_int * c) /* Start: bn_mp_submod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -5985,10 +6153,10 @@ mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d) /* Start: bn_mp_to_signed_bin.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -6017,10 +6185,10 @@ mp_to_signed_bin (mp_int * a, unsigned char *b) /* Start: bn_mp_to_unsigned_bin.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -6062,513 +6230,513 @@ mp_to_unsigned_bin (mp_int * a, unsigned char *b) /* End: bn_mp_to_unsigned_bin.c */ /* Start: bn_mp_toom_mul.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* multiplication using the Toom-Cook 3-way algorithm */ -int -mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) -{ - mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = MIN(a->used, b->used) / 3; - - /* a = a2 * B**2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* b = b2 * B**2 + b1 * B + b0 */ - if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(b, &b1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b1, B); - mp_mod_2d(&b1, DIGIT_BIT * B, &b1); - - if ((res = mp_copy(b, &b2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&b2, B*2); - - /* w0 = a0*b0 */ - if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * b2 */ - if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, - 2 small divisions and 1 small multiplication - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, - &a0, &a1, &a2, &b0, &b1, - &b2, &tmp1, &tmp2, NULL); - return res; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* multiplication using the Toom-Cook 3-way algorithm */ +int +mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = MIN(a->used, b->used) / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* b = b2 * B**2 + b1 * B + b0 */ + if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(b, &b1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b1, B); + mp_mod_2d(&b1, DIGIT_BIT * B, &b1); + + if ((res = mp_copy(b, &b2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&b2, B*2); + + /* w0 = a0*b0 */ + if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * b2 */ + if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, + 2 small divisions and 1 small multiplication + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL); + return res; +} + /* End: bn_mp_toom_mul.c */ /* Start: bn_mp_toom_sqr.c */ -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is library that provides for multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library is 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@iahu.ca, http://math.libtomcrypt.org - */ -#include - -/* squaring using Toom-Cook 3-way algorithm */ -int -mp_toom_sqr(mp_int *a, mp_int *b) -{ - mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; - int res, B; - - /* init temps */ - if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { - return res; - } - - /* B */ - B = a->used / 3; - - /* a = a2 * B^2 + a1 * B + a0 */ - if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_copy(a, &a1)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a1, B); - mp_mod_2d(&a1, DIGIT_BIT * B, &a1); - - if ((res = mp_copy(a, &a2)) != MP_OKAY) { - goto ERR; - } - mp_rshd(&a2, B*2); - - /* w0 = a0*a0 */ - if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { - goto ERR; - } - - /* w4 = a2 * a2 */ - if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { - goto ERR; - } - - /* w1 = (a2 + 2(a1 + 2a0))**2 */ - if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - - /* w3 = (a0 + 2(a1 + 2a2))**2 */ - if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - - - /* w2 = (a2 + a1 + a0)**2 */ - if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { - goto ERR; - } - - /* now solve the matrix - - 0 0 0 0 1 - 1 2 4 8 16 - 1 1 1 1 1 - 16 8 4 2 1 - 1 0 0 0 0 - - using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. - */ - - /* r1 - r4 */ - if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r0 */ - if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/2 */ - if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3/2 */ - if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { - goto ERR; - } - /* r2 - r0 - r4 */ - if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1 - 8r0 */ - if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - 8r4 */ - if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { - goto ERR; - } - /* 3r2 - r1 - r3 */ - if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { - goto ERR; - } - /* r1 - r2 */ - if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { - goto ERR; - } - /* r3 - r2 */ - if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { - goto ERR; - } - /* r1/3 */ - if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { - goto ERR; - } - /* r3/3 */ - if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { - goto ERR; - } - - /* at this point shift W[n] by B*n */ - if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { - goto ERR; - } - - if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { - goto ERR; - } - if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { - goto ERR; - } - -ERR: - mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); - return res; -} - +/* 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@iahu.ca, http://math.libtomcrypt.org + */ +#include + +/* squaring using Toom-Cook 3-way algorithm */ +int +mp_toom_sqr(mp_int *a, mp_int *b) +{ + mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = a->used / 3; + + /* a = a2 * B^2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a1, B); + mp_mod_2d(&a1, DIGIT_BIT * B, &a1); + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto ERR; + } + mp_rshd(&a2, B*2); + + /* w0 = a0*a0 */ + if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { + goto ERR; + } + + /* w4 = a2 * a2 */ + if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { + goto ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))**2 */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))**2 */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + + + /* w2 = (a2 + a1 + a0)**2 */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { + goto ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto ERR; + } + + if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto ERR; + } + if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { + goto ERR; + } + +ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); + return res; +} + /* End: bn_mp_toom_sqr.c */ /* Start: bn_mp_toradix.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -6639,10 +6807,10 @@ mp_toradix (mp_int * a, char *str, int radix) /* Start: bn_mp_unsigned_bin_size.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -6666,10 +6834,10 @@ mp_unsigned_bin_size (mp_int * a) /* Start: bn_mp_xor.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -6715,10 +6883,10 @@ mp_xor (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_mp_zero.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -6743,10 +6911,10 @@ mp_zero (mp_int * a) /* Start: bn_prime_tab.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -6802,10 +6970,10 @@ const mp_digit __prime_tab[] = { /* Start: bn_reverse.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -6839,10 +7007,10 @@ bn_reverse (unsigned char *s, int len) /* Start: bn_s_mp_add.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -6946,10 +7114,10 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c) /* Start: bn_s_mp_exptmod.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -7051,7 +7219,9 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) } } - /* create upper table */ + /* create upper table, that is M[x] = M[x-1] * M[1] (mod P) + * for x = (2**(winsize - 1) + 1) to (2**winsize - 1) + */ for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) { goto __MU; @@ -7078,15 +7248,17 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) for (;;) { /* grab next digit as required */ if (--bitcnt == 0) { + /* if digidx == -1 we are out of digits */ if (digidx == -1) { break; } - buf = X->dp[digidx--]; + /* read next digit and reset the bitcnt */ + buf = X->dp[digidx--]; bitcnt = (int) DIGIT_BIT; } /* grab the next msb from the exponent */ - y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; buf <<= (mp_digit)1; /* if the bit is zero and mode == 0 then we ignore it @@ -7094,8 +7266,9 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) * in the exponent. Technically this opt is not required but it * does lower the # of trivial squaring/reductions used */ - if (mode == 0 && y == 0) + if (mode == 0 && y == 0) { continue; + } /* if the bit is zero and mode == 1 then we square */ if (mode == 1 && y == 0) { @@ -7110,7 +7283,7 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) /* else we add it to the window */ bitbuf |= (y << (winsize - ++bitcpy)); - mode = 2; + mode = 2; if (bitcpy == winsize) { /* ok window is filled so square as required and multiply */ @@ -7135,7 +7308,7 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) /* empty window and reset */ bitcpy = 0; bitbuf = 0; - mode = 1; + mode = 1; } } @@ -7180,10 +7353,10 @@ __M: /* Start: bn_s_mp_mul_digs.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -7269,10 +7442,10 @@ s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) /* Start: bn_s_mp_mul_high_digs.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -7345,10 +7518,10 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs) /* Start: bn_s_mp_sqr.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -7426,10 +7599,10 @@ s_mp_sqr (mp_int * a, mp_int * b) /* Start: bn_s_mp_sub.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -7513,10 +7686,10 @@ s_mp_sub (mp_int * a, mp_int * b, mp_int * c) /* Start: bncore.c */ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * diff --git a/tdcal.pdf b/tdcal.pdf deleted file mode 100644 index e4f4b35..0000000 Binary files a/tdcal.pdf and /dev/null differ diff --git a/tommath.h b/tommath.h index e5e166b..f5c2ad1 100644 --- a/tommath.h +++ b/tommath.h @@ -1,9 +1,9 @@ /* LibTomMath, multiple-precision integer library -- Tom St Denis * - * LibTomMath is library that provides for multiple-precision + * LibTomMath is a library that provides multiple-precision * integer arithmetic as well as number theoretic functionality. * - * The library is designed directly after the MPI library by + * The library was designed directly after the MPI library by * Michael Fromberger but has been written from scratch with * additional optimizations in place. * @@ -82,8 +82,10 @@ extern "C" { typedef ulong64 mp_word; #ifdef MP_31BIT + /* this is an extension that uses 31-bit digits */ #define DIGIT_BIT 31 #else + /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ #define DIGIT_BIT 28 #define MP_28BIT #endif @@ -94,7 +96,6 @@ extern "C" { #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */ #endif - #define MP_DIGIT_BIT DIGIT_BIT #define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) #define MP_DIGIT_MAX MP_MASK @@ -121,7 +122,7 @@ extern int KARATSUBA_MUL_CUTOFF, TOOM_SQR_CUTOFF; /* various build options */ -#define MP_PREC 64 /* default digits of precision (must be power of two) */ +#define MP_PREC 64 /* default digits of precision */ /* define this to use lower memory usage routines (exptmods mostly) */ /* #define MP_LOW_MEM */ @@ -135,11 +136,13 @@ typedef struct { } mp_int; #define USED(m) ((m)->used) -#define DIGIT(m,k) ((m)->dp[k]) +#define DIGIT(m,k) ((m)->dp[(k)]) #define SIGN(m) ((m)->sign) -/* ---> init and deinit bignum functions <--- */ +/* error code to char* string */ +char *mp_error_to_string(int code); +/* ---> init and deinit bignum functions <--- */ /* init a bignum */ int mp_init(mp_int *a); @@ -165,7 +168,6 @@ int mp_grow(mp_int *a, int size); int mp_init_size(mp_int *a, int size); /* ---> Basic Manipulations <--- */ - #define mp_iszero(a) (((a)->used == 0) ? 1 : 0) #define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? 1 : 0) #define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? 1 : 0)