added libtommath-0.26
This commit is contained in:
parent
c1da6aa2de
commit
6e732340a9
bn.pdfbn.texbn_fast_mp_montgomery_reduce.cbn_mp_add_d.cbn_mp_cmp.cbn_mp_cmp_mag.cbn_mp_div.cbn_mp_dr_reduce.cbn_mp_init_multi.cbn_mp_lcm.cbn_mp_montgomery_reduce.cbn_mp_neg.cbn_mp_read_signed_bin.cbn_mp_read_unsigned_bin.cbn_mp_set_int.cbn_s_mp_mul_digs.cbn_s_mp_mul_high_digs.cbn_s_mp_sqr.cchanges.txtchanges.txt~
demo
etc
logs
add.logaddsub.pngexpt.logexpt.pngexpt_2k.logexpt_dr.loginvmod.loginvmod.pngmult.logmult.pngmult_kara.logsqr.logsqr_kara.logsub.log
makefilemtest
pics
poster.pdfpre_gen
BIN
bn.pdf
BIN
bn.pdf
Binary file not shown.
2
bn.tex
2
bn.tex
@ -1,7 +1,7 @@
|
|||||||
\documentclass[]{article}
|
\documentclass[]{article}
|
||||||
\begin{document}
|
\begin{document}
|
||||||
|
|
||||||
\title{LibTomMath v0.25 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
|
\title{LibTomMath v0.26 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
|
||||||
\author{Tom St Denis \\ tomstdenis@iahu.ca}
|
\author{Tom St Denis \\ tomstdenis@iahu.ca}
|
||||||
\maketitle
|
\maketitle
|
||||||
\newpage
|
\newpage
|
||||||
|
@ -45,7 +45,10 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
register mp_word *_W;
|
register mp_word *_W;
|
||||||
register mp_digit *tmpx;
|
register mp_digit *tmpx;
|
||||||
|
|
||||||
_W = W;
|
/* alias for the W[] array */
|
||||||
|
_W = W;
|
||||||
|
|
||||||
|
/* alias for the digits of x*/
|
||||||
tmpx = x->dp;
|
tmpx = x->dp;
|
||||||
|
|
||||||
/* copy the digits of a into W[0..a->used-1] */
|
/* copy the digits of a into W[0..a->used-1] */
|
||||||
|
@ -42,7 +42,6 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* old number of used digits in c */
|
/* old number of used digits in c */
|
||||||
oldused = c->used;
|
oldused = c->used;
|
||||||
|
|
||||||
@ -76,7 +75,6 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c)
|
|||||||
/* set final carry */
|
/* set final carry */
|
||||||
ix++;
|
ix++;
|
||||||
*tmpc++ = mu;
|
*tmpc++ = mu;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* a was negative and |a| < b */
|
/* a was negative and |a| < b */
|
||||||
c->used = 1;
|
c->used = 1;
|
||||||
|
12
bn_mp_cmp.c
12
bn_mp_cmp.c
@ -19,12 +19,12 @@ int
|
|||||||
mp_cmp (mp_int * a, mp_int * b)
|
mp_cmp (mp_int * a, mp_int * b)
|
||||||
{
|
{
|
||||||
/* compare based on sign */
|
/* compare based on sign */
|
||||||
if (a->sign == MP_NEG && b->sign == MP_ZPOS) {
|
if (a->sign != b->sign) {
|
||||||
return MP_LT;
|
if (a->sign == MP_NEG) {
|
||||||
}
|
return MP_LT;
|
||||||
|
} else {
|
||||||
if (a->sign == MP_ZPOS && b->sign == MP_NEG) {
|
return MP_GT;
|
||||||
return MP_GT;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compare digits */
|
/* compare digits */
|
||||||
|
@ -19,23 +19,30 @@ int
|
|||||||
mp_cmp_mag (mp_int * a, mp_int * b)
|
mp_cmp_mag (mp_int * a, mp_int * b)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
mp_digit *tmpa, *tmpb;
|
||||||
|
|
||||||
/* compare based on # of non-zero digits */
|
/* compare based on # of non-zero digits */
|
||||||
if (a->used > b->used) {
|
if (a->used > b->used) {
|
||||||
return MP_GT;
|
return MP_GT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->used < b->used) {
|
if (a->used < b->used) {
|
||||||
return MP_LT;
|
return MP_LT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* alias for a */
|
||||||
|
tmpa = a->dp + (a->used - 1);
|
||||||
|
|
||||||
|
/* alias for b */
|
||||||
|
tmpb = b->dp + (a->used - 1);
|
||||||
|
|
||||||
/* compare based on digits */
|
/* compare based on digits */
|
||||||
for (n = a->used - 1; n >= 0; n--) {
|
for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
|
||||||
if (a->dp[n] > b->dp[n]) {
|
if (*tmpa > *tmpb) {
|
||||||
return MP_GT;
|
return MP_GT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->dp[n] < b->dp[n]) {
|
if (*tmpa < *tmpb) {
|
||||||
return MP_LT;
|
return MP_LT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,8 +111,9 @@ mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
|||||||
|
|
||||||
/* step 3. for i from n down to (t + 1) */
|
/* step 3. for i from n down to (t + 1) */
|
||||||
for (i = n; i >= (t + 1); i--) {
|
for (i = n; i >= (t + 1); i--) {
|
||||||
if (i > x.used)
|
if (i > x.used) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* step 3.1 if xi == yt then set q{i-t-1} to b-1,
|
/* step 3.1 if xi == yt then set q{i-t-1} to b-1,
|
||||||
* otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
|
* otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
* The modulus must be of a special format [see manual]
|
* The modulus must be of a special format [see manual]
|
||||||
*
|
*
|
||||||
* Has been modified to use algorithm 7.10 from the LTM book instead
|
* Has been modified to use algorithm 7.10 from the LTM book instead
|
||||||
|
*
|
||||||
|
* Input x must be in the range 0 <= x <= (n-1)^2
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
|
mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
|
||||||
@ -63,10 +65,10 @@ top:
|
|||||||
*tmpx1++ = (mp_digit)(r & MP_MASK);
|
*tmpx1++ = (mp_digit)(r & MP_MASK);
|
||||||
mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
|
mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set final carry */
|
/* set final carry */
|
||||||
*tmpx1++ = mu;
|
*tmpx1++ = mu;
|
||||||
|
|
||||||
/* zero words above m */
|
/* zero words above m */
|
||||||
for (i = m + 1; i < x->used; i++) {
|
for (i = m + 1; i < x->used; i++) {
|
||||||
*tmpx1++ = 0;
|
*tmpx1++ = 0;
|
||||||
|
@ -49,4 +49,5 @@ int mp_init_multi(mp_int *mp, ...)
|
|||||||
}
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return res; /* Assumed ok, if error flagged above. */
|
return res; /* Assumed ok, if error flagged above. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
35
bn_mp_lcm.c
35
bn_mp_lcm.c
@ -14,29 +14,42 @@
|
|||||||
*/
|
*/
|
||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* computes least common multiple as a*b/(a, b) */
|
/* computes least common multiple as |a*b|/(a, b) */
|
||||||
int
|
int
|
||||||
mp_lcm (mp_int * a, mp_int * b, mp_int * c)
|
mp_lcm (mp_int * a, mp_int * b, mp_int * c)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
mp_int t;
|
mp_int t1, t2;
|
||||||
|
|
||||||
|
|
||||||
if ((res = mp_init (&t)) != MP_OKAY) {
|
if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
|
/* t1 = get the GCD of the two inputs */
|
||||||
mp_clear (&t);
|
if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
|
||||||
return res;
|
goto __T;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((res = mp_gcd (a, b, c)) != MP_OKAY) {
|
/* divide the smallest by the GCD */
|
||||||
mp_clear (&t);
|
if (mp_cmp_mag(a, b) == MP_LT) {
|
||||||
return res;
|
/* store quotient in t2 such that t2 * b is the LCM */
|
||||||
|
if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
|
||||||
|
goto __T;
|
||||||
|
}
|
||||||
|
res = mp_mul(b, &t2, c);
|
||||||
|
} else {
|
||||||
|
/* store quotient in t2 such that t2 * a is the LCM */
|
||||||
|
if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
|
||||||
|
goto __T;
|
||||||
|
}
|
||||||
|
res = mp_mul(a, &t2, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = mp_div (&t, c, c, NULL);
|
/* fix the sign to positive */
|
||||||
mp_clear (&t);
|
c->sign = MP_ZPOS;
|
||||||
|
|
||||||
|
__T:
|
||||||
|
mp_clear_multi (&t1, &t2, NULL);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,14 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
x->used = digs;
|
x->used = digs;
|
||||||
|
|
||||||
for (ix = 0; ix < n->used; ix++) {
|
for (ix = 0; ix < n->used; ix++) {
|
||||||
/* mu = ai * m' mod b */
|
/* mu = ai * rho mod b
|
||||||
|
*
|
||||||
|
* The value of rho must be precalculated via
|
||||||
|
* bn_mp_montgomery_setup() such that
|
||||||
|
* it equals -1/n0 mod b this allows the
|
||||||
|
* following inner loop to reduce the
|
||||||
|
* input one digit at a time
|
||||||
|
*/
|
||||||
mu = ((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK;
|
mu = ((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK;
|
||||||
|
|
||||||
/* a = a + mu * m * b**i */
|
/* a = a + mu * m * b**i */
|
||||||
@ -52,8 +59,10 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
register mp_digit *tmpn, *tmpx, u;
|
register mp_digit *tmpn, *tmpx, u;
|
||||||
register mp_word r;
|
register mp_word r;
|
||||||
|
|
||||||
/* aliases */
|
/* alias for digits of the modulus */
|
||||||
tmpn = n->dp;
|
tmpn = n->dp;
|
||||||
|
|
||||||
|
/* alias for the digits of x [the input] */
|
||||||
tmpx = x->dp + ix;
|
tmpx = x->dp + ix;
|
||||||
|
|
||||||
/* set the carry to zero */
|
/* set the carry to zero */
|
||||||
@ -61,12 +70,20 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
|
|
||||||
/* Multiply and add in place */
|
/* Multiply and add in place */
|
||||||
for (iy = 0; iy < n->used; iy++) {
|
for (iy = 0; iy < n->used; iy++) {
|
||||||
|
/* compute product and sum */
|
||||||
r = ((mp_word)mu) * ((mp_word)*tmpn++) +
|
r = ((mp_word)mu) * ((mp_word)*tmpn++) +
|
||||||
((mp_word) u) + ((mp_word) * tmpx);
|
((mp_word) u) + ((mp_word) * tmpx);
|
||||||
|
|
||||||
|
/* get carry */
|
||||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||||
|
|
||||||
|
/* fix digit */
|
||||||
*tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
*tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
||||||
}
|
}
|
||||||
/* propagate carries */
|
/* At this point the ix'th digit of x should be zero */
|
||||||
|
|
||||||
|
|
||||||
|
/* propagate carries upwards as required*/
|
||||||
while (u) {
|
while (u) {
|
||||||
*tmpx += u;
|
*tmpx += u;
|
||||||
u = *tmpx >> DIGIT_BIT;
|
u = *tmpx >> DIGIT_BIT;
|
||||||
@ -75,11 +92,18 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* at this point the n.used'th least
|
||||||
|
* significant digits of x are all zero
|
||||||
|
* which means we can shift x to the
|
||||||
|
* right by n.used digits and the
|
||||||
|
* residue is unchanged.
|
||||||
|
*/
|
||||||
|
|
||||||
/* x = x/b**n.used */
|
/* x = x/b**n.used */
|
||||||
mp_clamp(x);
|
mp_clamp(x);
|
||||||
mp_rshd (x, n->used);
|
mp_rshd (x, n->used);
|
||||||
|
|
||||||
/* if A >= m then A = A - m */
|
/* if x >= n then x = x - n */
|
||||||
if (mp_cmp_mag (x, n) != MP_LT) {
|
if (mp_cmp_mag (x, n) != MP_LT) {
|
||||||
return s_mp_sub (x, n, x);
|
return s_mp_sub (x, n, x);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ mp_neg (mp_int * a, mp_int * b)
|
|||||||
if ((res = mp_copy (a, b)) != MP_OKAY) {
|
if ((res = mp_copy (a, b)) != MP_OKAY) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
|
if (mp_iszero(b) != 1) {
|
||||||
|
b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
|
||||||
|
}
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,17 @@ mp_read_signed_bin (mp_int * a, unsigned char *b, int c)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
/* read magnitude */
|
||||||
if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
|
if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
a->sign = ((b[0] == (unsigned char) 0) ? MP_ZPOS : MP_NEG);
|
|
||||||
|
/* first byte is 0 for positive, non-zero for negative */
|
||||||
|
if (b[0] == 0) {
|
||||||
|
a->sign = MP_ZPOS;
|
||||||
|
} else {
|
||||||
|
a->sign = MP_NEG;
|
||||||
|
}
|
||||||
|
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,18 @@ int
|
|||||||
mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c)
|
mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
/* make sure there are at least two digits */
|
||||||
|
if (a->alloc < 2) {
|
||||||
|
if ((res = mp_grow(a, 2)) != MP_OKAY) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* zero the int */
|
||||||
mp_zero (a);
|
mp_zero (a);
|
||||||
|
|
||||||
|
/* read the bytes in */
|
||||||
while (c-- > 0) {
|
while (c-- > 0) {
|
||||||
if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
|
if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
|
||||||
return res;
|
return res;
|
||||||
|
@ -21,6 +21,7 @@ mp_set_int (mp_int * a, unsigned int b)
|
|||||||
int x, res;
|
int x, res;
|
||||||
|
|
||||||
mp_zero (a);
|
mp_zero (a);
|
||||||
|
|
||||||
/* set four bits at a time */
|
/* set four bits at a time */
|
||||||
for (x = 0; x < 8; x++) {
|
for (x = 0; x < 8; x++) {
|
||||||
/* shift the number up four bits */
|
/* shift the number up four bits */
|
||||||
|
@ -61,15 +61,15 @@ s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
|
|||||||
/* compute the columns of the output and propagate the carry */
|
/* compute the columns of the output and propagate the carry */
|
||||||
for (iy = 0; iy < pb; iy++) {
|
for (iy = 0; iy < pb; iy++) {
|
||||||
/* compute the column as a mp_word */
|
/* compute the column as a mp_word */
|
||||||
r = ((mp_word) *tmpt) +
|
r = ((mp_word)*tmpt) +
|
||||||
((mp_word)tmpx) * ((mp_word)*tmpy++) +
|
((mp_word)tmpx) * ((mp_word)*tmpy++) +
|
||||||
((mp_word) u);
|
((mp_word) u);
|
||||||
|
|
||||||
/* the new column is the lower part of the result */
|
/* the new column is the lower part of the result */
|
||||||
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||||
|
|
||||||
/* get the carry word from the result */
|
/* get the carry word from the result */
|
||||||
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
|
||||||
}
|
}
|
||||||
/* set carry if it is placed below digs */
|
/* set carry if it is placed below digs */
|
||||||
if (ix + iy < digs) {
|
if (ix + iy < digs) {
|
||||||
|
@ -26,7 +26,6 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
|
|||||||
mp_word r;
|
mp_word r;
|
||||||
mp_digit tmpx, *tmpt, *tmpy;
|
mp_digit tmpx, *tmpt, *tmpy;
|
||||||
|
|
||||||
|
|
||||||
/* can we use the fast multiplier? */
|
/* can we use the fast multiplier? */
|
||||||
if (((a->used + b->used + 1) < MP_WARRAY)
|
if (((a->used + b->used + 1) < MP_WARRAY)
|
||||||
&& MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
|
&& MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
|
||||||
@ -55,13 +54,15 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
|
|||||||
|
|
||||||
for (iy = digs - ix; iy < pb; iy++) {
|
for (iy = digs - ix; iy < pb; iy++) {
|
||||||
/* calculate the double precision result */
|
/* calculate the double precision result */
|
||||||
r = ((mp_word) * tmpt) + ((mp_word)tmpx) * ((mp_word)*tmpy++) + ((mp_word) u);
|
r = ((mp_word)*tmpt) +
|
||||||
|
((mp_word)tmpx) * ((mp_word)*tmpy++) +
|
||||||
|
((mp_word) u);
|
||||||
|
|
||||||
/* get the lower part */
|
/* get the lower part */
|
||||||
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||||
|
|
||||||
/* carry the carry */
|
/* carry the carry */
|
||||||
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
|
||||||
}
|
}
|
||||||
*tmpt = u;
|
*tmpt = u;
|
||||||
}
|
}
|
||||||
|
@ -54,19 +54,19 @@ s_mp_sqr (mp_int * a, mp_int * b)
|
|||||||
/* now calculate the double precision result, note we use
|
/* now calculate the double precision result, note we use
|
||||||
* addition instead of *2 since it's easier to optimize
|
* addition instead of *2 since it's easier to optimize
|
||||||
*/
|
*/
|
||||||
r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
|
r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
|
||||||
|
|
||||||
/* store lower part */
|
/* store lower part */
|
||||||
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||||
|
|
||||||
/* get carry */
|
/* get carry */
|
||||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||||
}
|
}
|
||||||
/* propagate upwards */
|
/* propagate upwards */
|
||||||
while (u != ((mp_digit) 0)) {
|
while (u != ((mp_digit) 0)) {
|
||||||
r = ((mp_word) * tmpt) + ((mp_word) u);
|
r = ((mp_word) *tmpt) + ((mp_word) u);
|
||||||
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
changes.txt
10
changes.txt
@ -1,3 +1,13 @@
|
|||||||
|
Aug 29th, 2003
|
||||||
|
v0.26 -- Fixed typo that caused warning with GCC 3.2
|
||||||
|
-- Martin Marcel noticed a bug in mp_neg() that allowed negative zeroes.
|
||||||
|
Also, Martin is the fellow who noted the bugs in mp_gcd() of 0.24/0.25.
|
||||||
|
-- Martin Marcel noticed an optimization [and slight bug] in mp_lcm().
|
||||||
|
-- Added fix to mp_read_unsigned_bin to prevent a buffer overflow.
|
||||||
|
-- Beefed up the comments in the baseline multipliers [and montgomery]
|
||||||
|
-- Added "mont" demo to the makefile.msvc in etc/
|
||||||
|
-- Optimized sign compares in mp_cmp from 4 to 2 cases.
|
||||||
|
|
||||||
Aug 4th, 2003
|
Aug 4th, 2003
|
||||||
v0.25 -- Fix to mp_gcd again... oops (0,-a) == (-a, 0) == a
|
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]
|
-- Fix to mp_clear which didn't reset the sign [Greg Rose]
|
||||||
|
244
changes.txt~
Normal file
244
changes.txt~
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
Aug 11th, 2003
|
||||||
|
v0.26 -- Fixed typo that caused warning with GCC 3.2
|
||||||
|
-- Martin Marcel noticed a bug in mp_neg() that allowed negative zeroes.
|
||||||
|
Also, Martin is the fellow who noted the bugs in mp_gcd() of 0.24/0.25.
|
||||||
|
-- Martin Marcel noticed an optimization [and slight bug] in mp_lcm().
|
||||||
|
-- Added fix to mp_read_unsigned_bin to prevent a buffer overflow.
|
||||||
|
-- Beefed up the comments in the baseline multipliers [and montgomery]
|
||||||
|
-- Added "mont" demo to the makefile.msvc in etc/
|
||||||
|
-- Optimized sign compares in mp_cmp from 4 to 2 cases.
|
||||||
|
|
||||||
|
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
|
||||||
|
e.g. (0,0,a) == a [instead of 1]
|
||||||
|
-- Should be one of the last release for a while. Working on LibTomMath book now.
|
||||||
|
-- optimized the pprime demo [/etc/pprime.c] to first make a huge table of single
|
||||||
|
digit primes then it reads them randomly instead of randomly choosing/testing single
|
||||||
|
digit primes.
|
||||||
|
|
||||||
|
July 12th, 2003
|
||||||
|
v0.23 -- Optimized mp_prime_next_prime() to not use mp_mod [via is_divisible()] in each
|
||||||
|
iteration. Instead now a smaller table is kept of the residues which can be updated
|
||||||
|
without division.
|
||||||
|
-- Fixed a bug in next_prime() where an input of zero would be treated as odd and
|
||||||
|
have two added to it [to move to the next odd].
|
||||||
|
-- fixed a bug in prime_fermat() and prime_miller_rabin() which allowed the base
|
||||||
|
to be negative, zero or one. Normally the test is only valid if the base is
|
||||||
|
greater than one.
|
||||||
|
-- changed the next_prime() prototype to accept a new parameter "bbs_style" which
|
||||||
|
will find the next prime congruent to 3 mod 4. The default [bbs_style==0] will
|
||||||
|
make primes which are either congruent to 1 or 3 mod 4.
|
||||||
|
-- fixed mp_read_unsigned_bin() so that it doesn't include both code for
|
||||||
|
the case DIGIT_BIT < 8 and >= 8
|
||||||
|
-- optimized div_d() to easy out on division by 1 [or if a == 0] and use
|
||||||
|
logical shifts if the divisor is a power of two.
|
||||||
|
-- the default DIGIT_BIT type was not int for non-default builds. Fixed.
|
||||||
|
|
||||||
|
July 2nd, 2003
|
||||||
|
v0.22 -- Fixed up mp_invmod so the result is properly in range now [was always congruent to the inverse...]
|
||||||
|
-- Fixed up s_mp_exptmod and mp_exptmod_fast so the lower half of the pre-computed table isn't allocated
|
||||||
|
which makes the algorithm use half as much ram.
|
||||||
|
-- Fixed the install script not to make the book :-) [which isn't included anyways]
|
||||||
|
-- added mp_cnt_lsb() which counts how many of the lsbs are zero
|
||||||
|
-- optimized mp_gcd() to use the new mp_cnt_lsb() to replace multiple divisions by two by a single division.
|
||||||
|
-- applied similar optimization to mp_prime_miller_rabin().
|
||||||
|
-- Fixed a bug in both mp_invmod() and fast_mp_invmod() which tested for odd
|
||||||
|
via "mp_iseven() == 0" which is not valid [since zero is not even either].
|
||||||
|
|
||||||
|
June 19th, 2003
|
||||||
|
v0.21 -- Fixed bug in mp_mul_d which would not handle sign correctly [would not always forward it]
|
||||||
|
-- Removed the #line lines from gen.pl [was in violation of ISO C]
|
||||||
|
|
||||||
|
June 8th, 2003
|
||||||
|
v0.20 -- Removed the book from the package. Added the TDCAL license document.
|
||||||
|
-- This release is officially pure-bred TDCAL again [last officially TDCAL based release was v0.16]
|
||||||
|
|
||||||
|
June 6th, 2003
|
||||||
|
v0.19 -- Fixed a bug in mp_montgomery_reduce() which was introduced when I tweaked mp_rshd() in the previous release.
|
||||||
|
Essentially the digits were not trimmed before the compare which cause a subtraction to occur all the time.
|
||||||
|
-- Fixed up etc/tune.c a bit to stop testing new cutoffs after 16 failures [to find more optimal points].
|
||||||
|
Brute force ho!
|
||||||
|
|
||||||
|
|
||||||
|
May 29th, 2003
|
||||||
|
v0.18 -- Fixed a bug in s_mp_sqr which would handle carries properly just not very elegantly.
|
||||||
|
(e.g. correct result, just bad looking code)
|
||||||
|
-- Fixed bug in mp_sqr which still had a 512 constant instead of MP_WARRAY
|
||||||
|
-- Added Toom-Cook multipliers [needs tuning!]
|
||||||
|
-- Added efficient divide by 3 algorithm mp_div_3
|
||||||
|
-- Re-wrote mp_div_d to be faster than calling mp_div
|
||||||
|
-- Added in a donated BCC makefile and a single page LTM poster (ahalhabsi@sbcglobal.net)
|
||||||
|
-- Added mp_reduce_2k which reduces an input modulo n = 2**p - k for any single digit k
|
||||||
|
-- Made the exptmod system be aware of the 2k reduction algorithms.
|
||||||
|
-- Rewrote mp_dr_reduce to be smaller, simpler and easier to understand.
|
||||||
|
|
||||||
|
May 17th, 2003
|
||||||
|
v0.17 -- Benjamin Goldberg submitted optimized mp_add and mp_sub routines. A new gen.pl as well
|
||||||
|
as several smaller suggestions. Thanks!
|
||||||
|
-- removed call to mp_cmp in inner loop of mp_div and put mp_cmp_mag in its place :-)
|
||||||
|
-- Fixed bug in mp_exptmod that would cause it to fail for odd moduli when DIGIT_BIT != 28
|
||||||
|
-- mp_exptmod now also returns errors if the modulus is negative and will handle negative exponents
|
||||||
|
-- mp_prime_is_prime will now return true if the input is one of the primes in the prime table
|
||||||
|
-- Damian M Gryski (dgryski@uwaterloo.ca) found a index out of bounds error in the
|
||||||
|
mp_fast_s_mp_mul_high_digs function which didn't come up before. (fixed)
|
||||||
|
-- Refactored the DR reduction code so there is only one function per file.
|
||||||
|
-- Fixed bug in the mp_mul() which would erroneously avoid the faster multiplier [comba] when it was
|
||||||
|
allowed. The bug would not cause the incorrect value to be produced just less efficient (fixed)
|
||||||
|
-- Fixed similar bug in the Montgomery reduction code.
|
||||||
|
-- Added tons of (mp_digit) casts so the 7/15/28/31 bit digit code will work flawlessly out of the box.
|
||||||
|
Also added limited support for 64-bit machines with a 60-bit digit. Both thanks to Tom Wu (tom@arcot.com)
|
||||||
|
-- Added new comments here and there, cleaned up some code [style stuff]
|
||||||
|
-- Fixed a lingering typo in mp_exptmod* that would set bitcnt to zero then one. Very silly stuff :-)
|
||||||
|
-- Fixed up mp_exptmod_fast so it would set "redux" to the comba Montgomery reduction if allowed. This
|
||||||
|
saves quite a few calls and if statements.
|
||||||
|
-- Added etc/mont.c a test of the Montgomery reduction [assuming all else works :-| ]
|
||||||
|
-- Fixed up etc/tune.c to use a wider test range [more appropriate] also added a x86 based addition which
|
||||||
|
uses RDTSC for high precision timing.
|
||||||
|
-- Updated demo/demo.c to remove MPI stuff [won't work anyways], made the tests run for 2 seconds each so its
|
||||||
|
not so insanely slow. Also made the output space delimited [and fixed up various errors]
|
||||||
|
-- Added logs directory, logs/graph.dem which will use gnuplot to make a series of PNG files
|
||||||
|
that go with the pre-made index.html. You have to build [via make timing] and run ltmtest first in the
|
||||||
|
root of the package.
|
||||||
|
-- Fixed a bug in mp_sub and mp_add where "-a - -a" or "-a + a" would produce -0 as the result [obviously invalid].
|
||||||
|
-- Fixed a bug in mp_rshd. If the count == a.used it should zero/return [instead of shifting]
|
||||||
|
-- Fixed a "off-by-one" bug in mp_mul2d. The initial size check on alloc would be off by one if the residue
|
||||||
|
shifting caused a carry.
|
||||||
|
-- Fixed a bug where s_mp_mul_digs() would not call the Comba based routine if allowed. This made Barrett reduction
|
||||||
|
slower than it had to be.
|
||||||
|
|
||||||
|
Mar 29th, 2003
|
||||||
|
v0.16 -- Sped up mp_div by making normalization one shift call
|
||||||
|
-- Sped up mp_mul_2d/mp_div_2d by aliasing pointers :-)
|
||||||
|
-- Cleaned up mp_gcd to use the macros for odd/even detection
|
||||||
|
-- Added comments here and there, mostly there but occasionally here too.
|
||||||
|
|
||||||
|
Mar 22nd, 2003
|
||||||
|
v0.15 -- Added series of prime testing routines to lib
|
||||||
|
-- Fixed up etc/tune.c
|
||||||
|
-- Added DR reduction algorithm
|
||||||
|
-- Beefed up the manual more.
|
||||||
|
-- Fixed up demo/demo.c so it doesn't have so many warnings and it does the full series of
|
||||||
|
tests
|
||||||
|
-- Added "pre-gen" directory which will hold a "gen.pl"'ed copy of the entire lib [done at
|
||||||
|
zipup time so its always the latest]
|
||||||
|
-- Added conditional casts for C++ users [boo!]
|
||||||
|
|
||||||
|
Mar 15th, 2003
|
||||||
|
v0.14 -- Tons of manual updates
|
||||||
|
-- cleaned up the directory
|
||||||
|
-- added MSVC makefiles
|
||||||
|
-- source changes [that I don't recall]
|
||||||
|
-- Fixed up the lshd/rshd code to use pointer aliasing
|
||||||
|
-- Fixed up the mul_2d and div_2d to not call rshd/lshd unless needed
|
||||||
|
-- Fixed up etc/tune.c a tad
|
||||||
|
-- fixed up demo/demo.c to output comma-delimited results of timing
|
||||||
|
also fixed up timing demo to use a finer granularity for various functions
|
||||||
|
-- fixed up demo/demo.c testing to pause during testing so my Duron won't catch on fire
|
||||||
|
[stays around 31-35C during testing :-)]
|
||||||
|
|
||||||
|
Feb 13th, 2003
|
||||||
|
v0.13 -- tons of minor speed-ups in low level add, sub, mul_2 and div_2 which propagate
|
||||||
|
to other functions like mp_invmod, mp_div, etc...
|
||||||
|
-- Sped up mp_exptmod_fast by using new code to find R mod m [e.g. B^n mod m]
|
||||||
|
-- minor fixes
|
||||||
|
|
||||||
|
Jan 17th, 2003
|
||||||
|
v0.12 -- re-wrote the majority of the makefile so its more portable and will
|
||||||
|
install via "make install" on most *nix platforms
|
||||||
|
-- Re-packaged all the source as seperate files. Means the library a single
|
||||||
|
file packagage any more. Instead of just adding "bn.c" you have to add
|
||||||
|
libtommath.a
|
||||||
|
-- Renamed "bn.h" to "tommath.h"
|
||||||
|
-- Changes to the manual to reflect all of this
|
||||||
|
-- Used GNU Indent to clean up the source
|
||||||
|
|
||||||
|
Jan 15th, 2003
|
||||||
|
v0.11 -- More subtle fixes
|
||||||
|
-- Moved to gentoo linux [hurrah!] so made *nix specific fixes to the make process
|
||||||
|
-- Sped up the montgomery reduction code quite a bit
|
||||||
|
-- fixed up demo so when building timing for the x86 it assumes ELF format now
|
||||||
|
|
||||||
|
Jan 9th, 2003
|
||||||
|
v0.10 -- Pekka Riikonen suggested fixes to the radix conversion code.
|
||||||
|
-- Added baseline montgomery and comba montgomery reductions, sped up exptmods
|
||||||
|
[to a point, see bn.h for MONTGOMERY_EXPT_CUTOFF]
|
||||||
|
|
||||||
|
Jan 6th, 2003
|
||||||
|
v0.09 -- Updated the manual to reflect recent changes. :-)
|
||||||
|
-- Added Jacobi function (mp_jacobi) to supplement the number theory side of the lib
|
||||||
|
-- Added a Mersenne prime finder demo in ./etc/mersenne.c
|
||||||
|
|
||||||
|
Jan 2nd, 2003
|
||||||
|
v0.08 -- Sped up the multipliers by moving the inner loop variables into a smaller scope
|
||||||
|
-- Corrected a bunch of small "warnings"
|
||||||
|
-- Added more comments
|
||||||
|
-- Made "mtest" be able to use /dev/random, /dev/urandom or stdin for RNG data
|
||||||
|
-- Corrected some bugs where error messages were potentially ignored
|
||||||
|
-- add etc/pprime.c program which makes numbers which are provably prime.
|
||||||
|
|
||||||
|
Jan 1st, 2003
|
||||||
|
v0.07 -- Removed alot of heap operations from core functions to speed them up
|
||||||
|
-- Added a root finding function [and mp_sqrt macro like from MPI]
|
||||||
|
-- Added more to manual
|
||||||
|
|
||||||
|
Dec 31st, 2002
|
||||||
|
v0.06 -- Sped up the s_mp_add, s_mp_sub which inturn sped up mp_invmod, mp_exptmod, etc...
|
||||||
|
-- Cleaned up the header a bit more
|
||||||
|
|
||||||
|
Dec 30th, 2002
|
||||||
|
v0.05 -- Builds with MSVC out of the box
|
||||||
|
-- Fixed a bug in mp_invmod w.r.t. even moduli
|
||||||
|
-- Made mp_toradix and mp_read_radix use char instead of unsigned char arrays
|
||||||
|
-- Fixed up exptmod to use fewer multiplications
|
||||||
|
-- Fixed up mp_init_size to use only one heap operation
|
||||||
|
-- Note there is a slight "off-by-one" bug in the library somewhere
|
||||||
|
without the padding (see the source for comment) the library
|
||||||
|
crashes in libtomcrypt. Anyways a reasonable workaround is to pad the
|
||||||
|
numbers which will always correct it since as the numbers grow the padding
|
||||||
|
will still be beyond the end of the number
|
||||||
|
-- Added more to the manual
|
||||||
|
|
||||||
|
Dec 29th, 2002
|
||||||
|
v0.04 -- Fixed a memory leak in mp_to_unsigned_bin
|
||||||
|
-- optimized invmod code
|
||||||
|
-- Fixed bug in mp_div
|
||||||
|
-- use exchange instead of copy for results
|
||||||
|
-- added a bit more to the manual
|
||||||
|
|
||||||
|
Dec 27th, 2002
|
||||||
|
v0.03 -- Sped up s_mp_mul_high_digs by not computing the carries of the lower digits
|
||||||
|
-- Fixed a bug where mp_set_int wouldn't zero the value first and set the used member.
|
||||||
|
-- fixed a bug in s_mp_mul_high_digs where the limit placed on the result digits was not calculated properly
|
||||||
|
-- fixed bugs in add/sub/mul/sqr_mod functions where if the modulus and dest were the same it wouldn't work
|
||||||
|
-- fixed a bug in mp_mod and mp_mod_d concerning negative inputs
|
||||||
|
-- mp_mul_d didn't preserve sign
|
||||||
|
-- Many many many many fixes
|
||||||
|
-- Works in LibTomCrypt now :-)
|
||||||
|
-- Added iterations to the timing demos... more accurate.
|
||||||
|
-- Tom needs a job.
|
||||||
|
|
||||||
|
Dec 26th, 2002
|
||||||
|
v0.02 -- Fixed a few "slips" in the manual. This is "LibTomMath" afterall :-)
|
||||||
|
-- Added mp_cmp_mag, mp_neg, mp_abs and mp_radix_size that were missing.
|
||||||
|
-- Sped up the fast [comba] multipliers more [yahoo!]
|
||||||
|
|
||||||
|
Dec 25th,2002
|
||||||
|
v0.01 -- Initial release. Gimme a break.
|
||||||
|
-- Todo list,
|
||||||
|
add details to manual [e.g. algorithms]
|
||||||
|
more comments in code
|
||||||
|
example programs
|
17
demo/demo.c
17
demo/demo.c
@ -1,5 +1,12 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifdef IOWNANATHLON
|
||||||
|
#include <unistd.h>
|
||||||
|
#define SLEEP sleep(4)
|
||||||
|
#else
|
||||||
|
#define SLEEP
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "tommath.h"
|
#include "tommath.h"
|
||||||
|
|
||||||
#ifdef TIMER
|
#ifdef TIMER
|
||||||
@ -185,6 +192,7 @@ int main(void)
|
|||||||
|
|
||||||
log = fopen("logs/add.log", "w");
|
log = fopen("logs/add.log", "w");
|
||||||
for (cnt = 8; cnt <= 128; cnt += 8) {
|
for (cnt = 8; cnt <= 128; cnt += 8) {
|
||||||
|
SLEEP;
|
||||||
mp_rand(&a, cnt);
|
mp_rand(&a, cnt);
|
||||||
mp_rand(&b, cnt);
|
mp_rand(&b, cnt);
|
||||||
reset();
|
reset();
|
||||||
@ -201,11 +209,12 @@ int main(void)
|
|||||||
|
|
||||||
log = fopen("logs/sub.log", "w");
|
log = fopen("logs/sub.log", "w");
|
||||||
for (cnt = 8; cnt <= 128; cnt += 8) {
|
for (cnt = 8; cnt <= 128; cnt += 8) {
|
||||||
|
SLEEP;
|
||||||
mp_rand(&a, cnt);
|
mp_rand(&a, cnt);
|
||||||
mp_rand(&b, cnt);
|
mp_rand(&b, cnt);
|
||||||
reset();
|
reset();
|
||||||
rr = 0;
|
rr = 0;
|
||||||
do {
|
do {
|
||||||
DO(mp_sub(&a,&b,&c));
|
DO(mp_sub(&a,&b,&c));
|
||||||
rr += 16;
|
rr += 16;
|
||||||
} while (rdtsc() < (CLOCKS_PER_SEC * 2));
|
} while (rdtsc() < (CLOCKS_PER_SEC * 2));
|
||||||
@ -226,6 +235,7 @@ int main(void)
|
|||||||
|
|
||||||
log = fopen((ix==0)?"logs/mult.log":"logs/mult_kara.log", "w");
|
log = fopen((ix==0)?"logs/mult.log":"logs/mult_kara.log", "w");
|
||||||
for (cnt = 32; cnt <= 288; cnt += 16) {
|
for (cnt = 32; cnt <= 288; cnt += 16) {
|
||||||
|
SLEEP;
|
||||||
mp_rand(&a, cnt);
|
mp_rand(&a, cnt);
|
||||||
mp_rand(&b, cnt);
|
mp_rand(&b, cnt);
|
||||||
reset();
|
reset();
|
||||||
@ -242,6 +252,7 @@ int main(void)
|
|||||||
|
|
||||||
log = fopen((ix==0)?"logs/sqr.log":"logs/sqr_kara.log", "w");
|
log = fopen((ix==0)?"logs/sqr.log":"logs/sqr_kara.log", "w");
|
||||||
for (cnt = 32; cnt <= 288; cnt += 16) {
|
for (cnt = 32; cnt <= 288; cnt += 16) {
|
||||||
|
SLEEP;
|
||||||
mp_rand(&a, cnt);
|
mp_rand(&a, cnt);
|
||||||
reset();
|
reset();
|
||||||
rr = 0;
|
rr = 0;
|
||||||
@ -265,7 +276,7 @@ int main(void)
|
|||||||
"1475979915214180235084898622737381736312066145333169775147771216478570297878078949377407337049389289382748507531496480477281264838760259191814463365330269540496961201113430156902396093989090226259326935025281409614983499388222831448598601834318536230923772641390209490231836446899608210795482963763094236630945410832793769905399982457186322944729636418890623372171723742105636440368218459649632948538696905872650486914434637457507280441823676813517852099348660847172579408422316678097670224011990280170474894487426924742108823536808485072502240519452587542875349976558572670229633962575212637477897785501552646522609988869914013540483809865681250419497686697771007",
|
"1475979915214180235084898622737381736312066145333169775147771216478570297878078949377407337049389289382748507531496480477281264838760259191814463365330269540496961201113430156902396093989090226259326935025281409614983499388222831448598601834318536230923772641390209490231836446899608210795482963763094236630945410832793769905399982457186322944729636418890623372171723742105636440368218459649632948538696905872650486914434637457507280441823676813517852099348660847172579408422316678097670224011990280170474894487426924742108823536808485072502240519452587542875349976558572670229633962575212637477897785501552646522609988869914013540483809865681250419497686697771007",
|
||||||
"259117086013202627776246767922441530941818887553125427303974923161874019266586362086201209516800483406550695241733194177441689509238807017410377709597512042313066624082916353517952311186154862265604547691127595848775610568757931191017711408826252153849035830401185072116424747461823031471398340229288074545677907941037288235820705892351068433882986888616658650280927692080339605869308790500409503709875902119018371991620994002568935113136548829739112656797303241986517250116412703509705427773477972349821676443446668383119322540099648994051790241624056519054483690809616061625743042361721863339415852426431208737266591962061753535748892894599629195183082621860853400937932839420261866586142503251450773096274235376822938649407127700846077124211823080804139298087057504713825264571448379371125032081826126566649084251699453951887789613650248405739378594599444335231188280123660406262468609212150349937584782292237144339628858485938215738821232393687046160677362909315071",
|
"259117086013202627776246767922441530941818887553125427303974923161874019266586362086201209516800483406550695241733194177441689509238807017410377709597512042313066624082916353517952311186154862265604547691127595848775610568757931191017711408826252153849035830401185072116424747461823031471398340229288074545677907941037288235820705892351068433882986888616658650280927692080339605869308790500409503709875902119018371991620994002568935113136548829739112656797303241986517250116412703509705427773477972349821676443446668383119322540099648994051790241624056519054483690809616061625743042361721863339415852426431208737266591962061753535748892894599629195183082621860853400937932839420261866586142503251450773096274235376822938649407127700846077124211823080804139298087057504713825264571448379371125032081826126566649084251699453951887789613650248405739378594599444335231188280123660406262468609212150349937584782292237144339628858485938215738821232393687046160677362909315071",
|
||||||
"190797007524439073807468042969529173669356994749940177394741882673528979787005053706368049835514900244303495954950709725762186311224148828811920216904542206960744666169364221195289538436845390250168663932838805192055137154390912666527533007309292687539092257043362517857366624699975402375462954490293259233303137330643531556539739921926201438606439020075174723029056838272505051571967594608350063404495977660656269020823960825567012344189908927956646011998057988548630107637380993519826582389781888135705408653045219655801758081251164080554609057468028203308718724654081055323215860189611391296030471108443146745671967766308925858547271507311563765171008318248647110097614890313562856541784154881743146033909602737947385055355960331855614540900081456378659068370317267696980001187750995491090350108417050917991562167972281070161305972518044872048331306383715094854938415738549894606070722584737978176686422134354526989443028353644037187375385397838259511833166416134323695660367676897722287918773420968982326089026150031515424165462111337527431154890666327374921446276833564519776797633875503548665093914556482031482248883127023777039667707976559857333357013727342079099064400455741830654320379350833236245819348824064783585692924881021978332974949906122664421376034687815350484991",
|
"190797007524439073807468042969529173669356994749940177394741882673528979787005053706368049835514900244303495954950709725762186311224148828811920216904542206960744666169364221195289538436845390250168663932838805192055137154390912666527533007309292687539092257043362517857366624699975402375462954490293259233303137330643531556539739921926201438606439020075174723029056838272505051571967594608350063404495977660656269020823960825567012344189908927956646011998057988548630107637380993519826582389781888135705408653045219655801758081251164080554609057468028203308718724654081055323215860189611391296030471108443146745671967766308925858547271507311563765171008318248647110097614890313562856541784154881743146033909602737947385055355960331855614540900081456378659068370317267696980001187750995491090350108417050917991562167972281070161305972518044872048331306383715094854938415738549894606070722584737978176686422134354526989443028353644037187375385397838259511833166416134323695660367676897722287918773420968982326089026150031515424165462111337527431154890666327374921446276833564519776797633875503548665093914556482031482248883127023777039667707976559857333357013727342079099064400455741830654320379350833236245819348824064783585692924881021978332974949906122664421376034687815350484991",
|
||||||
|
|
||||||
/* DR moduli */
|
/* DR moduli */
|
||||||
"14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368612079",
|
"14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368612079",
|
||||||
"101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039",
|
"101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039",
|
||||||
@ -289,6 +300,7 @@ int main(void)
|
|||||||
logb = fopen("logs/expt_dr.log", "w");
|
logb = fopen("logs/expt_dr.log", "w");
|
||||||
logc = fopen("logs/expt_2k.log", "w");
|
logc = fopen("logs/expt_2k.log", "w");
|
||||||
for (n = 0; primes[n]; n++) {
|
for (n = 0; primes[n]; n++) {
|
||||||
|
SLEEP;
|
||||||
mp_read_radix(&a, primes[n], 10);
|
mp_read_radix(&a, primes[n], 10);
|
||||||
mp_zero(&b);
|
mp_zero(&b);
|
||||||
for (rr = 0; rr < mp_count_bits(&a); rr++) {
|
for (rr = 0; rr < mp_count_bits(&a); rr++) {
|
||||||
@ -325,6 +337,7 @@ int main(void)
|
|||||||
|
|
||||||
log = fopen("logs/invmod.log", "w");
|
log = fopen("logs/invmod.log", "w");
|
||||||
for (cnt = 4; cnt <= 128; cnt += 4) {
|
for (cnt = 4; cnt <= 128; cnt += 4) {
|
||||||
|
SLEEP;
|
||||||
mp_rand(&a, cnt);
|
mp_rand(&a, cnt);
|
||||||
mp_rand(&b, cnt);
|
mp_rand(&b, cnt);
|
||||||
|
|
||||||
|
@ -12,6 +12,9 @@ mersenne: mersenne.obj
|
|||||||
|
|
||||||
tune: tune.obj
|
tune: tune.obj
|
||||||
cl tune.obj ../tommath.lib
|
cl tune.obj ../tommath.lib
|
||||||
|
|
||||||
|
mont: mont.obj
|
||||||
|
cl mont.obj ../tommath.lib
|
||||||
|
|
||||||
drprime: drprime.obj
|
drprime: drprime.obj
|
||||||
cl drprime.obj ../tommath.lib
|
cl drprime.obj ../tommath.lib
|
||||||
|
32
logs/add.log
32
logs/add.log
@ -1,16 +1,16 @@
|
|||||||
224 12444616
|
224 12849536
|
||||||
448 10412040
|
448 9956080
|
||||||
672 8825112
|
672 8372000
|
||||||
896 7519080
|
896 7065464
|
||||||
1120 6428432
|
1120 5824864
|
||||||
1344 5794784
|
1344 5141728
|
||||||
1568 5242952
|
1568 4511808
|
||||||
1792 4737008
|
1792 4170480
|
||||||
2016 4434104
|
2016 3802536
|
||||||
2240 4132912
|
2240 3500936
|
||||||
2464 3827752
|
2464 3193352
|
||||||
2688 3589672
|
2688 2991976
|
||||||
2912 3350176
|
2912 2818672
|
||||||
3136 3180208
|
3136 2661448
|
||||||
3360 3014160
|
3360 2506560
|
||||||
3584 2847672
|
3584 2343304
|
||||||
|
BIN
logs/addsub.png
BIN
logs/addsub.png
Binary file not shown.
Before ![]() (image error) Size: 6.8 KiB After ![]() (image error) Size: 6.6 KiB ![]() ![]() |
@ -1,7 +1,7 @@
|
|||||||
513 680
|
513 600
|
||||||
769 257
|
769 221
|
||||||
1025 117
|
1025 103
|
||||||
2049 17
|
2049 15
|
||||||
2561 9
|
2561 8
|
||||||
3073 5
|
3073 4
|
||||||
4097 2
|
4097 2
|
||||||
|
BIN
logs/expt.png
BIN
logs/expt.png
Binary file not shown.
Before ![]() (image error) Size: 7.2 KiB After ![]() (image error) Size: 7.2 KiB ![]() ![]() |
@ -1,6 +1,6 @@
|
|||||||
521 736
|
521 728
|
||||||
607 552
|
607 549
|
||||||
1279 112
|
1279 100
|
||||||
2203 33
|
2203 29
|
||||||
3217 13
|
3217 11
|
||||||
4253 6
|
4253 5
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
532 1064
|
532 1032
|
||||||
784 460
|
784 424
|
||||||
1036 240
|
1036 214
|
||||||
1540 91
|
1540 81
|
||||||
2072 43
|
2072 38
|
||||||
3080 15
|
3080 13
|
||||||
4116 6
|
4116 5
|
||||||
|
@ -1,32 +1,32 @@
|
|||||||
112 16248
|
112 14936
|
||||||
224 8192
|
224 7208
|
||||||
336 5320
|
336 6864
|
||||||
448 3560
|
448 5000
|
||||||
560 2728
|
560 3648
|
||||||
672 2064
|
672 1832
|
||||||
784 1704
|
784 1480
|
||||||
896 2176
|
896 1232
|
||||||
1008 1184
|
1008 1010
|
||||||
1120 976
|
1120 1360
|
||||||
1232 1280
|
1232 728
|
||||||
1344 1176
|
1344 632
|
||||||
1456 624
|
1456 544
|
||||||
1568 912
|
1568 800
|
||||||
1680 504
|
1680 704
|
||||||
1792 452
|
1792 396
|
||||||
1904 658
|
1904 584
|
||||||
2016 608
|
2016 528
|
||||||
2128 336
|
2128 483
|
||||||
2240 312
|
2240 448
|
||||||
2352 288
|
2352 250
|
||||||
2464 264
|
2464 378
|
||||||
2576 408
|
2576 350
|
||||||
2688 376
|
2688 198
|
||||||
2800 354
|
2800 300
|
||||||
2912 198
|
2912 170
|
||||||
3024 307
|
3024 265
|
||||||
3136 173
|
3136 150
|
||||||
3248 162
|
3248 142
|
||||||
3360 256
|
3360 134
|
||||||
3472 145
|
3472 126
|
||||||
3584 226
|
3584 118
|
||||||
|
BIN
logs/invmod.png
BIN
logs/invmod.png
Binary file not shown.
Before ![]() (image error) Size: 5.6 KiB After ![]() (image error) Size: 5.6 KiB ![]() ![]() |
@ -0,0 +1,17 @@
|
|||||||
|
896 301008
|
||||||
|
1344 141872
|
||||||
|
1792 84424
|
||||||
|
2240 55864
|
||||||
|
2688 39784
|
||||||
|
3136 29624
|
||||||
|
3584 22952
|
||||||
|
4032 18304
|
||||||
|
4480 14944
|
||||||
|
4928 12432
|
||||||
|
5376 10496
|
||||||
|
5824 8976
|
||||||
|
6272 7776
|
||||||
|
6720 6792
|
||||||
|
7168 1656
|
||||||
|
7616 1472
|
||||||
|
8064 1312
|
BIN
logs/mult.png
BIN
logs/mult.png
Binary file not shown.
Before ![]() (image error) Size: 8.1 KiB After ![]() (image error) Size: 8.0 KiB ![]() ![]() |
@ -1,17 +1,17 @@
|
|||||||
896 322872
|
896 301784
|
||||||
1344 151688
|
1344 141568
|
||||||
1792 90480
|
1792 84592
|
||||||
2240 59984
|
2240 55864
|
||||||
2688 42656
|
2688 39576
|
||||||
3136 32144
|
3136 30088
|
||||||
3584 25840
|
3584 24032
|
||||||
4032 21328
|
4032 19760
|
||||||
4480 17856
|
4480 16536
|
||||||
4928 14928
|
4928 13376
|
||||||
5376 12856
|
5376 11880
|
||||||
5824 11256
|
5824 10256
|
||||||
6272 9880
|
6272 9160
|
||||||
6720 8984
|
6720 8208
|
||||||
7168 7928
|
7168 7384
|
||||||
7616 7200
|
7616 6664
|
||||||
8064 6576
|
8064 6112
|
||||||
|
17
logs/sqr.log
17
logs/sqr.log
@ -0,0 +1,17 @@
|
|||||||
|
896 371856
|
||||||
|
1344 196352
|
||||||
|
1792 122312
|
||||||
|
2240 83144
|
||||||
|
2688 60304
|
||||||
|
3136 45832
|
||||||
|
3584 12760
|
||||||
|
4032 10160
|
||||||
|
4480 8352
|
||||||
|
4928 6944
|
||||||
|
5376 5824
|
||||||
|
5824 5008
|
||||||
|
6272 4336
|
||||||
|
6720 3768
|
||||||
|
7168 3280
|
||||||
|
7616 2952
|
||||||
|
8064 2640
|
@ -1,17 +1,17 @@
|
|||||||
896 420464
|
896 372256
|
||||||
1344 224800
|
1344 196368
|
||||||
1792 142808
|
1792 122272
|
||||||
2240 97704
|
2240 82976
|
||||||
2688 71416
|
2688 60480
|
||||||
3136 54504
|
3136 45808
|
||||||
3584 38320
|
3584 33296
|
||||||
4032 32360
|
4032 27888
|
||||||
4480 27576
|
4480 23608
|
||||||
4928 23840
|
4928 20296
|
||||||
5376 20688
|
5376 17576
|
||||||
5824 18264
|
5824 15416
|
||||||
6272 16176
|
6272 13600
|
||||||
6720 14440
|
6720 12104
|
||||||
7168 11688
|
7168 10080
|
||||||
7616 10752
|
7616 9232
|
||||||
8064 9936
|
8064 8008
|
||||||
|
32
logs/sub.log
32
logs/sub.log
@ -1,16 +1,16 @@
|
|||||||
224 10876088
|
224 9325944
|
||||||
448 9103552
|
448 8075808
|
||||||
672 7823536
|
672 7054912
|
||||||
896 6724960
|
896 5757992
|
||||||
1120 5993496
|
1120 5081768
|
||||||
1344 5278984
|
1344 4669384
|
||||||
1568 4947736
|
1568 4422384
|
||||||
1792 4478384
|
1792 3900416
|
||||||
2016 4108840
|
2016 3548872
|
||||||
2240 3838696
|
2240 3428912
|
||||||
2464 3604128
|
2464 3216968
|
||||||
2688 3402192
|
2688 2905280
|
||||||
2912 3166568
|
2912 2782664
|
||||||
3136 3090672
|
3136 2591440
|
||||||
3360 2946720
|
3360 2475728
|
||||||
3584 2781288
|
3584 2282216
|
||||||
|
8
makefile
8
makefile
@ -6,7 +6,7 @@ CFLAGS += -I./ -Wall -W -Wshadow -O3 -funroll-loops
|
|||||||
#x86 optimizations [should be valid for any GCC install though]
|
#x86 optimizations [should be valid for any GCC install though]
|
||||||
CFLAGS += -fomit-frame-pointer
|
CFLAGS += -fomit-frame-pointer
|
||||||
|
|
||||||
VERSION=0.25
|
VERSION=0.26
|
||||||
|
|
||||||
default: libtommath.a
|
default: libtommath.a
|
||||||
|
|
||||||
@ -81,12 +81,6 @@ poster: poster.tex
|
|||||||
docs:
|
docs:
|
||||||
cd pics ; make pdfes
|
cd pics ; make pdfes
|
||||||
echo "hello" > tommath.ind
|
echo "hello" > tommath.ind
|
||||||
perl booker.pl
|
|
||||||
latex tommath > /dev/null
|
|
||||||
makeindex tommath
|
|
||||||
latex tommath > /dev/null
|
|
||||||
dvips -tB5 -D600 tommath
|
|
||||||
echo "hello" > tommath.ind
|
|
||||||
perl booker.pl PDF
|
perl booker.pl PDF
|
||||||
latex tommath > /dev/null
|
latex tommath > /dev/null
|
||||||
makeindex tommath
|
makeindex tommath
|
||||||
|
23
mtest/test.c~
Normal file
23
mtest/test.c~
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include "mpi.c"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
mp_int a, b;
|
||||||
|
int ix;
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
mp_init(&a);
|
||||||
|
mp_init(&b);
|
||||||
|
|
||||||
|
mp_set(&a, 0x1B);
|
||||||
|
mp_neg(&a, &a);
|
||||||
|
ix = 0;
|
||||||
|
mp_add_d(&a, ix, &b);
|
||||||
|
|
||||||
|
mp_toradix(&b, buf, 64);
|
||||||
|
printf("b == %s\n", buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -3,16 +3,16 @@
|
|||||||
default: pses
|
default: pses
|
||||||
|
|
||||||
design_process.ps: design_process.tif
|
design_process.ps: design_process.tif
|
||||||
tiff2ps -c -e design_process.tif > design_process.ps
|
tiff2ps -s -e design_process.tif > design_process.ps
|
||||||
|
|
||||||
sliding_window.ps: sliding_window.tif
|
sliding_window.ps: sliding_window.tif
|
||||||
tiff2ps -c -e sliding_window.tif > sliding_window.ps
|
tiff2ps -s -e sliding_window.tif > sliding_window.ps
|
||||||
|
|
||||||
expt_state.ps: expt_state.tif
|
expt_state.ps: expt_state.tif
|
||||||
tiff2ps -c -e expt_state.tif > expt_state.ps
|
tiff2ps -s -e expt_state.tif > expt_state.ps
|
||||||
|
|
||||||
primality.ps: primality.tif
|
primality.ps: primality.tif
|
||||||
tiff2ps -c -e primality.tif > primality.ps
|
tiff2ps -s -e primality.tif > primality.ps
|
||||||
|
|
||||||
design_process.pdf: design_process.ps
|
design_process.pdf: design_process.ps
|
||||||
epstopdf design_process.ps
|
epstopdf design_process.ps
|
||||||
|
35
pics/makefile~
Normal file
35
pics/makefile~
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# makes the images... yeah
|
||||||
|
|
||||||
|
default: pses
|
||||||
|
|
||||||
|
design_process.ps: design_process.tif
|
||||||
|
tiff2ps -s -e design_process.tif > design_process.ps
|
||||||
|
|
||||||
|
sliding_window.ps: sliding_window.tif
|
||||||
|
tiff2ps -e sliding_window.tif > sliding_window.ps
|
||||||
|
|
||||||
|
expt_state.ps: expt_state.tif
|
||||||
|
tiff2ps -e expt_state.tif > expt_state.ps
|
||||||
|
|
||||||
|
primality.ps: primality.tif
|
||||||
|
tiff2ps -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
|
||||||
|
|
BIN
poster.pdf
BIN
poster.pdf
Binary file not shown.
165
pre_gen/mpi.c
165
pre_gen/mpi.c
@ -241,7 +241,10 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
register mp_word *_W;
|
register mp_word *_W;
|
||||||
register mp_digit *tmpx;
|
register mp_digit *tmpx;
|
||||||
|
|
||||||
_W = W;
|
/* alias for the W[] array */
|
||||||
|
_W = W;
|
||||||
|
|
||||||
|
/* alias for the digits of x*/
|
||||||
tmpx = x->dp;
|
tmpx = x->dp;
|
||||||
|
|
||||||
/* copy the digits of a into W[0..a->used-1] */
|
/* copy the digits of a into W[0..a->used-1] */
|
||||||
@ -925,7 +928,6 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* old number of used digits in c */
|
/* old number of used digits in c */
|
||||||
oldused = c->used;
|
oldused = c->used;
|
||||||
|
|
||||||
@ -959,7 +961,6 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c)
|
|||||||
/* set final carry */
|
/* set final carry */
|
||||||
ix++;
|
ix++;
|
||||||
*tmpc++ = mu;
|
*tmpc++ = mu;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* a was negative and |a| < b */
|
/* a was negative and |a| < b */
|
||||||
c->used = 1;
|
c->used = 1;
|
||||||
@ -1217,12 +1218,12 @@ int
|
|||||||
mp_cmp (mp_int * a, mp_int * b)
|
mp_cmp (mp_int * a, mp_int * b)
|
||||||
{
|
{
|
||||||
/* compare based on sign */
|
/* compare based on sign */
|
||||||
if (a->sign == MP_NEG && b->sign == MP_ZPOS) {
|
if (a->sign != b->sign) {
|
||||||
return MP_LT;
|
if (a->sign == MP_NEG) {
|
||||||
}
|
return MP_LT;
|
||||||
|
} else {
|
||||||
if (a->sign == MP_ZPOS && b->sign == MP_NEG) {
|
return MP_GT;
|
||||||
return MP_GT;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compare digits */
|
/* compare digits */
|
||||||
@ -1301,23 +1302,30 @@ int
|
|||||||
mp_cmp_mag (mp_int * a, mp_int * b)
|
mp_cmp_mag (mp_int * a, mp_int * b)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
mp_digit *tmpa, *tmpb;
|
||||||
|
|
||||||
/* compare based on # of non-zero digits */
|
/* compare based on # of non-zero digits */
|
||||||
if (a->used > b->used) {
|
if (a->used > b->used) {
|
||||||
return MP_GT;
|
return MP_GT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->used < b->used) {
|
if (a->used < b->used) {
|
||||||
return MP_LT;
|
return MP_LT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* alias for a */
|
||||||
|
tmpa = a->dp + (a->used - 1);
|
||||||
|
|
||||||
|
/* alias for b */
|
||||||
|
tmpb = b->dp + (a->used - 1);
|
||||||
|
|
||||||
/* compare based on digits */
|
/* compare based on digits */
|
||||||
for (n = a->used - 1; n >= 0; n--) {
|
for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
|
||||||
if (a->dp[n] > b->dp[n]) {
|
if (*tmpa > *tmpb) {
|
||||||
return MP_GT;
|
return MP_GT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->dp[n] < b->dp[n]) {
|
if (*tmpa < *tmpb) {
|
||||||
return MP_LT;
|
return MP_LT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1594,8 +1602,9 @@ mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
|||||||
|
|
||||||
/* step 3. for i from n down to (t + 1) */
|
/* step 3. for i from n down to (t + 1) */
|
||||||
for (i = n; i >= (t + 1); i--) {
|
for (i = n; i >= (t + 1); i--) {
|
||||||
if (i > x.used)
|
if (i > x.used) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* step 3.1 if xi == yt then set q{i-t-1} to b-1,
|
/* step 3.1 if xi == yt then set q{i-t-1} to b-1,
|
||||||
* otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
|
* otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
|
||||||
@ -2111,6 +2120,8 @@ int mp_dr_is_modulus(mp_int *a)
|
|||||||
* The modulus must be of a special format [see manual]
|
* The modulus must be of a special format [see manual]
|
||||||
*
|
*
|
||||||
* Has been modified to use algorithm 7.10 from the LTM book instead
|
* Has been modified to use algorithm 7.10 from the LTM book instead
|
||||||
|
*
|
||||||
|
* Input x must be in the range 0 <= x <= (n-1)^2
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
|
mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
|
||||||
@ -2149,10 +2160,10 @@ top:
|
|||||||
*tmpx1++ = (mp_digit)(r & MP_MASK);
|
*tmpx1++ = (mp_digit)(r & MP_MASK);
|
||||||
mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
|
mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set final carry */
|
/* set final carry */
|
||||||
*tmpx1++ = mu;
|
*tmpx1++ = mu;
|
||||||
|
|
||||||
/* zero words above m */
|
/* zero words above m */
|
||||||
for (i = m + 1; i < x->used; i++) {
|
for (i = m + 1; i < x->used; i++) {
|
||||||
*tmpx1++ = 0;
|
*tmpx1++ = 0;
|
||||||
@ -3060,6 +3071,8 @@ int mp_init_multi(mp_int *mp, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
return res; /* Assumed ok, if error flagged above. */
|
return res; /* Assumed ok, if error flagged above. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* End: bn_mp_init_multi.c */
|
/* End: bn_mp_init_multi.c */
|
||||||
|
|
||||||
/* Start: bn_mp_init_size.c */
|
/* Start: bn_mp_init_size.c */
|
||||||
@ -3689,30 +3702,43 @@ ERR:
|
|||||||
*/
|
*/
|
||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* computes least common multiple as a*b/(a, b) */
|
/* computes least common multiple as |a*b|/(a, b) */
|
||||||
int
|
int
|
||||||
mp_lcm (mp_int * a, mp_int * b, mp_int * c)
|
mp_lcm (mp_int * a, mp_int * b, mp_int * c)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
mp_int t;
|
mp_int t1, t2;
|
||||||
|
|
||||||
|
|
||||||
if ((res = mp_init (&t)) != MP_OKAY) {
|
if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
|
/* t1 = get the GCD of the two inputs */
|
||||||
mp_clear (&t);
|
if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
|
||||||
return res;
|
goto __T;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((res = mp_gcd (a, b, c)) != MP_OKAY) {
|
/* divide the smallest by the GCD */
|
||||||
mp_clear (&t);
|
if (mp_cmp_mag(a, b) == MP_LT) {
|
||||||
return res;
|
/* store quotient in t2 such that t2 * b is the LCM */
|
||||||
|
if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
|
||||||
|
goto __T;
|
||||||
|
}
|
||||||
|
res = mp_mul(b, &t2, c);
|
||||||
|
} else {
|
||||||
|
/* store quotient in t2 such that t2 * a is the LCM */
|
||||||
|
if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
|
||||||
|
goto __T;
|
||||||
|
}
|
||||||
|
res = mp_mul(a, &t2, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = mp_div (&t, c, c, NULL);
|
/* fix the sign to positive */
|
||||||
mp_clear (&t);
|
c->sign = MP_ZPOS;
|
||||||
|
|
||||||
|
__T:
|
||||||
|
mp_clear_multi (&t1, &t2, NULL);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4012,7 +4038,14 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
x->used = digs;
|
x->used = digs;
|
||||||
|
|
||||||
for (ix = 0; ix < n->used; ix++) {
|
for (ix = 0; ix < n->used; ix++) {
|
||||||
/* mu = ai * m' mod b */
|
/* mu = ai * rho mod b
|
||||||
|
*
|
||||||
|
* The value of rho must be precalculated via
|
||||||
|
* bn_mp_montgomery_setup() such that
|
||||||
|
* it equals -1/n0 mod b this allows the
|
||||||
|
* following inner loop to reduce the
|
||||||
|
* input one digit at a time
|
||||||
|
*/
|
||||||
mu = ((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK;
|
mu = ((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK;
|
||||||
|
|
||||||
/* a = a + mu * m * b**i */
|
/* a = a + mu * m * b**i */
|
||||||
@ -4021,8 +4054,10 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
register mp_digit *tmpn, *tmpx, u;
|
register mp_digit *tmpn, *tmpx, u;
|
||||||
register mp_word r;
|
register mp_word r;
|
||||||
|
|
||||||
/* aliases */
|
/* alias for digits of the modulus */
|
||||||
tmpn = n->dp;
|
tmpn = n->dp;
|
||||||
|
|
||||||
|
/* alias for the digits of x [the input] */
|
||||||
tmpx = x->dp + ix;
|
tmpx = x->dp + ix;
|
||||||
|
|
||||||
/* set the carry to zero */
|
/* set the carry to zero */
|
||||||
@ -4030,12 +4065,20 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
|
|
||||||
/* Multiply and add in place */
|
/* Multiply and add in place */
|
||||||
for (iy = 0; iy < n->used; iy++) {
|
for (iy = 0; iy < n->used; iy++) {
|
||||||
|
/* compute product and sum */
|
||||||
r = ((mp_word)mu) * ((mp_word)*tmpn++) +
|
r = ((mp_word)mu) * ((mp_word)*tmpn++) +
|
||||||
((mp_word) u) + ((mp_word) * tmpx);
|
((mp_word) u) + ((mp_word) * tmpx);
|
||||||
|
|
||||||
|
/* get carry */
|
||||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||||
|
|
||||||
|
/* fix digit */
|
||||||
*tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
*tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
|
||||||
}
|
}
|
||||||
/* propagate carries */
|
/* At this point the ix'th digit of x should be zero */
|
||||||
|
|
||||||
|
|
||||||
|
/* propagate carries upwards as required*/
|
||||||
while (u) {
|
while (u) {
|
||||||
*tmpx += u;
|
*tmpx += u;
|
||||||
u = *tmpx >> DIGIT_BIT;
|
u = *tmpx >> DIGIT_BIT;
|
||||||
@ -4044,11 +4087,18 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* at this point the n.used'th least
|
||||||
|
* significant digits of x are all zero
|
||||||
|
* which means we can shift x to the
|
||||||
|
* right by n.used digits and the
|
||||||
|
* residue is unchanged.
|
||||||
|
*/
|
||||||
|
|
||||||
/* x = x/b**n.used */
|
/* x = x/b**n.used */
|
||||||
mp_clamp(x);
|
mp_clamp(x);
|
||||||
mp_rshd (x, n->used);
|
mp_rshd (x, n->used);
|
||||||
|
|
||||||
/* if A >= m then A = A - m */
|
/* if x >= n then x = x - n */
|
||||||
if (mp_cmp_mag (x, n) != MP_LT) {
|
if (mp_cmp_mag (x, n) != MP_LT) {
|
||||||
return s_mp_sub (x, n, x);
|
return s_mp_sub (x, n, x);
|
||||||
}
|
}
|
||||||
@ -4606,7 +4656,9 @@ mp_neg (mp_int * a, mp_int * b)
|
|||||||
if ((res = mp_copy (a, b)) != MP_OKAY) {
|
if ((res = mp_copy (a, b)) != MP_OKAY) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
|
if (mp_iszero(b) != 1) {
|
||||||
|
b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
|
||||||
|
}
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5360,10 +5412,18 @@ mp_read_signed_bin (mp_int * a, unsigned char *b, int c)
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
/* read magnitude */
|
||||||
if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
|
if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
a->sign = ((b[0] == (unsigned char) 0) ? MP_ZPOS : MP_NEG);
|
|
||||||
|
/* first byte is 0 for positive, non-zero for negative */
|
||||||
|
if (b[0] == 0) {
|
||||||
|
a->sign = MP_ZPOS;
|
||||||
|
} else {
|
||||||
|
a->sign = MP_NEG;
|
||||||
|
}
|
||||||
|
|
||||||
return MP_OKAY;
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5391,7 +5451,18 @@ int
|
|||||||
mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c)
|
mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
/* make sure there are at least two digits */
|
||||||
|
if (a->alloc < 2) {
|
||||||
|
if ((res = mp_grow(a, 2)) != MP_OKAY) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* zero the int */
|
||||||
mp_zero (a);
|
mp_zero (a);
|
||||||
|
|
||||||
|
/* read the bytes in */
|
||||||
while (c-- > 0) {
|
while (c-- > 0) {
|
||||||
if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
|
if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
|
||||||
return res;
|
return res;
|
||||||
@ -5804,6 +5875,7 @@ mp_set_int (mp_int * a, unsigned int b)
|
|||||||
int x, res;
|
int x, res;
|
||||||
|
|
||||||
mp_zero (a);
|
mp_zero (a);
|
||||||
|
|
||||||
/* set four bits at a time */
|
/* set four bits at a time */
|
||||||
for (x = 0; x < 8; x++) {
|
for (x = 0; x < 8; x++) {
|
||||||
/* shift the number up four bits */
|
/* shift the number up four bits */
|
||||||
@ -7414,15 +7486,15 @@ s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
|
|||||||
/* compute the columns of the output and propagate the carry */
|
/* compute the columns of the output and propagate the carry */
|
||||||
for (iy = 0; iy < pb; iy++) {
|
for (iy = 0; iy < pb; iy++) {
|
||||||
/* compute the column as a mp_word */
|
/* compute the column as a mp_word */
|
||||||
r = ((mp_word) *tmpt) +
|
r = ((mp_word)*tmpt) +
|
||||||
((mp_word)tmpx) * ((mp_word)*tmpy++) +
|
((mp_word)tmpx) * ((mp_word)*tmpy++) +
|
||||||
((mp_word) u);
|
((mp_word) u);
|
||||||
|
|
||||||
/* the new column is the lower part of the result */
|
/* the new column is the lower part of the result */
|
||||||
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||||
|
|
||||||
/* get the carry word from the result */
|
/* get the carry word from the result */
|
||||||
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
|
||||||
}
|
}
|
||||||
/* set carry if it is placed below digs */
|
/* set carry if it is placed below digs */
|
||||||
if (ix + iy < digs) {
|
if (ix + iy < digs) {
|
||||||
@ -7468,7 +7540,6 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
|
|||||||
mp_word r;
|
mp_word r;
|
||||||
mp_digit tmpx, *tmpt, *tmpy;
|
mp_digit tmpx, *tmpt, *tmpy;
|
||||||
|
|
||||||
|
|
||||||
/* can we use the fast multiplier? */
|
/* can we use the fast multiplier? */
|
||||||
if (((a->used + b->used + 1) < MP_WARRAY)
|
if (((a->used + b->used + 1) < MP_WARRAY)
|
||||||
&& MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
|
&& MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
|
||||||
@ -7497,13 +7568,15 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
|
|||||||
|
|
||||||
for (iy = digs - ix; iy < pb; iy++) {
|
for (iy = digs - ix; iy < pb; iy++) {
|
||||||
/* calculate the double precision result */
|
/* calculate the double precision result */
|
||||||
r = ((mp_word) * tmpt) + ((mp_word)tmpx) * ((mp_word)*tmpy++) + ((mp_word) u);
|
r = ((mp_word)*tmpt) +
|
||||||
|
((mp_word)tmpx) * ((mp_word)*tmpy++) +
|
||||||
|
((mp_word) u);
|
||||||
|
|
||||||
/* get the lower part */
|
/* get the lower part */
|
||||||
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||||
|
|
||||||
/* carry the carry */
|
/* carry the carry */
|
||||||
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
|
||||||
}
|
}
|
||||||
*tmpt = u;
|
*tmpt = u;
|
||||||
}
|
}
|
||||||
@ -7572,19 +7645,19 @@ s_mp_sqr (mp_int * a, mp_int * b)
|
|||||||
/* now calculate the double precision result, note we use
|
/* now calculate the double precision result, note we use
|
||||||
* addition instead of *2 since it's easier to optimize
|
* addition instead of *2 since it's easier to optimize
|
||||||
*/
|
*/
|
||||||
r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
|
r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
|
||||||
|
|
||||||
/* store lower part */
|
/* store lower part */
|
||||||
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||||
|
|
||||||
/* get carry */
|
/* get carry */
|
||||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||||
}
|
}
|
||||||
/* propagate upwards */
|
/* propagate upwards */
|
||||||
while (u != ((mp_digit) 0)) {
|
while (u != ((mp_digit) 0)) {
|
||||||
r = ((mp_word) * tmpt) + ((mp_word) u);
|
r = ((mp_word) *tmpt) + ((mp_word) u);
|
||||||
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
*tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user