From 8c97c9e1814ad3b7c5e99a7c951521d6ea079834 Mon Sep 17 00:00:00 2001 From: Tom St Denis Date: Fri, 28 Feb 2003 16:03:08 +0000 Subject: [PATCH] added libtommath-0.02 --- b.bat | 4 +- bn.c | 85 +- bn.h | 17 + bn.pdf | Bin 135254 -> 135995 bytes bn.tex | 58 +- changes.txt | 15 +- demo.c | 7 +- makefile | 2 +- mtest/logtab.h | 20 + mtest/mpi-config.h | 86 + mtest/mpi-types.h | 16 + mtest/mpi.c | 3981 ++++++++++++++++++++++++++++++++++++++++++++ mtest/mpi.h | 227 +++ mtest/mtest.c | 218 +++ 14 files changed, 4689 insertions(+), 47 deletions(-) create mode 100644 mtest/logtab.h create mode 100644 mtest/mpi-config.h create mode 100644 mtest/mpi-types.h create mode 100644 mtest/mpi.c create mode 100644 mtest/mpi.h create mode 100644 mtest/mtest.c diff --git a/b.bat b/b.bat index 1142d35..38c1120 100644 --- a/b.bat +++ b/b.bat @@ -1,3 +1,3 @@ nasm -f coff timer.asm -gcc -Wall -W -O3 -fomit-frame-pointer -funroll-loops -DTIMER demo.c bn.c timer.o -o demo -gcc -I./mtest/ -DU_MPI -Wall -W -O3 -fomit-frame-pointer -funroll-loops -DTIMER demo.c mtest/mpi.c timer.o -o mpidemo +gcc -Wall -W -O3 -fomit-frame-pointer -funroll-loops -DTIMER_X86 demo.c bn.c timer.o -o demo +gcc -I./mtest/ -DU_MPI -Wall -W -O3 -fomit-frame-pointer -funroll-loops -DTIMER_X86 demo.c mtest/mpi.c timer.o -o mpidemo diff --git a/bn.c b/bn.c index 82262f5..c0af1b7 100644 --- a/bn.c +++ b/bn.c @@ -168,8 +168,31 @@ int mp_init_copy(mp_int *a, mp_int *b) return mp_copy(b, a); } +/* b = |a| */ +int mp_abs(mp_int *a, mp_int *b) +{ + int res; + if ((res = mp_copy(a, b)) != MP_OKAY) { + return res; + } + b->sign = MP_ZPOS; + return MP_OKAY; +} + +/* b = -a */ +int mp_neg(mp_int *a, mp_int *b) +{ + int res; + if ((res = mp_copy(a, b)) != MP_OKAY) { + return res; + } + b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; + return MP_OKAY; +} + + /* compare maginitude of two ints (unsigned) */ -static int s_mp_cmp(mp_int *a, mp_int *b) +int mp_cmp_mag(mp_int *a, mp_int *b) { int n; @@ -200,7 +223,7 @@ int mp_cmp(mp_int *a, mp_int *b) } else if (a->sign == MP_ZPOS && b->sign == MP_NEG) { return MP_GT; } - return s_mp_cmp(a, b); + return mp_cmp_mag(a, b); } /* compare a digit */ @@ -500,7 +523,7 @@ static int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs) { mp_int t; int res, pa, pb, ix, iy; - mp_word W[512]; + mp_word W[512], *_W; mp_digit tmpx, *tmpt, *tmpy; // printf("\nHOLA\n"); @@ -519,8 +542,9 @@ static int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs) tmpx = a->dp[ix]; tmpt = &(t.dp[ix]); tmpy = b->dp; + _W = &(W[ix]); for (iy = 0; iy < pb; iy++) { - W[iy+ix] += ((mp_word)tmpx) * ((mp_word)*tmpy++); + *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++); } } @@ -590,7 +614,7 @@ static int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs) { mp_int t; int res, pa, pb, ix, iy; - mp_word W[512]; + mp_word W[512], *_W; mp_digit tmpx, *tmpt, *tmpy; if ((res = mp_init_size(&t, a->used + b->used + 1)) != MP_OKAY) { @@ -605,8 +629,9 @@ static int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs) tmpx = a->dp[ix]; tmpt = &(t.dp[digs]); tmpy = b->dp + (digs - ix); + _W = &(W[digs]); for (iy = digs - ix; iy < pb; iy++) { - W[ix+iy] += ((mp_word)tmpx) * ((mp_word)*tmpy++); + *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++); } } @@ -678,7 +703,7 @@ static int fast_s_mp_sqr(mp_int *a, mp_int *b) { mp_int t; int res, ix, iy, pa; - mp_word r, W[512]; + mp_word W[512], *_W; mp_digit tmpx, *tmpy; pa = a->used; @@ -694,9 +719,9 @@ static int fast_s_mp_sqr(mp_int *a, mp_int *b) W[ix+ix] += ((mp_word)a->dp[ix]) * ((mp_word)a->dp[ix]); tmpx = a->dp[ix]; tmpy = &(a->dp[ix+1]); + _W = &(W[ix+ix+1]); for (iy = ix + 1; iy < pa; iy++) { - r = ((mp_word)tmpx) * ((mp_word)*tmpy++); - W[ix+iy] += r + r; + *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++) << ((mp_word)1); } } for (ix = 1; ix < (pa+pa+1); ix++) { @@ -781,7 +806,7 @@ int mp_add(mp_int *a, mp_int *b, mp_int *c) c->sign = MP_ZPOS; } else if (sa == MP_ZPOS && sb == MP_NEG) { /* a + -b == a - b, but if b>a then we do it as -(b-a) */ - if (s_mp_cmp(a, b) == MP_LT) { + if (mp_cmp_mag(a, b) == MP_LT) { res = s_mp_sub(b, a, c); c->sign = MP_NEG; } else { @@ -790,7 +815,7 @@ int mp_add(mp_int *a, mp_int *b, mp_int *c) } } else if (sa == MP_NEG && sb == MP_ZPOS) { /* -a + b == b - a, but if a>b then we do it as -(a-b) */ - if (s_mp_cmp(a, b) == MP_GT) { + if (mp_cmp_mag(a, b) == MP_GT) { res = s_mp_sub(a, b, c); c->sign = MP_NEG; } else { @@ -816,7 +841,7 @@ int mp_sub(mp_int *a, mp_int *b, mp_int *c) /* handle four cases */ if (sa == MP_ZPOS && sb == MP_ZPOS) { /* both positive, a - b, but if b>a then we do -(b - a) */ - if (s_mp_cmp(a, b) == MP_LT) { + if (mp_cmp_mag(a, b) == MP_LT) { /* b>a */ res = s_mp_sub(b, a, c); c->sign = MP_NEG; @@ -834,7 +859,7 @@ int mp_sub(mp_int *a, mp_int *b, mp_int *c) c->sign = MP_NEG; } else { /* -a - -b == b - a, but if a>b == -(a - b) */ - if (s_mp_cmp(a, b) == MP_GT) { + if (mp_cmp_mag(a, b) == MP_GT) { res = s_mp_sub(a, b, c); c->sign = MP_NEG; } else { @@ -1023,7 +1048,7 @@ int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d) int res, n, t, i, norm, neg; /* if a < b then q=0, r = a */ - if (s_mp_cmp(a, b) == MP_LT) { + if (mp_cmp_mag(a, b) == MP_LT) { if (d != NULL) { res = mp_copy(a, d); d->sign = a->sign; @@ -1981,3 +2006,35 @@ int mp_toradix(mp_int *a, unsigned char *str, int radix) return MP_OKAY; } +/* returns size of ASCII reprensentation */ +int mp_radix_size(mp_int *a, int radix) +{ + int res, digs; + mp_int t; + mp_digit d; + + digs = 0; + + if (radix < 2 || radix > 64) { + return 0; + } + + if ((res = mp_init_copy(&t, a)) != MP_OKAY) { + return 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) { + return 0; + } + ++digs; + } + mp_clear(&t); + return digs + 1; +} + diff --git a/bn.h b/bn.h index 2c780e6..496f42d 100644 --- a/bn.h +++ b/bn.h @@ -128,9 +128,18 @@ int mp_mod_2d(mp_int *a, int b, mp_int *c); /* ---> Basic arithmetic <--- */ +/* b = -a */ +int mp_neg(mp_int *a, mp_int *b); + +/* b = |a| */ +int mp_abs(mp_int *a, mp_int *b); + /* compare a to b */ int mp_cmp(mp_int *a, mp_int *b); +/* compare |a| to |b| */ +int mp_cmp_mag(mp_int *a, mp_int *b); + /* c = a + b */ int mp_add(mp_int *a, mp_int *b, mp_int *c); @@ -215,6 +224,14 @@ int mp_to_signed_bin(mp_int *a, unsigned char *b); int mp_read_radix(mp_int *a, unsigned char *str, int radix); int mp_toradix(mp_int *a, unsigned char *str, int radix); +int mp_radix_size(mp_int *a, int radix); + +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) #define mp_tobinary(M, S) mp_toradix((M), (S), 2) #define mp_tooctal(M, S) mp_toradix((M), (S), 8) diff --git a/bn.pdf b/bn.pdf index 0550ee583d8471bd679528fd44b04d099ec951e0..43b9c7dce4cddd3c6f0f7b6d415b34fb56d41498 100644 GIT binary patch delta 71457 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�-|t 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 wfB@bX8jyXwFEr- + Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved + + Arbitrary precision integer arithmetic library + + $ID$ + */ + +#include "mpi.h" +#include +#include +#include + +#if MP_DEBUG +#include + +#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);} +#else +#define DIAG(T,V) +#endif + +/* + If MP_LOGTAB is not defined, use the math library to compute the + logarithms on the fly. Otherwise, use the static table below. + Pick which works best for your system. + */ +#if MP_LOGTAB + +/* {{{ s_logv_2[] - log table for 2 in various bases */ + +/* + A table of the logs of 2 for various bases (the 0 and 1 entries of + this table are meaningless and should not be referenced). + + This table is used to compute output lengths for the mp_toradix() + function. Since a number n in radix r takes up about log_r(n) + digits, we estimate the output size by taking the least integer + greater than log_r(n), where: + + log_r(n) = log_2(n) * log_r(2) + + This table, therefore, is a table of log_r(2) for 2 <= r <= 36, + which are the output bases supported. + */ + +#include "logtab.h" + +/* }}} */ +#define LOG_V_2(R) s_logv_2[(R)] + +#else + +#include +#define LOG_V_2(R) (log(2.0)/log(R)) + +#endif + +/* Default precision for newly created mp_int's */ +static unsigned int s_mp_defprec = MP_DEFPREC; + +/* {{{ Digit arithmetic macros */ + +/* + When adding and multiplying digits, the results can be larger than + can be contained in an mp_digit. Thus, an mp_word is used. These + macros mask off the upper and lower digits of the mp_word (the + mp_word may be more than 2 mp_digits wide, but we only concern + ourselves with the low-order 2 mp_digits) + + If your mp_word DOES have more than 2 mp_digits, you need to + uncomment the first line, and comment out the second. + */ + +/* #define CARRYOUT(W) (((W)>>DIGIT_BIT)&MP_DIGIT_MAX) */ +#define CARRYOUT(W) ((W)>>DIGIT_BIT) +#define ACCUM(W) ((W)&MP_DIGIT_MAX) + +/* }}} */ + +/* {{{ Comparison constants */ + +#define MP_LT -1 +#define MP_EQ 0 +#define MP_GT 1 + +/* }}} */ + +/* {{{ Constant strings */ + +/* Constant strings returned by mp_strerror() */ +static const char *mp_err_string[] = { + "unknown result code", /* say what? */ + "boolean true", /* MP_OKAY, MP_YES */ + "boolean false", /* MP_NO */ + "out of memory", /* MP_MEM */ + "argument out of range", /* MP_RANGE */ + "invalid input parameter", /* MP_BADARG */ + "result is undefined" /* MP_UNDEF */ +}; + +/* Value to digit maps for radix conversion */ + +/* s_dmap_1 - standard digits and letters */ +static const char *s_dmap_1 = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; + +#if 0 +/* s_dmap_2 - base64 ordering for digits */ +static const char *s_dmap_2 = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +#endif + +/* }}} */ + +/* {{{ Static function declarations */ + +/* + If MP_MACRO is false, these will be defined as actual functions; + otherwise, suitable macro definitions will be used. This works + around the fact that ANSI C89 doesn't support an 'inline' keyword + (although I hear C9x will ... about bloody time). At present, the + macro definitions are identical to the function bodies, but they'll + expand in place, instead of generating a function call. + + I chose these particular functions to be made into macros because + some profiling showed they are called a lot on a typical workload, + and yet they are primarily housekeeping. + */ +#if MP_MACRO == 0 + void s_mp_setz(mp_digit *dp, mp_size count); /* zero digits */ + void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count); /* copy */ + void *s_mp_alloc(size_t nb, size_t ni); /* general allocator */ + void s_mp_free(void *ptr); /* general free function */ +#else + + /* Even if these are defined as macros, we need to respect the settings + of the MP_MEMSET and MP_MEMCPY configuration options... + */ + #if MP_MEMSET == 0 + #define s_mp_setz(dp, count) \ + {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;} + #else + #define s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit)) + #endif /* MP_MEMSET */ + + #if MP_MEMCPY == 0 + #define s_mp_copy(sp, dp, count) \ + {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];} + #else + #define s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit)) + #endif /* MP_MEMCPY */ + + #define s_mp_alloc(nb, ni) calloc(nb, ni) + #define s_mp_free(ptr) {if(ptr) free(ptr);} +#endif /* MP_MACRO */ + +mp_err s_mp_grow(mp_int *mp, mp_size min); /* increase allocated size */ +mp_err s_mp_pad(mp_int *mp, mp_size min); /* left pad with zeroes */ + +void s_mp_clamp(mp_int *mp); /* clip leading zeroes */ + +void s_mp_exch(mp_int *a, mp_int *b); /* swap a and b in place */ + +mp_err s_mp_lshd(mp_int *mp, mp_size p); /* left-shift by p digits */ +void s_mp_rshd(mp_int *mp, mp_size p); /* right-shift by p digits */ +void s_mp_div_2d(mp_int *mp, mp_digit d); /* divide by 2^d in place */ +void s_mp_mod_2d(mp_int *mp, mp_digit d); /* modulo 2^d in place */ +mp_err s_mp_mul_2d(mp_int *mp, mp_digit d); /* multiply by 2^d in place*/ +void s_mp_div_2(mp_int *mp); /* divide by 2 in place */ +mp_err s_mp_mul_2(mp_int *mp); /* multiply by 2 in place */ +mp_digit s_mp_norm(mp_int *a, mp_int *b); /* normalize for division */ +mp_err s_mp_add_d(mp_int *mp, mp_digit d); /* unsigned digit addition */ +mp_err s_mp_sub_d(mp_int *mp, mp_digit d); /* unsigned digit subtract */ +mp_err s_mp_mul_d(mp_int *mp, mp_digit d); /* unsigned digit multiply */ +mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r); + /* unsigned digit divide */ +mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu); + /* Barrett reduction */ +mp_err s_mp_add(mp_int *a, mp_int *b); /* magnitude addition */ +mp_err s_mp_sub(mp_int *a, mp_int *b); /* magnitude subtract */ +mp_err s_mp_mul(mp_int *a, mp_int *b); /* magnitude multiply */ +#if 0 +void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len); + /* multiply buffers in place */ +#endif +#if MP_SQUARE +mp_err s_mp_sqr(mp_int *a); /* magnitude square */ +#else +#define s_mp_sqr(a) s_mp_mul(a, a) +#endif +mp_err s_mp_div(mp_int *a, mp_int *b); /* magnitude divide */ +mp_err s_mp_2expt(mp_int *a, mp_digit k); /* a = 2^k */ +int s_mp_cmp(mp_int *a, mp_int *b); /* magnitude comparison */ +int s_mp_cmp_d(mp_int *a, mp_digit d); /* magnitude digit compare */ +int s_mp_ispow2(mp_int *v); /* is v a power of 2? */ +int s_mp_ispow2d(mp_digit d); /* is d a power of 2? */ + +int s_mp_tovalue(char ch, int r); /* convert ch to value */ +char s_mp_todigit(int val, int r, int low); /* convert val to digit */ +int s_mp_outlen(int bits, int r); /* output length in bytes */ + +/* }}} */ + +/* {{{ Default precision manipulation */ + +unsigned int mp_get_prec(void) +{ + return s_mp_defprec; + +} /* end mp_get_prec() */ + +void mp_set_prec(unsigned int prec) +{ + if(prec == 0) + s_mp_defprec = MP_DEFPREC; + else + s_mp_defprec = prec; + +} /* end mp_set_prec() */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ mp_init(mp) */ + +/* + mp_init(mp) + + Initialize a new zero-valued mp_int. Returns MP_OKAY if successful, + MP_MEM if memory could not be allocated for the structure. + */ + +mp_err mp_init(mp_int *mp) +{ + return mp_init_size(mp, s_mp_defprec); + +} /* end mp_init() */ + +/* }}} */ + +/* {{{ mp_init_array(mp[], count) */ + +mp_err mp_init_array(mp_int mp[], int count) +{ + mp_err res; + int pos; + + ARGCHK(mp !=NULL && count > 0, MP_BADARG); + + for(pos = 0; pos < count; ++pos) { + if((res = mp_init(&mp[pos])) != MP_OKAY) + goto CLEANUP; + } + + return MP_OKAY; + + CLEANUP: + while(--pos >= 0) + mp_clear(&mp[pos]); + + return res; + +} /* end mp_init_array() */ + +/* }}} */ + +/* {{{ mp_init_size(mp, prec) */ + +/* + mp_init_size(mp, prec) + + Initialize a new zero-valued mp_int with at least the given + precision; returns MP_OKAY if successful, or MP_MEM if memory could + not be allocated for the structure. + */ + +mp_err mp_init_size(mp_int *mp, mp_size prec) +{ + ARGCHK(mp != NULL && prec > 0, MP_BADARG); + + if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL) + return MP_MEM; + + SIGN(mp) = MP_ZPOS; + USED(mp) = 1; + ALLOC(mp) = prec; + + return MP_OKAY; + +} /* end mp_init_size() */ + +/* }}} */ + +/* {{{ mp_init_copy(mp, from) */ + +/* + mp_init_copy(mp, from) + + Initialize mp as an exact copy of from. Returns MP_OKAY if + successful, MP_MEM if memory could not be allocated for the new + structure. + */ + +mp_err mp_init_copy(mp_int *mp, mp_int *from) +{ + ARGCHK(mp != NULL && from != NULL, MP_BADARG); + + if(mp == from) + return MP_OKAY; + + if((DIGITS(mp) = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL) + return MP_MEM; + + s_mp_copy(DIGITS(from), DIGITS(mp), USED(from)); + USED(mp) = USED(from); + ALLOC(mp) = USED(from); + SIGN(mp) = SIGN(from); + + return MP_OKAY; + +} /* end mp_init_copy() */ + +/* }}} */ + +/* {{{ mp_copy(from, to) */ + +/* + mp_copy(from, to) + + Copies the mp_int 'from' to the mp_int 'to'. It is presumed that + 'to' has already been initialized (if not, use mp_init_copy() + instead). If 'from' and 'to' are identical, nothing happens. + */ + +mp_err mp_copy(mp_int *from, mp_int *to) +{ + ARGCHK(from != NULL && to != NULL, MP_BADARG); + + if(from == to) + return MP_OKAY; + + { /* copy */ + mp_digit *tmp; + + /* + If the allocated buffer in 'to' already has enough space to hold + all the used digits of 'from', we'll re-use it to avoid hitting + the memory allocater more than necessary; otherwise, we'd have + to grow anyway, so we just allocate a hunk and make the copy as + usual + */ + if(ALLOC(to) >= USED(from)) { + s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from)); + s_mp_copy(DIGITS(from), DIGITS(to), USED(from)); + + } else { + if((tmp = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL) + return MP_MEM; + + s_mp_copy(DIGITS(from), tmp, USED(from)); + + if(DIGITS(to) != NULL) { +#if MP_CRYPTO + s_mp_setz(DIGITS(to), ALLOC(to)); +#endif + s_mp_free(DIGITS(to)); + } + + DIGITS(to) = tmp; + ALLOC(to) = USED(from); + } + + /* Copy the precision and sign from the original */ + USED(to) = USED(from); + SIGN(to) = SIGN(from); + } /* end copy */ + + return MP_OKAY; + +} /* end mp_copy() */ + +/* }}} */ + +/* {{{ mp_exch(mp1, mp2) */ + +/* + mp_exch(mp1, mp2) + + Exchange mp1 and mp2 without allocating any intermediate memory + (well, unless you count the stack space needed for this call and the + locals it creates...). This cannot fail. + */ + +void mp_exch(mp_int *mp1, mp_int *mp2) +{ +#if MP_ARGCHK == 2 + assert(mp1 != NULL && mp2 != NULL); +#else + if(mp1 == NULL || mp2 == NULL) + return; +#endif + + s_mp_exch(mp1, mp2); + +} /* end mp_exch() */ + +/* }}} */ + +/* {{{ mp_clear(mp) */ + +/* + mp_clear(mp) + + Release the storage used by an mp_int, and void its fields so that + if someone calls mp_clear() again for the same int later, we won't + get tollchocked. + */ + +void mp_clear(mp_int *mp) +{ + if(mp == NULL) + return; + + if(DIGITS(mp) != NULL) { +#if MP_CRYPTO + s_mp_setz(DIGITS(mp), ALLOC(mp)); +#endif + s_mp_free(DIGITS(mp)); + DIGITS(mp) = NULL; + } + + USED(mp) = 0; + ALLOC(mp) = 0; + +} /* end mp_clear() */ + +/* }}} */ + +/* {{{ mp_clear_array(mp[], count) */ + +void mp_clear_array(mp_int mp[], int count) +{ + ARGCHK(mp != NULL && count > 0, MP_BADARG); + + while(--count >= 0) + mp_clear(&mp[count]); + +} /* end mp_clear_array() */ + +/* }}} */ + +/* {{{ mp_zero(mp) */ + +/* + mp_zero(mp) + + Set mp to zero. Does not change the allocated size of the structure, + and therefore cannot fail (except on a bad argument, which we ignore) + */ +void mp_zero(mp_int *mp) +{ + if(mp == NULL) + return; + + s_mp_setz(DIGITS(mp), ALLOC(mp)); + USED(mp) = 1; + SIGN(mp) = MP_ZPOS; + +} /* end mp_zero() */ + +/* }}} */ + +/* {{{ mp_set(mp, d) */ + +void mp_set(mp_int *mp, mp_digit d) +{ + if(mp == NULL) + return; + + mp_zero(mp); + DIGIT(mp, 0) = d; + +} /* end mp_set() */ + +/* }}} */ + +/* {{{ mp_set_int(mp, z) */ + +mp_err mp_set_int(mp_int *mp, long z) +{ + int ix; + unsigned long v = abs(z); + mp_err res; + + ARGCHK(mp != NULL, MP_BADARG); + + mp_zero(mp); + if(z == 0) + return MP_OKAY; /* shortcut for zero */ + + for(ix = sizeof(long) - 1; ix >= 0; ix--) { + + if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY) + return res; + + res = s_mp_add_d(mp, + (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX)); + if(res != MP_OKAY) + return res; + + } + + if(z < 0) + SIGN(mp) = MP_NEG; + + return MP_OKAY; + +} /* end mp_set_int() */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Digit arithmetic */ + +/* {{{ mp_add_d(a, d, b) */ + +/* + mp_add_d(a, d, b) + + Compute the sum b = a + d, for a single digit d. Respects the sign of + its primary addend (single digits are unsigned anyway). + */ + +mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b) +{ + mp_err res = MP_OKAY; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + if(SIGN(b) == MP_ZPOS) { + res = s_mp_add_d(b, d); + } else if(s_mp_cmp_d(b, d) >= 0) { + res = s_mp_sub_d(b, d); + } else { + SIGN(b) = MP_ZPOS; + + DIGIT(b, 0) = d - DIGIT(b, 0); + } + + return res; + +} /* end mp_add_d() */ + +/* }}} */ + +/* {{{ mp_sub_d(a, d, b) */ + +/* + mp_sub_d(a, d, b) + + Compute the difference b = a - d, for a single digit d. Respects the + sign of its subtrahend (single digits are unsigned anyway). + */ + +mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + if(SIGN(b) == MP_NEG) { + if((res = s_mp_add_d(b, d)) != MP_OKAY) + return res; + + } else if(s_mp_cmp_d(b, d) >= 0) { + if((res = s_mp_sub_d(b, d)) != MP_OKAY) + return res; + + } else { + mp_neg(b, b); + + DIGIT(b, 0) = d - DIGIT(b, 0); + SIGN(b) = MP_NEG; + } + + if(s_mp_cmp_d(b, 0) == 0) + SIGN(b) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_sub_d() */ + +/* }}} */ + +/* {{{ mp_mul_d(a, d, b) */ + +/* + mp_mul_d(a, d, b) + + Compute the product b = a * d, for a single digit d. Respects the sign + of its multiplicand (single digits are unsigned anyway) + */ + +mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if(d == 0) { + mp_zero(b); + return MP_OKAY; + } + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + res = s_mp_mul_d(b, d); + + return res; + +} /* end mp_mul_d() */ + +/* }}} */ + +/* {{{ mp_mul_2(a, c) */ + +mp_err mp_mul_2(mp_int *a, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + return s_mp_mul_2(c); + +} /* end mp_mul_2() */ + +/* }}} */ + +/* {{{ mp_div_d(a, d, q, r) */ + +/* + mp_div_d(a, d, q, r) + + Compute the quotient q = a / d and remainder r = a mod d, for a + single digit d. Respects the sign of its divisor (single digits are + unsigned anyway). + */ + +mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r) +{ + mp_err res; + mp_digit rem; + int pow; + + ARGCHK(a != NULL, MP_BADARG); + + if(d == 0) + return MP_RANGE; + + /* Shortcut for powers of two ... */ + if((pow = s_mp_ispow2d(d)) >= 0) { + mp_digit mask; + + mask = (1 << pow) - 1; + rem = DIGIT(a, 0) & mask; + + if(q) { + mp_copy(a, q); + s_mp_div_2d(q, pow); + } + + if(r) + *r = rem; + + return MP_OKAY; + } + + /* + If the quotient is actually going to be returned, we'll try to + avoid hitting the memory allocator by copying the dividend into it + and doing the division there. This can't be any _worse_ than + always copying, and will sometimes be better (since it won't make + another copy) + + If it's not going to be returned, we need to allocate a temporary + to hold the quotient, which will just be discarded. + */ + if(q) { + if((res = mp_copy(a, q)) != MP_OKAY) + return res; + + res = s_mp_div_d(q, d, &rem); + if(s_mp_cmp_d(q, 0) == MP_EQ) + SIGN(q) = MP_ZPOS; + + } else { + mp_int qp; + + if((res = mp_init_copy(&qp, a)) != MP_OKAY) + return res; + + res = s_mp_div_d(&qp, d, &rem); + if(s_mp_cmp_d(&qp, 0) == 0) + SIGN(&qp) = MP_ZPOS; + + mp_clear(&qp); + } + + if(r) + *r = rem; + + return res; + +} /* end mp_div_d() */ + +/* }}} */ + +/* {{{ mp_div_2(a, c) */ + +/* + mp_div_2(a, c) + + Compute c = a / 2, disregarding the remainder. + */ + +mp_err mp_div_2(mp_int *a, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + s_mp_div_2(c); + + return MP_OKAY; + +} /* end mp_div_2() */ + +/* }}} */ + +/* {{{ mp_expt_d(a, d, b) */ + +mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c) +{ + mp_int s, x; + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_init(&s)) != MP_OKAY) + return res; + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + + DIGIT(&s, 0) = 1; + + while(d != 0) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + } + + s_mp_exch(&s, c); + +CLEANUP: + mp_clear(&x); +X: + mp_clear(&s); + + return res; + +} /* end mp_expt_d() */ + +/* }}} */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Full arithmetic */ + +/* {{{ mp_abs(a, b) */ + +/* + mp_abs(a, b) + + Compute b = |a|. 'a' and 'b' may be identical. + */ + +mp_err mp_abs(mp_int *a, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + SIGN(b) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_abs() */ + +/* }}} */ + +/* {{{ mp_neg(a, b) */ + +/* + mp_neg(a, b) + + Compute b = -a. 'a' and 'b' may be identical. + */ + +mp_err mp_neg(mp_int *a, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + if(s_mp_cmp_d(b, 0) == MP_EQ) + SIGN(b) = MP_ZPOS; + else + SIGN(b) = (SIGN(b) == MP_NEG) ? MP_ZPOS : MP_NEG; + + return MP_OKAY; + +} /* end mp_neg() */ + +/* }}} */ + +/* {{{ mp_add(a, b, c) */ + +/* + mp_add(a, b, c) + + Compute c = a + b. All parameters may be identical. + */ + +mp_err mp_add(mp_int *a, mp_int *b, mp_int *c) +{ + mp_err res; + int cmp; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */ + + /* Commutativity of addition lets us do this in either order, + so we avoid having to use a temporary even if the result + is supposed to replace the output + */ + if(c == b) { + if((res = s_mp_add(c, a)) != MP_OKAY) + return res; + } else { + if(c != a && (res = mp_copy(a, c)) != MP_OKAY) + return res; + + if((res = s_mp_add(c, b)) != MP_OKAY) + return res; + } + + } else if((cmp = s_mp_cmp(a, b)) > 0) { /* different sign: a > b */ + + /* If the output is going to be clobbered, we will use a temporary + variable; otherwise, we'll do it without touching the memory + allocator at all, if possible + */ + if(c == b) { + mp_int tmp; + + if((res = mp_init_copy(&tmp, a)) != MP_OKAY) + return res; + if((res = s_mp_sub(&tmp, b)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + s_mp_exch(&tmp, c); + mp_clear(&tmp); + + } else { + + if(c != a && (res = mp_copy(a, c)) != MP_OKAY) + return res; + if((res = s_mp_sub(c, b)) != MP_OKAY) + return res; + + } + + } else if(cmp == 0) { /* different sign, a == b */ + + mp_zero(c); + return MP_OKAY; + + } else { /* different sign: a < b */ + + /* See above... */ + if(c == a) { + mp_int tmp; + + if((res = mp_init_copy(&tmp, b)) != MP_OKAY) + return res; + if((res = s_mp_sub(&tmp, a)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + s_mp_exch(&tmp, c); + mp_clear(&tmp); + + } else { + + if(c != b && (res = mp_copy(b, c)) != MP_OKAY) + return res; + if((res = s_mp_sub(c, a)) != MP_OKAY) + return res; + + } + } + + if(USED(c) == 1 && DIGIT(c, 0) == 0) + SIGN(c) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_add() */ + +/* }}} */ + +/* {{{ mp_sub(a, b, c) */ + +/* + mp_sub(a, b, c) + + Compute c = a - b. All parameters may be identical. + */ + +mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c) +{ + mp_err res; + int cmp; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(SIGN(a) != SIGN(b)) { + if(c == a) { + if((res = s_mp_add(c, b)) != MP_OKAY) + return res; + } else { + if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) + return res; + if((res = s_mp_add(c, a)) != MP_OKAY) + return res; + SIGN(c) = SIGN(a); + } + + } else if((cmp = s_mp_cmp(a, b)) > 0) { /* Same sign, a > b */ + if(c == b) { + mp_int tmp; + + if((res = mp_init_copy(&tmp, a)) != MP_OKAY) + return res; + if((res = s_mp_sub(&tmp, b)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + s_mp_exch(&tmp, c); + mp_clear(&tmp); + + } else { + if(c != a && ((res = mp_copy(a, c)) != MP_OKAY)) + return res; + + if((res = s_mp_sub(c, b)) != MP_OKAY) + return res; + } + + } else if(cmp == 0) { /* Same sign, equal magnitude */ + mp_zero(c); + return MP_OKAY; + + } else { /* Same sign, b > a */ + if(c == a) { + mp_int tmp; + + if((res = mp_init_copy(&tmp, b)) != MP_OKAY) + return res; + + if((res = s_mp_sub(&tmp, a)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + s_mp_exch(&tmp, c); + mp_clear(&tmp); + + } else { + if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) + return res; + + if((res = s_mp_sub(c, a)) != MP_OKAY) + return res; + } + + SIGN(c) = !SIGN(b); + } + + if(USED(c) == 1 && DIGIT(c, 0) == 0) + SIGN(c) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_sub() */ + +/* }}} */ + +/* {{{ mp_mul(a, b, c) */ + +/* + mp_mul(a, b, c) + + Compute c = a * b. All parameters may be identical. + */ + +mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c) +{ + mp_err res; + mp_sign sgn; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + sgn = (SIGN(a) == SIGN(b)) ? MP_ZPOS : MP_NEG; + + if(c == b) { + if((res = s_mp_mul(c, a)) != MP_OKAY) + return res; + + } else { + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + if((res = s_mp_mul(c, b)) != MP_OKAY) + return res; + } + + if(sgn == MP_ZPOS || s_mp_cmp_d(c, 0) == MP_EQ) + SIGN(c) = MP_ZPOS; + else + SIGN(c) = sgn; + + return MP_OKAY; + +} /* end mp_mul() */ + +/* }}} */ + +/* {{{ mp_mul_2d(a, d, c) */ + +/* + mp_mul_2d(a, d, c) + + Compute c = a * 2^d. a may be the same as c. + */ + +mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + if(d == 0) + return MP_OKAY; + + return s_mp_mul_2d(c, d); + +} /* end mp_mul() */ + +/* }}} */ + +/* {{{ mp_sqr(a, b) */ + +#if MP_SQUARE +mp_err mp_sqr(mp_int *a, mp_int *b) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if((res = mp_copy(a, b)) != MP_OKAY) + return res; + + if((res = s_mp_sqr(b)) != MP_OKAY) + return res; + + SIGN(b) = MP_ZPOS; + + return MP_OKAY; + +} /* end mp_sqr() */ +#endif + +/* }}} */ + +/* {{{ mp_div(a, b, q, r) */ + +/* + mp_div(a, b, q, r) + + Compute q = a / b and r = a mod b. Input parameters may be re-used + as output parameters. If q or r is NULL, that portion of the + computation will be discarded (although it will still be computed) + + Pay no attention to the hacker behind the curtain. + */ + +mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r) +{ + mp_err res; + mp_int qtmp, rtmp; + int cmp; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + if(mp_cmp_z(b) == MP_EQ) + return MP_RANGE; + + /* If a <= b, we can compute the solution without division, and + avoid any memory allocation + */ + if((cmp = s_mp_cmp(a, b)) < 0) { + if(r) { + if((res = mp_copy(a, r)) != MP_OKAY) + return res; + } + + if(q) + mp_zero(q); + + return MP_OKAY; + + } else if(cmp == 0) { + + /* Set quotient to 1, with appropriate sign */ + if(q) { + int qneg = (SIGN(a) != SIGN(b)); + + mp_set(q, 1); + if(qneg) + SIGN(q) = MP_NEG; + } + + if(r) + mp_zero(r); + + return MP_OKAY; + } + + /* If we get here, it means we actually have to do some division */ + + /* Set up some temporaries... */ + if((res = mp_init_copy(&qtmp, a)) != MP_OKAY) + return res; + if((res = mp_init_copy(&rtmp, b)) != MP_OKAY) + goto CLEANUP; + + if((res = s_mp_div(&qtmp, &rtmp)) != MP_OKAY) + goto CLEANUP; + + /* Compute the signs for the output */ + SIGN(&rtmp) = SIGN(a); /* Sr = Sa */ + if(SIGN(a) == SIGN(b)) + SIGN(&qtmp) = MP_ZPOS; /* Sq = MP_ZPOS if Sa = Sb */ + else + SIGN(&qtmp) = MP_NEG; /* Sq = MP_NEG if Sa != Sb */ + + if(s_mp_cmp_d(&qtmp, 0) == MP_EQ) + SIGN(&qtmp) = MP_ZPOS; + if(s_mp_cmp_d(&rtmp, 0) == MP_EQ) + SIGN(&rtmp) = MP_ZPOS; + + /* Copy output, if it is needed */ + if(q) + s_mp_exch(&qtmp, q); + + if(r) + s_mp_exch(&rtmp, r); + +CLEANUP: + mp_clear(&rtmp); + mp_clear(&qtmp); + + return res; + +} /* end mp_div() */ + +/* }}} */ + +/* {{{ mp_div_2d(a, d, q, r) */ + +mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r) +{ + mp_err res; + + ARGCHK(a != NULL, MP_BADARG); + + if(q) { + if((res = mp_copy(a, q)) != MP_OKAY) + return res; + + s_mp_div_2d(q, d); + } + + if(r) { + if((res = mp_copy(a, r)) != MP_OKAY) + return res; + + s_mp_mod_2d(r, d); + } + + return MP_OKAY; + +} /* end mp_div_2d() */ + +/* }}} */ + +/* {{{ mp_expt(a, b, c) */ + +/* + mp_expt(a, b, c) + + Compute c = a ** b, that is, raise a to the b power. Uses a + standard iterative square-and-multiply technique. + */ + +mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int s, x; + mp_err res; + mp_digit d; + int dig, bit; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(mp_cmp_z(b) < 0) + return MP_RANGE; + + if((res = mp_init(&s)) != MP_OKAY) + return res; + + mp_set(&s, 1); + + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + + /* Loop over low-order digits in ascending order */ + for(dig = 0; dig < (USED(b) - 1); dig++) { + d = DIGIT(b, dig); + + /* Loop over bits of each non-maximal digit */ + for(bit = 0; bit < DIGIT_BIT; bit++) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + } + } + + /* Consider now the last digit... */ + d = DIGIT(b, dig); + + while(d) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + } + + if(mp_iseven(b)) + SIGN(&s) = SIGN(a); + + res = mp_copy(&s, c); + +CLEANUP: + mp_clear(&x); +X: + mp_clear(&s); + + return res; + +} /* end mp_expt() */ + +/* }}} */ + +/* {{{ mp_2expt(a, k) */ + +/* Compute a = 2^k */ + +mp_err mp_2expt(mp_int *a, mp_digit k) +{ + ARGCHK(a != NULL, MP_BADARG); + + return s_mp_2expt(a, k); + +} /* end mp_2expt() */ + +/* }}} */ + +/* {{{ mp_mod(a, m, c) */ + +/* + mp_mod(a, m, c) + + Compute c = a (mod m). Result will always be 0 <= c < m. + */ + +mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c) +{ + mp_err res; + int mag; + + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); + + if(SIGN(m) == MP_NEG) + return MP_RANGE; + + /* + If |a| > m, we need to divide to get the remainder and take the + absolute value. + + If |a| < m, we don't need to do any division, just copy and adjust + the sign (if a is negative). + + If |a| == m, we can simply set the result to zero. + + This order is intended to minimize the average path length of the + comparison chain on common workloads -- the most frequent cases are + that |a| != m, so we do those first. + */ + if((mag = s_mp_cmp(a, m)) > 0) { + if((res = mp_div(a, m, NULL, c)) != MP_OKAY) + return res; + + if(SIGN(c) == MP_NEG) { + if((res = mp_add(c, m, c)) != MP_OKAY) + return res; + } + + } else if(mag < 0) { + if((res = mp_copy(a, c)) != MP_OKAY) + return res; + + if(mp_cmp_z(a) < 0) { + if((res = mp_add(c, m, c)) != MP_OKAY) + return res; + + } + + } else { + mp_zero(c); + + } + + return MP_OKAY; + +} /* end mp_mod() */ + +/* }}} */ + +/* {{{ mp_mod_d(a, d, c) */ + +/* + mp_mod_d(a, d, c) + + Compute c = a (mod d). Result will always be 0 <= c < d + */ +mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c) +{ + mp_err res; + mp_digit rem; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if(s_mp_cmp_d(a, d) > 0) { + if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY) + return res; + + } else { + if(SIGN(a) == MP_NEG) + rem = d - DIGIT(a, 0); + else + rem = DIGIT(a, 0); + } + + if(c) + *c = rem; + + return MP_OKAY; + +} /* end mp_mod_d() */ + +/* }}} */ + +/* {{{ mp_sqrt(a, b) */ + +/* + mp_sqrt(a, b) + + Compute the integer square root of a, and store the result in b. + Uses an integer-arithmetic version of Newton's iterative linear + approximation technique to determine this value; the result has the + following two properties: + + b^2 <= a + (b+1)^2 >= a + + It is a range error to pass a negative value. + */ +mp_err mp_sqrt(mp_int *a, mp_int *b) +{ + mp_int x, t; + mp_err res; + + ARGCHK(a != NULL && b != NULL, MP_BADARG); + + /* Cannot take square root of a negative value */ + if(SIGN(a) == MP_NEG) + return MP_RANGE; + + /* Special cases for zero and one, trivial */ + if(mp_cmp_d(a, 0) == MP_EQ || mp_cmp_d(a, 1) == MP_EQ) + return mp_copy(a, b); + + /* Initialize the temporaries we'll use below */ + if((res = mp_init_size(&t, USED(a))) != MP_OKAY) + return res; + + /* Compute an initial guess for the iteration as a itself */ + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + +s_mp_rshd(&x, (USED(&x)/2)+1); +mp_add_d(&x, 1, &x); + + for(;;) { + /* t = (x * x) - a */ + mp_copy(&x, &t); /* can't fail, t is big enough for original x */ + if((res = mp_sqr(&t, &t)) != MP_OKAY || + (res = mp_sub(&t, a, &t)) != MP_OKAY) + goto CLEANUP; + + /* t = t / 2x */ + s_mp_mul_2(&x); + if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY) + goto CLEANUP; + s_mp_div_2(&x); + + /* Terminate the loop, if the quotient is zero */ + if(mp_cmp_z(&t) == MP_EQ) + break; + + /* x = x - t */ + if((res = mp_sub(&x, &t, &x)) != MP_OKAY) + goto CLEANUP; + + } + + /* Copy result to output parameter */ + mp_sub_d(&x, 1, &x); + s_mp_exch(&x, b); + + CLEANUP: + mp_clear(&x); + X: + mp_clear(&t); + + return res; + +} /* end mp_sqrt() */ + +/* }}} */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Modular arithmetic */ + +#if MP_MODARITH +/* {{{ mp_addmod(a, b, m, c) */ + +/* + mp_addmod(a, b, m, c) + + Compute c = (a + b) mod m + */ + +mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); + + if((res = mp_add(a, b, c)) != MP_OKAY) + return res; + if((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + + return MP_OKAY; + +} + +/* }}} */ + +/* {{{ mp_submod(a, b, m, c) */ + +/* + mp_submod(a, b, m, c) + + Compute c = (a - b) mod m + */ + +mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); + + if((res = mp_sub(a, b, c)) != MP_OKAY) + return res; + if((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + + return MP_OKAY; + +} + +/* }}} */ + +/* {{{ mp_mulmod(a, b, m, c) */ + +/* + mp_mulmod(a, b, m, c) + + Compute c = (a * b) mod m + */ + +mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG); + + if((res = mp_mul(a, b, c)) != MP_OKAY) + return res; + if((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + + return MP_OKAY; + +} + +/* }}} */ + +/* {{{ mp_sqrmod(a, m, c) */ + +#if MP_SQUARE +mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c) +{ + mp_err res; + + ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG); + + if((res = mp_sqr(a, c)) != MP_OKAY) + return res; + if((res = mp_mod(c, m, c)) != MP_OKAY) + return res; + + return MP_OKAY; + +} /* end mp_sqrmod() */ +#endif + +/* }}} */ + +/* {{{ mp_exptmod(a, b, m, c) */ + +/* + mp_exptmod(a, b, m, c) + + Compute c = (a ** b) mod m. Uses a standard square-and-multiply + method with modular reductions at each step. (This is basically the + same code as mp_expt(), except for the addition of the reductions) + + The modular reductions are done using Barrett's algorithm (see + s_mp_reduce() below for details) + */ + +mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c) +{ + mp_int s, x, mu; + mp_err res; + mp_digit d, *db = DIGITS(b); + mp_size ub = USED(b); + int dig, bit; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0) + return MP_RANGE; + + if((res = mp_init(&s)) != MP_OKAY) + return res; + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + if((res = mp_mod(&x, m, &x)) != MP_OKAY || + (res = mp_init(&mu)) != MP_OKAY) + goto MU; + + mp_set(&s, 1); + + /* mu = b^2k / m */ + s_mp_add_d(&mu, 1); + s_mp_lshd(&mu, 2 * USED(m)); + if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY) + goto CLEANUP; + + /* Loop over digits of b in ascending order, except highest order */ + for(dig = 0; dig < (ub - 1); dig++) { + d = *db++; + + /* Loop over the bits of the lower-order digits */ + for(bit = 0; bit < DIGIT_BIT; bit++) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + } + + /* Now do the last digit... */ + d = *db; + + while(d) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY) + goto CLEANUP; + if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + + d >>= 1; + + if((res = s_mp_sqr(&x)) != MP_OKAY) + goto CLEANUP; + if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY) + goto CLEANUP; + } + + s_mp_exch(&s, c); + + CLEANUP: + mp_clear(&mu); + MU: + mp_clear(&x); + X: + mp_clear(&s); + + return res; + +} /* end mp_exptmod() */ + +/* }}} */ + +/* {{{ mp_exptmod_d(a, d, m, c) */ + +mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c) +{ + mp_int s, x; + mp_err res; + + ARGCHK(a != NULL && c != NULL, MP_BADARG); + + if((res = mp_init(&s)) != MP_OKAY) + return res; + if((res = mp_init_copy(&x, a)) != MP_OKAY) + goto X; + + mp_set(&s, 1); + + while(d != 0) { + if(d & 1) { + if((res = s_mp_mul(&s, &x)) != MP_OKAY || + (res = mp_mod(&s, m, &s)) != MP_OKAY) + goto CLEANUP; + } + + d /= 2; + + if((res = s_mp_sqr(&x)) != MP_OKAY || + (res = mp_mod(&x, m, &x)) != MP_OKAY) + goto CLEANUP; + } + + s_mp_exch(&s, c); + +CLEANUP: + mp_clear(&x); +X: + mp_clear(&s); + + return res; + +} /* end mp_exptmod_d() */ + +/* }}} */ +#endif /* if MP_MODARITH */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Comparison functions */ + +/* {{{ mp_cmp_z(a) */ + +/* + mp_cmp_z(a) + + Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0. + */ + +int mp_cmp_z(mp_int *a) +{ + if(SIGN(a) == MP_NEG) + return MP_LT; + else if(USED(a) == 1 && DIGIT(a, 0) == 0) + return MP_EQ; + else + return MP_GT; + +} /* end mp_cmp_z() */ + +/* }}} */ + +/* {{{ mp_cmp_d(a, d) */ + +/* + mp_cmp_d(a, d) + + Compare a <=> d. Returns <0 if a0 if a>d + */ + +int mp_cmp_d(mp_int *a, mp_digit d) +{ + ARGCHK(a != NULL, MP_EQ); + + if(SIGN(a) == MP_NEG) + return MP_LT; + + return s_mp_cmp_d(a, d); + +} /* end mp_cmp_d() */ + +/* }}} */ + +/* {{{ mp_cmp(a, b) */ + +int mp_cmp(mp_int *a, mp_int *b) +{ + ARGCHK(a != NULL && b != NULL, MP_EQ); + + if(SIGN(a) == SIGN(b)) { + int mag; + + if((mag = s_mp_cmp(a, b)) == MP_EQ) + return MP_EQ; + + if(SIGN(a) == MP_ZPOS) + return mag; + else + return -mag; + + } else if(SIGN(a) == MP_ZPOS) { + return MP_GT; + } else { + return MP_LT; + } + +} /* end mp_cmp() */ + +/* }}} */ + +/* {{{ mp_cmp_mag(a, b) */ + +/* + mp_cmp_mag(a, b) + + Compares |a| <=> |b|, and returns an appropriate comparison result + */ + +int mp_cmp_mag(mp_int *a, mp_int *b) +{ + ARGCHK(a != NULL && b != NULL, MP_EQ); + + return s_mp_cmp(a, b); + +} /* end mp_cmp_mag() */ + +/* }}} */ + +/* {{{ mp_cmp_int(a, z) */ + +/* + This just converts z to an mp_int, and uses the existing comparison + routines. This is sort of inefficient, but it's not clear to me how + frequently this wil get used anyway. For small positive constants, + you can always use mp_cmp_d(), and for zero, there is mp_cmp_z(). + */ +int mp_cmp_int(mp_int *a, long z) +{ + mp_int tmp; + int out; + + ARGCHK(a != NULL, MP_EQ); + + mp_init(&tmp); mp_set_int(&tmp, z); + out = mp_cmp(a, &tmp); + mp_clear(&tmp); + + return out; + +} /* end mp_cmp_int() */ + +/* }}} */ + +/* {{{ mp_isodd(a) */ + +/* + mp_isodd(a) + + Returns a true (non-zero) value if a is odd, false (zero) otherwise. + */ +int mp_isodd(mp_int *a) +{ + ARGCHK(a != NULL, 0); + + return (DIGIT(a, 0) & 1); + +} /* end mp_isodd() */ + +/* }}} */ + +/* {{{ mp_iseven(a) */ + +int mp_iseven(mp_int *a) +{ + return !mp_isodd(a); + +} /* end mp_iseven() */ + +/* }}} */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ Number theoretic functions */ + +#if MP_NUMTH +/* {{{ mp_gcd(a, b, c) */ + +/* + Like the old mp_gcd() function, except computes the GCD using the + binary algorithm due to Josef Stein in 1961 (via Knuth). + */ +mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c) +{ + mp_err res; + mp_int u, v, t; + mp_size k = 0; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ) + return MP_RANGE; + if(mp_cmp_z(a) == MP_EQ) { + return mp_copy(b, c); + } else if(mp_cmp_z(b) == MP_EQ) { + return mp_copy(a, c); + } + + if((res = mp_init(&t)) != MP_OKAY) + return res; + if((res = mp_init_copy(&u, a)) != MP_OKAY) + goto U; + if((res = mp_init_copy(&v, b)) != MP_OKAY) + goto V; + + SIGN(&u) = MP_ZPOS; + SIGN(&v) = MP_ZPOS; + + /* Divide out common factors of 2 until at least 1 of a, b is even */ + while(mp_iseven(&u) && mp_iseven(&v)) { + s_mp_div_2(&u); + s_mp_div_2(&v); + ++k; + } + + /* Initialize t */ + if(mp_isodd(&u)) { + if((res = mp_copy(&v, &t)) != MP_OKAY) + goto CLEANUP; + + /* t = -v */ + if(SIGN(&v) == MP_ZPOS) + SIGN(&t) = MP_NEG; + else + SIGN(&t) = MP_ZPOS; + + } else { + if((res = mp_copy(&u, &t)) != MP_OKAY) + goto CLEANUP; + + } + + for(;;) { + while(mp_iseven(&t)) { + s_mp_div_2(&t); + } + + if(mp_cmp_z(&t) == MP_GT) { + if((res = mp_copy(&t, &u)) != MP_OKAY) + goto CLEANUP; + + } else { + if((res = mp_copy(&t, &v)) != MP_OKAY) + goto CLEANUP; + + /* v = -t */ + if(SIGN(&t) == MP_ZPOS) + SIGN(&v) = MP_NEG; + else + SIGN(&v) = MP_ZPOS; + } + + if((res = mp_sub(&u, &v, &t)) != MP_OKAY) + goto CLEANUP; + + if(s_mp_cmp_d(&t, 0) == MP_EQ) + break; + } + + s_mp_2expt(&v, k); /* v = 2^k */ + res = mp_mul(&u, &v, c); /* c = u * v */ + + CLEANUP: + mp_clear(&v); + V: + mp_clear(&u); + U: + mp_clear(&t); + + return res; + +} /* end mp_bgcd() */ + +/* }}} */ + +/* {{{ mp_lcm(a, b, c) */ + +/* We compute the least common multiple using the rule: + + ab = [a, b](a, b) + + ... by computing the product, and dividing out the gcd. + */ + +mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c) +{ + mp_int gcd, prod; + mp_err res; + + ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG); + + /* Set up temporaries */ + if((res = mp_init(&gcd)) != MP_OKAY) + return res; + if((res = mp_init(&prod)) != MP_OKAY) + goto GCD; + + if((res = mp_mul(a, b, &prod)) != MP_OKAY) + goto CLEANUP; + if((res = mp_gcd(a, b, &gcd)) != MP_OKAY) + goto CLEANUP; + + res = mp_div(&prod, &gcd, c, NULL); + + CLEANUP: + mp_clear(&prod); + GCD: + mp_clear(&gcd); + + return res; + +} /* end mp_lcm() */ + +/* }}} */ + +/* {{{ mp_xgcd(a, b, g, x, y) */ + +/* + mp_xgcd(a, b, g, x, y) + + Compute g = (a, b) and values x and y satisfying Bezout's identity + (that is, ax + by = g). This uses the extended binary GCD algorithm + based on the Stein algorithm used for mp_gcd() + */ + +mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y) +{ + mp_int gx, xc, yc, u, v, A, B, C, D; + mp_int *clean[9]; + mp_err res; + int last = -1; + + if(mp_cmp_z(b) == 0) + return MP_RANGE; + + /* Initialize all these variables we need */ + if((res = mp_init(&u)) != MP_OKAY) goto CLEANUP; + clean[++last] = &u; + if((res = mp_init(&v)) != MP_OKAY) goto CLEANUP; + clean[++last] = &v; + if((res = mp_init(&gx)) != MP_OKAY) goto CLEANUP; + clean[++last] = &gx; + if((res = mp_init(&A)) != MP_OKAY) goto CLEANUP; + clean[++last] = &A; + if((res = mp_init(&B)) != MP_OKAY) goto CLEANUP; + clean[++last] = &B; + if((res = mp_init(&C)) != MP_OKAY) goto CLEANUP; + clean[++last] = &C; + if((res = mp_init(&D)) != MP_OKAY) goto CLEANUP; + clean[++last] = &D; + if((res = mp_init_copy(&xc, a)) != MP_OKAY) goto CLEANUP; + clean[++last] = &xc; + mp_abs(&xc, &xc); + if((res = mp_init_copy(&yc, b)) != MP_OKAY) goto CLEANUP; + clean[++last] = &yc; + mp_abs(&yc, &yc); + + mp_set(&gx, 1); + + /* Divide by two until at least one of them is even */ + while(mp_iseven(&xc) && mp_iseven(&yc)) { + s_mp_div_2(&xc); + s_mp_div_2(&yc); + if((res = s_mp_mul_2(&gx)) != MP_OKAY) + goto CLEANUP; + } + + mp_copy(&xc, &u); + mp_copy(&yc, &v); + mp_set(&A, 1); mp_set(&D, 1); + + /* Loop through binary GCD algorithm */ + for(;;) { + while(mp_iseven(&u)) { + s_mp_div_2(&u); + + if(mp_iseven(&A) && mp_iseven(&B)) { + s_mp_div_2(&A); s_mp_div_2(&B); + } else { + if((res = mp_add(&A, &yc, &A)) != MP_OKAY) goto CLEANUP; + s_mp_div_2(&A); + if((res = mp_sub(&B, &xc, &B)) != MP_OKAY) goto CLEANUP; + s_mp_div_2(&B); + } + } + + while(mp_iseven(&v)) { + s_mp_div_2(&v); + + if(mp_iseven(&C) && mp_iseven(&D)) { + s_mp_div_2(&C); s_mp_div_2(&D); + } else { + if((res = mp_add(&C, &yc, &C)) != MP_OKAY) goto CLEANUP; + s_mp_div_2(&C); + if((res = mp_sub(&D, &xc, &D)) != MP_OKAY) goto CLEANUP; + s_mp_div_2(&D); + } + } + + if(mp_cmp(&u, &v) >= 0) { + if((res = mp_sub(&u, &v, &u)) != MP_OKAY) goto CLEANUP; + if((res = mp_sub(&A, &C, &A)) != MP_OKAY) goto CLEANUP; + if((res = mp_sub(&B, &D, &B)) != MP_OKAY) goto CLEANUP; + + } else { + if((res = mp_sub(&v, &u, &v)) != MP_OKAY) goto CLEANUP; + if((res = mp_sub(&C, &A, &C)) != MP_OKAY) goto CLEANUP; + if((res = mp_sub(&D, &B, &D)) != MP_OKAY) goto CLEANUP; + + } + + /* If we're done, copy results to output */ + if(mp_cmp_z(&u) == 0) { + if(x) + if((res = mp_copy(&C, x)) != MP_OKAY) goto CLEANUP; + + if(y) + if((res = mp_copy(&D, y)) != MP_OKAY) goto CLEANUP; + + if(g) + if((res = mp_mul(&gx, &v, g)) != MP_OKAY) goto CLEANUP; + + break; + } + } + + CLEANUP: + while(last >= 0) + mp_clear(clean[last--]); + + return res; + +} /* end mp_xgcd() */ + +/* }}} */ + +/* {{{ mp_invmod(a, m, c) */ + +/* + mp_invmod(a, m, c) + + Compute c = a^-1 (mod m), if there is an inverse for a (mod m). + This is equivalent to the question of whether (a, m) = 1. If not, + MP_UNDEF is returned, and there is no inverse. + */ + +mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c) +{ + mp_int g, x; + mp_err res; + + ARGCHK(a && m && c, MP_BADARG); + + if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0) + return MP_RANGE; + + if((res = mp_init(&g)) != MP_OKAY) + return res; + if((res = mp_init(&x)) != MP_OKAY) + goto X; + + if((res = mp_xgcd(a, m, &g, &x, NULL)) != MP_OKAY) + goto CLEANUP; + + if(mp_cmp_d(&g, 1) != MP_EQ) { + res = MP_UNDEF; + goto CLEANUP; + } + + res = mp_mod(&x, m, c); + SIGN(c) = SIGN(a); + +CLEANUP: + mp_clear(&x); +X: + mp_clear(&g); + + return res; + +} /* end mp_invmod() */ + +/* }}} */ +#endif /* if MP_NUMTH */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ mp_print(mp, ofp) */ + +#if MP_IOFUNC +/* + mp_print(mp, ofp) + + Print a textual representation of the given mp_int on the output + stream 'ofp'. Output is generated using the internal radix. + */ + +void mp_print(mp_int *mp, FILE *ofp) +{ + int ix; + + if(mp == NULL || ofp == NULL) + return; + + fputc((SIGN(mp) == MP_NEG) ? '-' : '+', ofp); + + for(ix = USED(mp) - 1; ix >= 0; ix--) { + fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix)); + } + +} /* end mp_print() */ + +#endif /* if MP_IOFUNC */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* {{{ More I/O Functions */ + +/* {{{ mp_read_signed_bin(mp, str, len) */ + +/* + mp_read_signed_bin(mp, str, len) + + Read in a raw value (base 256) into the given mp_int + */ + +mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len) +{ + mp_err res; + + ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); + + if((res = mp_read_unsigned_bin(mp, str + 1, len - 1)) == MP_OKAY) { + /* Get sign from first byte */ + if(str[0]) + SIGN(mp) = MP_NEG; + else + SIGN(mp) = MP_ZPOS; + } + + return res; + +} /* end mp_read_signed_bin() */ + +/* }}} */ + +/* {{{ mp_signed_bin_size(mp) */ + +int mp_signed_bin_size(mp_int *mp) +{ + ARGCHK(mp != NULL, 0); + + return mp_unsigned_bin_size(mp) + 1; + +} /* end mp_signed_bin_size() */ + +/* }}} */ + +/* {{{ mp_to_signed_bin(mp, str) */ + +mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str) +{ + ARGCHK(mp != NULL && str != NULL, MP_BADARG); + + /* Caller responsible for allocating enough memory (use mp_raw_size(mp)) */ + str[0] = (char)SIGN(mp); + + return mp_to_unsigned_bin(mp, str + 1); + +} /* end mp_to_signed_bin() */ + +/* }}} */ + +/* {{{ mp_read_unsigned_bin(mp, str, len) */ + +/* + mp_read_unsigned_bin(mp, str, len) + + Read in an unsigned value (base 256) into the given mp_int + */ + +mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len) +{ + int ix; + mp_err res; + + ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG); + + mp_zero(mp); + + for(ix = 0; ix < len; ix++) { + if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY) + return res; + + if((res = mp_add_d(mp, str[ix], mp)) != MP_OKAY) + return res; + } + + return MP_OKAY; + +} /* end mp_read_unsigned_bin() */ + +/* }}} */ + +/* {{{ mp_unsigned_bin_size(mp) */ + +int mp_unsigned_bin_size(mp_int *mp) +{ + mp_digit topdig; + int count; + + ARGCHK(mp != NULL, 0); + + /* Special case for the value zero */ + if(USED(mp) == 1 && DIGIT(mp, 0) == 0) + return 1; + + count = (USED(mp) - 1) * sizeof(mp_digit); + topdig = DIGIT(mp, USED(mp) - 1); + + while(topdig != 0) { + ++count; + topdig >>= CHAR_BIT; + } + + return count; + +} /* end mp_unsigned_bin_size() */ + +/* }}} */ + +/* {{{ mp_to_unsigned_bin(mp, str) */ + +mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str) +{ + mp_digit *dp, *end, d; + unsigned char *spos; + + ARGCHK(mp != NULL && str != NULL, MP_BADARG); + + dp = DIGITS(mp); + end = dp + USED(mp) - 1; + spos = str; + + /* Special case for zero, quick test */ + if(dp == end && *dp == 0) { + *str = '\0'; + return MP_OKAY; + } + + /* Generate digits in reverse order */ + while(dp < end) { + int ix; + + d = *dp; + for(ix = 0; ix < sizeof(mp_digit); ++ix) { + *spos = d & UCHAR_MAX; + d >>= CHAR_BIT; + ++spos; + } + + ++dp; + } + + /* Now handle last digit specially, high order zeroes are not written */ + d = *end; + while(d != 0) { + *spos = d & UCHAR_MAX; + d >>= CHAR_BIT; + ++spos; + } + + /* Reverse everything to get digits in the correct order */ + while(--spos > str) { + unsigned char t = *str; + *str = *spos; + *spos = t; + + ++str; + } + + return MP_OKAY; + +} /* end mp_to_unsigned_bin() */ + +/* }}} */ + +/* {{{ mp_count_bits(mp) */ + +int mp_count_bits(mp_int *mp) +{ + int len; + mp_digit d; + + ARGCHK(mp != NULL, MP_BADARG); + + len = DIGIT_BIT * (USED(mp) - 1); + d = DIGIT(mp, USED(mp) - 1); + + while(d != 0) { + ++len; + d >>= 1; + } + + return len; + +} /* end mp_count_bits() */ + +/* }}} */ + +/* {{{ mp_read_radix(mp, str, radix) */ + +/* + mp_read_radix(mp, str, radix) + + Read an integer from the given string, and set mp to the resulting + value. The input is presumed to be in base 10. Leading non-digit + characters are ignored, and the function reads until a non-digit + character or the end of the string. + */ + +mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix) +{ + int ix = 0, val = 0; + mp_err res; + mp_sign sig = MP_ZPOS; + + ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX, + MP_BADARG); + + mp_zero(mp); + + /* Skip leading non-digit characters until a digit or '-' or '+' */ + while(str[ix] && + (s_mp_tovalue(str[ix], radix) < 0) && + str[ix] != '-' && + str[ix] != '+') { + ++ix; + } + + if(str[ix] == '-') { + sig = MP_NEG; + ++ix; + } else if(str[ix] == '+') { + sig = MP_ZPOS; /* this is the default anyway... */ + ++ix; + } + + while((val = s_mp_tovalue(str[ix], radix)) >= 0) { + if((res = s_mp_mul_d(mp, radix)) != MP_OKAY) + return res; + if((res = s_mp_add_d(mp, val)) != MP_OKAY) + return res; + ++ix; + } + + if(s_mp_cmp_d(mp, 0) == MP_EQ) + SIGN(mp) = MP_ZPOS; + else + SIGN(mp) = sig; + + return MP_OKAY; + +} /* end mp_read_radix() */ + +/* }}} */ + +/* {{{ mp_radix_size(mp, radix) */ + +int mp_radix_size(mp_int *mp, int radix) +{ + int len; + ARGCHK(mp != NULL, 0); + + len = s_mp_outlen(mp_count_bits(mp), radix) + 1; /* for NUL terminator */ + + if(mp_cmp_z(mp) < 0) + ++len; /* for sign */ + + return len; + +} /* end mp_radix_size() */ + +/* }}} */ + +/* {{{ mp_value_radix_size(num, qty, radix) */ + +/* num = number of digits + qty = number of bits per digit + radix = target base + + Return the number of digits in the specified radix that would be + needed to express 'num' digits of 'qty' bits each. + */ +int mp_value_radix_size(int num, int qty, int radix) +{ + ARGCHK(num >= 0 && qty > 0 && radix >= 2 && radix <= MAX_RADIX, 0); + + return s_mp_outlen(num * qty, radix); + +} /* end mp_value_radix_size() */ + +/* }}} */ + +/* {{{ mp_toradix(mp, str, radix) */ + +mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix) +{ + int ix, pos = 0; + + ARGCHK(mp != NULL && str != NULL, MP_BADARG); + ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE); + + if(mp_cmp_z(mp) == MP_EQ) { + str[0] = '0'; + str[1] = '\0'; + } else { + mp_err res; + mp_int tmp; + mp_sign sgn; + mp_digit rem, rdx = (mp_digit)radix; + char ch; + + if((res = mp_init_copy(&tmp, mp)) != MP_OKAY) + return res; + + /* Save sign for later, and take absolute value */ + sgn = SIGN(&tmp); SIGN(&tmp) = MP_ZPOS; + + /* Generate output digits in reverse order */ + while(mp_cmp_z(&tmp) != 0) { + if((res = s_mp_div_d(&tmp, rdx, &rem)) != MP_OKAY) { + mp_clear(&tmp); + return res; + } + + /* Generate digits, use capital letters */ + ch = s_mp_todigit(rem, radix, 0); + + str[pos++] = ch; + } + + /* Add - sign if original value was negative */ + if(sgn == MP_NEG) + str[pos++] = '-'; + + /* Add trailing NUL to end the string */ + str[pos--] = '\0'; + + /* Reverse the digits and sign indicator */ + ix = 0; + while(ix < pos) { + char tmp = str[ix]; + + str[ix] = str[pos]; + str[pos] = tmp; + ++ix; + --pos; + } + + mp_clear(&tmp); + } + + return MP_OKAY; + +} /* end mp_toradix() */ + +/* }}} */ + +/* {{{ mp_char2value(ch, r) */ + +int mp_char2value(char ch, int r) +{ + return s_mp_tovalue(ch, r); + +} /* end mp_tovalue() */ + +/* }}} */ + +/* }}} */ + +/* {{{ mp_strerror(ec) */ + +/* + mp_strerror(ec) + + Return a string describing the meaning of error code 'ec'. The + string returned is allocated in static memory, so the caller should + not attempt to modify or free the memory associated with this + string. + */ +const char *mp_strerror(mp_err ec) +{ + int aec = (ec < 0) ? -ec : ec; + + /* Code values are negative, so the senses of these comparisons + are accurate */ + if(ec < MP_LAST_CODE || ec > MP_OKAY) { + return mp_err_string[0]; /* unknown error code */ + } else { + return mp_err_string[aec + 1]; + } + +} /* end mp_strerror() */ + +/* }}} */ + +/*========================================================================*/ +/*------------------------------------------------------------------------*/ +/* Static function definitions (internal use only) */ + +/* {{{ Memory management */ + +/* {{{ s_mp_grow(mp, min) */ + +/* Make sure there are at least 'min' digits allocated to mp */ +mp_err s_mp_grow(mp_int *mp, mp_size min) +{ + if(min > ALLOC(mp)) { + mp_digit *tmp; + + /* Set min to next nearest default precision block size */ + min = ((min + (s_mp_defprec - 1)) / s_mp_defprec) * s_mp_defprec; + + if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL) + return MP_MEM; + + s_mp_copy(DIGITS(mp), tmp, USED(mp)); + +#if MP_CRYPTO + s_mp_setz(DIGITS(mp), ALLOC(mp)); +#endif + s_mp_free(DIGITS(mp)); + DIGITS(mp) = tmp; + ALLOC(mp) = min; + } + + return MP_OKAY; + +} /* end s_mp_grow() */ + +/* }}} */ + +/* {{{ s_mp_pad(mp, min) */ + +/* Make sure the used size of mp is at least 'min', growing if needed */ +mp_err s_mp_pad(mp_int *mp, mp_size min) +{ + if(min > USED(mp)) { + mp_err res; + + /* Make sure there is room to increase precision */ + if(min > ALLOC(mp) && (res = s_mp_grow(mp, min)) != MP_OKAY) + return res; + + /* Increase precision; should already be 0-filled */ + USED(mp) = min; + } + + return MP_OKAY; + +} /* end s_mp_pad() */ + +/* }}} */ + +/* {{{ s_mp_setz(dp, count) */ + +#if MP_MACRO == 0 +/* Set 'count' digits pointed to by dp to be zeroes */ +void s_mp_setz(mp_digit *dp, mp_size count) +{ +#if MP_MEMSET == 0 + int ix; + + for(ix = 0; ix < count; ix++) + dp[ix] = 0; +#else + memset(dp, 0, count * sizeof(mp_digit)); +#endif + +} /* end s_mp_setz() */ +#endif + +/* }}} */ + +/* {{{ s_mp_copy(sp, dp, count) */ + +#if MP_MACRO == 0 +/* Copy 'count' digits from sp to dp */ +void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count) +{ +#if MP_MEMCPY == 0 + int ix; + + for(ix = 0; ix < count; ix++) + dp[ix] = sp[ix]; +#else + memcpy(dp, sp, count * sizeof(mp_digit)); +#endif + +} /* end s_mp_copy() */ +#endif + +/* }}} */ + +/* {{{ s_mp_alloc(nb, ni) */ + +#if MP_MACRO == 0 +/* Allocate ni records of nb bytes each, and return a pointer to that */ +void *s_mp_alloc(size_t nb, size_t ni) +{ + return calloc(nb, ni); + +} /* end s_mp_alloc() */ +#endif + +/* }}} */ + +/* {{{ s_mp_free(ptr) */ + +#if MP_MACRO == 0 +/* Free the memory pointed to by ptr */ +void s_mp_free(void *ptr) +{ + if(ptr) + free(ptr); + +} /* end s_mp_free() */ +#endif + +/* }}} */ + +/* {{{ s_mp_clamp(mp) */ + +/* Remove leading zeroes from the given value */ +void s_mp_clamp(mp_int *mp) +{ + mp_size du = USED(mp); + mp_digit *zp = DIGITS(mp) + du - 1; + + while(du > 1 && !*zp--) + --du; + + USED(mp) = du; + +} /* end s_mp_clamp() */ + + +/* }}} */ + +/* {{{ s_mp_exch(a, b) */ + +/* Exchange the data for a and b; (b, a) = (a, b) */ +void s_mp_exch(mp_int *a, mp_int *b) +{ + mp_int tmp; + + tmp = *a; + *a = *b; + *b = tmp; + +} /* end s_mp_exch() */ + +/* }}} */ + +/* }}} */ + +/* {{{ Arithmetic helpers */ + +/* {{{ s_mp_lshd(mp, p) */ + +/* + Shift mp leftward by p digits, growing if needed, and zero-filling + the in-shifted digits at the right end. This is a convenient + alternative to multiplication by powers of the radix + */ + +mp_err s_mp_lshd(mp_int *mp, mp_size p) +{ + mp_err res; + mp_size pos; + mp_digit *dp; + int ix; + + if(p == 0) + return MP_OKAY; + + if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY) + return res; + + pos = USED(mp) - 1; + dp = DIGITS(mp); + + /* Shift all the significant figures over as needed */ + for(ix = pos - p; ix >= 0; ix--) + dp[ix + p] = dp[ix]; + + /* Fill the bottom digits with zeroes */ + for(ix = 0; ix < p; ix++) + dp[ix] = 0; + + return MP_OKAY; + +} /* end s_mp_lshd() */ + +/* }}} */ + +/* {{{ s_mp_rshd(mp, p) */ + +/* + Shift mp rightward by p digits. Maintains the invariant that + digits above the precision are all zero. Digits shifted off the + end are lost. Cannot fail. + */ + +void s_mp_rshd(mp_int *mp, mp_size p) +{ + mp_size ix; + mp_digit *dp; + + if(p == 0) + return; + + /* Shortcut when all digits are to be shifted off */ + if(p >= USED(mp)) { + s_mp_setz(DIGITS(mp), ALLOC(mp)); + USED(mp) = 1; + SIGN(mp) = MP_ZPOS; + return; + } + + /* Shift all the significant figures over as needed */ + dp = DIGITS(mp); + for(ix = p; ix < USED(mp); ix++) + dp[ix - p] = dp[ix]; + + /* Fill the top digits with zeroes */ + ix -= p; + while(ix < USED(mp)) + dp[ix++] = 0; + + /* Strip off any leading zeroes */ + s_mp_clamp(mp); + +} /* end s_mp_rshd() */ + +/* }}} */ + +/* {{{ s_mp_div_2(mp) */ + +/* Divide by two -- take advantage of radix properties to do it fast */ +void s_mp_div_2(mp_int *mp) +{ + s_mp_div_2d(mp, 1); + +} /* end s_mp_div_2() */ + +/* }}} */ + +/* {{{ s_mp_mul_2(mp) */ + +mp_err s_mp_mul_2(mp_int *mp) +{ + int ix; + mp_digit kin = 0, kout, *dp = DIGITS(mp); + mp_err res; + + /* Shift digits leftward by 1 bit */ + for(ix = 0; ix < USED(mp); ix++) { + kout = (dp[ix] >> (DIGIT_BIT - 1)) & 1; + dp[ix] = (dp[ix] << 1) | kin; + + kin = kout; + } + + /* Deal with rollover from last digit */ + if(kin) { + if(ix >= ALLOC(mp)) { + if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY) + return res; + dp = DIGITS(mp); + } + + dp[ix] = kin; + USED(mp) += 1; + } + + return MP_OKAY; + +} /* end s_mp_mul_2() */ + +/* }}} */ + +/* {{{ s_mp_mod_2d(mp, d) */ + +/* + Remainder the integer by 2^d, where d is a number of bits. This + amounts to a bitwise AND of the value, and does not require the full + division code + */ +void s_mp_mod_2d(mp_int *mp, mp_digit d) +{ + unsigned int ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT); + unsigned int ix; + mp_digit dmask, *dp = DIGITS(mp); + + if(ndig >= USED(mp)) + return; + + /* Flush all the bits above 2^d in its digit */ + dmask = (1 << nbit) - 1; + dp[ndig] &= dmask; + + /* Flush all digits above the one with 2^d in it */ + for(ix = ndig + 1; ix < USED(mp); ix++) + dp[ix] = 0; + + s_mp_clamp(mp); + +} /* end s_mp_mod_2d() */ + +/* }}} */ + +/* {{{ s_mp_mul_2d(mp, d) */ + +/* + Multiply by the integer 2^d, where d is a number of bits. This + amounts to a bitwise shift of the value, and does not require the + full multiplication code. + */ +mp_err s_mp_mul_2d(mp_int *mp, mp_digit d) +{ + mp_err res; + mp_digit save, next, mask, *dp; + mp_size used; + int ix; + + if((res = s_mp_lshd(mp, d / DIGIT_BIT)) != MP_OKAY) + return res; + + dp = DIGITS(mp); used = USED(mp); + d %= DIGIT_BIT; + + mask = (1 << d) - 1; + + /* If the shift requires another digit, make sure we've got one to + work with */ + if((dp[used - 1] >> (DIGIT_BIT - d)) & mask) { + if((res = s_mp_grow(mp, used + 1)) != MP_OKAY) + return res; + dp = DIGITS(mp); + } + + /* Do the shifting... */ + save = 0; + for(ix = 0; ix < used; ix++) { + next = (dp[ix] >> (DIGIT_BIT - d)) & mask; + dp[ix] = (dp[ix] << d) | save; + save = next; + } + + /* If, at this point, we have a nonzero carryout into the next + digit, we'll increase the size by one digit, and store it... + */ + if(save) { + dp[used] = save; + USED(mp) += 1; + } + + s_mp_clamp(mp); + return MP_OKAY; + +} /* end s_mp_mul_2d() */ + +/* }}} */ + +/* {{{ s_mp_div_2d(mp, d) */ + +/* + Divide the integer by 2^d, where d is a number of bits. This + amounts to a bitwise shift of the value, and does not require the + full division code (used in Barrett reduction, see below) + */ +void s_mp_div_2d(mp_int *mp, mp_digit d) +{ + int ix; + mp_digit save, next, mask, *dp = DIGITS(mp); + + s_mp_rshd(mp, d / DIGIT_BIT); + d %= DIGIT_BIT; + + mask = (1 << d) - 1; + + save = 0; + for(ix = USED(mp) - 1; ix >= 0; ix--) { + next = dp[ix] & mask; + dp[ix] = (dp[ix] >> d) | (save << (DIGIT_BIT - d)); + save = next; + } + + s_mp_clamp(mp); + +} /* end s_mp_div_2d() */ + +/* }}} */ + +/* {{{ s_mp_norm(a, b) */ + +/* + s_mp_norm(a, b) + + Normalize a and b for division, where b is the divisor. In order + that we might make good guesses for quotient digits, we want the + leading digit of b to be at least half the radix, which we + accomplish by multiplying a and b by a constant. This constant is + returned (so that it can be divided back out of the remainder at the + end of the division process). + + We multiply by the smallest power of 2 that gives us a leading digit + at least half the radix. By choosing a power of 2, we simplify the + multiplication and division steps to simple shifts. + */ +mp_digit s_mp_norm(mp_int *a, mp_int *b) +{ + mp_digit t, d = 0; + + t = DIGIT(b, USED(b) - 1); + while(t < (RADIX / 2)) { + t <<= 1; + ++d; + } + + if(d != 0) { + s_mp_mul_2d(a, d); + s_mp_mul_2d(b, d); + } + + return d; + +} /* end s_mp_norm() */ + +/* }}} */ + +/* }}} */ + +/* {{{ Primitive digit arithmetic */ + +/* {{{ s_mp_add_d(mp, d) */ + +/* Add d to |mp| in place */ +mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */ +{ + mp_word w, k = 0; + mp_size ix = 1, used = USED(mp); + mp_digit *dp = DIGITS(mp); + + w = dp[0] + d; + dp[0] = ACCUM(w); + k = CARRYOUT(w); + + while(ix < used && k) { + w = dp[ix] + k; + dp[ix] = ACCUM(w); + k = CARRYOUT(w); + ++ix; + } + + if(k != 0) { + mp_err res; + + if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY) + return res; + + DIGIT(mp, ix) = k; + } + + return MP_OKAY; + +} /* end s_mp_add_d() */ + +/* }}} */ + +/* {{{ s_mp_sub_d(mp, d) */ + +/* Subtract d from |mp| in place, assumes |mp| > d */ +mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */ +{ + mp_word w, b = 0; + mp_size ix = 1, used = USED(mp); + mp_digit *dp = DIGITS(mp); + + /* Compute initial subtraction */ + w = (RADIX + dp[0]) - d; + b = CARRYOUT(w) ? 0 : 1; + dp[0] = ACCUM(w); + + /* Propagate borrows leftward */ + while(b && ix < used) { + w = (RADIX + dp[ix]) - b; + b = CARRYOUT(w) ? 0 : 1; + dp[ix] = ACCUM(w); + ++ix; + } + + /* Remove leading zeroes */ + s_mp_clamp(mp); + + /* If we have a borrow out, it's a violation of the input invariant */ + if(b) + return MP_RANGE; + else + return MP_OKAY; + +} /* end s_mp_sub_d() */ + +/* }}} */ + +/* {{{ s_mp_mul_d(a, d) */ + +/* Compute a = a * d, single digit multiplication */ +mp_err s_mp_mul_d(mp_int *a, mp_digit d) +{ + mp_word w, k = 0; + mp_size ix, max; + mp_err res; + mp_digit *dp = DIGITS(a); + + /* + Single-digit multiplication will increase the precision of the + output by at most one digit. However, we can detect when this + will happen -- if the high-order digit of a, times d, gives a + two-digit result, then the precision of the result will increase; + otherwise it won't. We use this fact to avoid calling s_mp_pad() + unless absolutely necessary. + */ + max = USED(a); + w = dp[max - 1] * d; + if(CARRYOUT(w) != 0) { + if((res = s_mp_pad(a, max + 1)) != MP_OKAY) + return res; + dp = DIGITS(a); + } + + for(ix = 0; ix < max; ix++) { + w = (dp[ix] * d) + k; + dp[ix] = ACCUM(w); + k = CARRYOUT(w); + } + + /* If there is a precision increase, take care of it here; the above + test guarantees we have enough storage to do this safely. + */ + if(k) { + dp[max] = k; + USED(a) = max + 1; + } + + s_mp_clamp(a); + + return MP_OKAY; + +} /* end s_mp_mul_d() */ + +/* }}} */ + +/* {{{ s_mp_div_d(mp, d, r) */ + +/* + s_mp_div_d(mp, d, r) + + Compute the quotient mp = mp / d and remainder r = mp mod d, for a + single digit d. If r is null, the remainder will be discarded. + */ + +mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r) +{ + mp_word w = 0, t; + mp_int quot; + mp_err res; + mp_digit *dp = DIGITS(mp), *qp; + int ix; + + if(d == 0) + return MP_RANGE; + + /* Make room for the quotient */ + if((res = mp_init_size(", USED(mp))) != MP_OKAY) + return res; + + USED(") = USED(mp); /* so clamping will work below */ + qp = DIGITS("); + + /* Divide without subtraction */ + for(ix = USED(mp) - 1; ix >= 0; ix--) { + w = (w << DIGIT_BIT) | dp[ix]; + + if(w >= d) { + t = w / d; + w = w % d; + } else { + t = 0; + } + + qp[ix] = t; + } + + /* Deliver the remainder, if desired */ + if(r) + *r = w; + + s_mp_clamp("); + mp_exch(", mp); + mp_clear("); + + return MP_OKAY; + +} /* end s_mp_div_d() */ + +/* }}} */ + +/* }}} */ + +/* {{{ Primitive full arithmetic */ + +/* {{{ s_mp_add(a, b) */ + +/* Compute a = |a| + |b| */ +mp_err s_mp_add(mp_int *a, mp_int *b) /* magnitude addition */ +{ + mp_word w = 0; + mp_digit *pa, *pb; + mp_size ix, used = USED(b); + mp_err res; + + /* Make sure a has enough precision for the output value */ + if((used > USED(a)) && (res = s_mp_pad(a, used)) != MP_OKAY) + return res; + + /* + Add up all digits up to the precision of b. If b had initially + the same precision as a, or greater, we took care of it by the + padding step above, so there is no problem. If b had initially + less precision, we'll have to make sure the carry out is duly + propagated upward among the higher-order digits of the sum. + */ + pa = DIGITS(a); + pb = DIGITS(b); + for(ix = 0; ix < used; ++ix) { + w += *pa + *pb++; + *pa++ = ACCUM(w); + w = CARRYOUT(w); + } + + /* If we run out of 'b' digits before we're actually done, make + sure the carries get propagated upward... + */ + used = USED(a); + while(w && ix < used) { + w += *pa; + *pa++ = ACCUM(w); + w = CARRYOUT(w); + ++ix; + } + + /* If there's an overall carry out, increase precision and include + it. We could have done this initially, but why touch the memory + allocator unless we're sure we have to? + */ + if(w) { + if((res = s_mp_pad(a, used + 1)) != MP_OKAY) + return res; + + DIGIT(a, ix) = w; /* pa may not be valid after s_mp_pad() call */ + } + + return MP_OKAY; + +} /* end s_mp_add() */ + +/* }}} */ + +/* {{{ s_mp_sub(a, b) */ + +/* Compute a = |a| - |b|, assumes |a| >= |b| */ +mp_err s_mp_sub(mp_int *a, mp_int *b) /* magnitude subtract */ +{ + mp_word w = 0; + mp_digit *pa, *pb; + mp_size ix, used = USED(b); + + /* + Subtract and propagate borrow. Up to the precision of b, this + accounts for the digits of b; after that, we just make sure the + carries get to the right place. This saves having to pad b out to + the precision of a just to make the loops work right... + */ + pa = DIGITS(a); + pb = DIGITS(b); + + for(ix = 0; ix < used; ++ix) { + w = (RADIX + *pa) - w - *pb++; + *pa++ = ACCUM(w); + w = CARRYOUT(w) ? 0 : 1; + } + + used = USED(a); + while(ix < used) { + w = RADIX + *pa - w; + *pa++ = ACCUM(w); + w = CARRYOUT(w) ? 0 : 1; + ++ix; + } + + /* Clobber any leading zeroes we created */ + s_mp_clamp(a); + + /* + If there was a borrow out, then |b| > |a| in violation + of our input invariant. We've already done the work, + but we'll at least complain about it... + */ + if(w) + return MP_RANGE; + else + return MP_OKAY; + +} /* end s_mp_sub() */ + +/* }}} */ + +mp_err s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu) +{ + mp_int q; + mp_err res; + mp_size um = USED(m); + + if((res = mp_init_copy(&q, x)) != MP_OKAY) + return res; + + s_mp_rshd(&q, um - 1); /* q1 = x / b^(k-1) */ + s_mp_mul(&q, mu); /* q2 = q1 * mu */ + s_mp_rshd(&q, um + 1); /* q3 = q2 / b^(k+1) */ + + /* x = x mod b^(k+1), quick (no division) */ + s_mp_mod_2d(x, (mp_digit)(DIGIT_BIT * (um + 1))); + + /* q = q * m mod b^(k+1), quick (no division), uses the short multiplier */ +#ifndef SHRT_MUL + s_mp_mul(&q, m); + s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1))); +#else + s_mp_mul_dig(&q, m, um + 1); +#endif + + /* x = x - q */ + if((res = mp_sub(x, &q, x)) != MP_OKAY) + goto CLEANUP; + + /* If x < 0, add b^(k+1) to it */ + if(mp_cmp_z(x) < 0) { + mp_set(&q, 1); + if((res = s_mp_lshd(&q, um + 1)) != MP_OKAY) + goto CLEANUP; + if((res = mp_add(x, &q, x)) != MP_OKAY) + goto CLEANUP; + } + + /* Back off if it's too big */ + while(mp_cmp(x, m) >= 0) { + if((res = s_mp_sub(x, m)) != MP_OKAY) + break; + } + + CLEANUP: + mp_clear(&q); + + return res; + +} /* end s_mp_reduce() */ + + + +/* {{{ s_mp_mul(a, b) */ + +/* Compute a = |a| * |b| */ +mp_err s_mp_mul(mp_int *a, mp_int *b) +{ + mp_word w, k = 0; + mp_int tmp; + mp_err res; + mp_size ix, jx, ua = USED(a), ub = USED(b); + mp_digit *pa, *pb, *pt, *pbt; + + if((res = mp_init_size(&tmp, ua + ub)) != MP_OKAY) + return res; + + /* This has the effect of left-padding with zeroes... */ + USED(&tmp) = ua + ub; + + /* We're going to need the base value each iteration */ + pbt = DIGITS(&tmp); + + /* Outer loop: Digits of b */ + + pb = DIGITS(b); + for(ix = 0; ix < ub; ++ix, ++pb) { + if(*pb == 0) + continue; + + /* Inner product: Digits of a */ + pa = DIGITS(a); + for(jx = 0; jx < ua; ++jx, ++pa) { + pt = pbt + ix + jx; + w = *pb * *pa + k + *pt; + *pt = ACCUM(w); + k = CARRYOUT(w); + } + + pbt[ix + jx] = k; + k = 0; + } + + s_mp_clamp(&tmp); + s_mp_exch(&tmp, a); + + mp_clear(&tmp); + + return MP_OKAY; + +} /* end s_mp_mul() */ + +/* }}} */ + +/* {{{ s_mp_kmul(a, b, out, len) */ + +#if 0 +void s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len) +{ + mp_word w, k = 0; + mp_size ix, jx; + mp_digit *pa, *pt; + + for(ix = 0; ix < len; ++ix, ++b) { + if(*b == 0) + continue; + + pa = a; + for(jx = 0; jx < len; ++jx, ++pa) { + pt = out + ix + jx; + w = *b * *pa + k + *pt; + *pt = ACCUM(w); + k = CARRYOUT(w); + } + + out[ix + jx] = k; + k = 0; + } + +} /* end s_mp_kmul() */ +#endif + +/* }}} */ + +/* {{{ s_mp_sqr(a) */ + +/* + Computes the square of a, in place. This can be done more + efficiently than a general multiplication, because many of the + computation steps are redundant when squaring. The inner product + step is a bit more complicated, but we save a fair number of + iterations of the multiplication loop. + */ +#if MP_SQUARE +mp_err s_mp_sqr(mp_int *a) +{ + mp_word w, k = 0; + mp_int tmp; + mp_err res; + mp_size ix, jx, kx, used = USED(a); + mp_digit *pa1, *pa2, *pt, *pbt; + + if((res = mp_init_size(&tmp, 2 * used)) != MP_OKAY) + return res; + + /* Left-pad with zeroes */ + USED(&tmp) = 2 * used; + + /* We need the base value each time through the loop */ + pbt = DIGITS(&tmp); + + pa1 = DIGITS(a); + for(ix = 0; ix < used; ++ix, ++pa1) { + if(*pa1 == 0) + continue; + + w = DIGIT(&tmp, ix + ix) + (*pa1 * *pa1); + + pbt[ix + ix] = ACCUM(w); + k = CARRYOUT(w); + + /* + The inner product is computed as: + + (C, S) = t[i,j] + 2 a[i] a[j] + C + + This can overflow what can be represented in an mp_word, and + since C arithmetic does not provide any way to check for + overflow, we have to check explicitly for overflow conditions + before they happen. + */ + for(jx = ix + 1, pa2 = DIGITS(a) + jx; jx < used; ++jx, ++pa2) { + mp_word u = 0, v; + + /* Store this in a temporary to avoid indirections later */ + pt = pbt + ix + jx; + + /* Compute the multiplicative step */ + w = *pa1 * *pa2; + + /* If w is more than half MP_WORD_MAX, the doubling will + overflow, and we need to record a carry out into the next + word */ + u = (w >> (MP_WORD_BIT - 1)) & 1; + + /* Double what we've got, overflow will be ignored as defined + for C arithmetic (we've already noted if it is to occur) + */ + w *= 2; + + /* Compute the additive step */ + v = *pt + k; + + /* If we do not already have an overflow carry, check to see + if the addition will cause one, and set the carry out if so + */ + u |= ((MP_WORD_MAX - v) < w); + + /* Add in the rest, again ignoring overflow */ + w += v; + + /* Set the i,j digit of the output */ + *pt = ACCUM(w); + + /* Save carry information for the next iteration of the loop. + This is why k must be an mp_word, instead of an mp_digit */ + k = CARRYOUT(w) | (u << DIGIT_BIT); + + } /* for(jx ...) */ + + /* Set the last digit in the cycle and reset the carry */ + k = DIGIT(&tmp, ix + jx) + k; + pbt[ix + jx] = ACCUM(k); + k = CARRYOUT(k); + + /* If we are carrying out, propagate the carry to the next digit + in the output. This may cascade, so we have to be somewhat + circumspect -- but we will have enough precision in the output + that we won't overflow + */ + kx = 1; + while(k) { + k = pbt[ix + jx + kx] + 1; + pbt[ix + jx + kx] = ACCUM(k); + k = CARRYOUT(k); + ++kx; + } + } /* for(ix ...) */ + + s_mp_clamp(&tmp); + s_mp_exch(&tmp, a); + + mp_clear(&tmp); + + return MP_OKAY; + +} /* end s_mp_sqr() */ +#endif + +/* }}} */ + +/* {{{ s_mp_div(a, b) */ + +/* + s_mp_div(a, b) + + Compute a = a / b and b = a mod b. Assumes b > a. + */ + +mp_err s_mp_div(mp_int *a, mp_int *b) +{ + mp_int quot, rem, t; + mp_word q; + mp_err res; + mp_digit d; + int ix; + + if(mp_cmp_z(b) == 0) + return MP_RANGE; + + /* Shortcut if b is power of two */ + if((ix = s_mp_ispow2(b)) >= 0) { + mp_copy(a, b); /* need this for remainder */ + s_mp_div_2d(a, (mp_digit)ix); + s_mp_mod_2d(b, (mp_digit)ix); + + return MP_OKAY; + } + + /* Allocate space to store the quotient */ + if((res = mp_init_size(", USED(a))) != MP_OKAY) + return res; + + /* A working temporary for division */ + if((res = mp_init_size(&t, USED(a))) != MP_OKAY) + goto T; + + /* Allocate space for the remainder */ + if((res = mp_init_size(&rem, USED(a))) != MP_OKAY) + goto REM; + + /* Normalize to optimize guessing */ + d = s_mp_norm(a, b); + + /* Perform the division itself...woo! */ + ix = USED(a) - 1; + + while(ix >= 0) { + /* Find a partial substring of a which is at least b */ + while(s_mp_cmp(&rem, b) < 0 && ix >= 0) { + if((res = s_mp_lshd(&rem, 1)) != MP_OKAY) + goto CLEANUP; + + if((res = s_mp_lshd(", 1)) != MP_OKAY) + goto CLEANUP; + + DIGIT(&rem, 0) = DIGIT(a, ix); + s_mp_clamp(&rem); + --ix; + } + + /* If we didn't find one, we're finished dividing */ + if(s_mp_cmp(&rem, b) < 0) + break; + + /* Compute a guess for the next quotient digit */ + q = DIGIT(&rem, USED(&rem) - 1); + if(q <= DIGIT(b, USED(b) - 1) && USED(&rem) > 1) + q = (q << DIGIT_BIT) | DIGIT(&rem, USED(&rem) - 2); + + q /= DIGIT(b, USED(b) - 1); + + /* The guess can be as much as RADIX + 1 */ + if(q >= RADIX) + q = RADIX - 1; + + /* See what that multiplies out to */ + mp_copy(b, &t); + if((res = s_mp_mul_d(&t, q)) != MP_OKAY) + goto CLEANUP; + + /* + If it's too big, back it off. We should not have to do this + more than once, or, in rare cases, twice. Knuth describes a + method by which this could be reduced to a maximum of once, but + I didn't implement that here. + */ + while(s_mp_cmp(&t, &rem) > 0) { + --q; + s_mp_sub(&t, b); + } + + /* At this point, q should be the right next digit */ + if((res = s_mp_sub(&rem, &t)) != MP_OKAY) + goto CLEANUP; + + /* + Include the digit in the quotient. We allocated enough memory + for any quotient we could ever possibly get, so we should not + have to check for failures here + */ + DIGIT(", 0) = q; + } + + /* Denormalize remainder */ + if(d != 0) + s_mp_div_2d(&rem, d); + + s_mp_clamp("); + s_mp_clamp(&rem); + + /* Copy quotient back to output */ + s_mp_exch(", a); + + /* Copy remainder back to output */ + s_mp_exch(&rem, b); + +CLEANUP: + mp_clear(&rem); +REM: + mp_clear(&t); +T: + mp_clear("); + + return res; + +} /* end s_mp_div() */ + +/* }}} */ + +/* {{{ s_mp_2expt(a, k) */ + +mp_err s_mp_2expt(mp_int *a, mp_digit k) +{ + mp_err res; + mp_size dig, bit; + + dig = k / DIGIT_BIT; + bit = k % DIGIT_BIT; + + mp_zero(a); + if((res = s_mp_pad(a, dig + 1)) != MP_OKAY) + return res; + + DIGIT(a, dig) |= (1 << bit); + + return MP_OKAY; + +} /* end s_mp_2expt() */ + +/* }}} */ + + +/* }}} */ + +/* }}} */ + +/* {{{ Primitive comparisons */ + +/* {{{ s_mp_cmp(a, b) */ + +/* Compare |a| <=> |b|, return 0 if equal, <0 if a0 if a>b */ +int s_mp_cmp(mp_int *a, mp_int *b) +{ + mp_size ua = USED(a), ub = USED(b); + + if(ua > ub) + return MP_GT; + else if(ua < ub) + return MP_LT; + else { + int ix = ua - 1; + mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix; + + while(ix >= 0) { + if(*ap > *bp) + return MP_GT; + else if(*ap < *bp) + return MP_LT; + + --ap; --bp; --ix; + } + + return MP_EQ; + } + +} /* end s_mp_cmp() */ + +/* }}} */ + +/* {{{ s_mp_cmp_d(a, d) */ + +/* Compare |a| <=> d, return 0 if equal, <0 if a0 if a>d */ +int s_mp_cmp_d(mp_int *a, mp_digit d) +{ + mp_size ua = USED(a); + mp_digit *ap = DIGITS(a); + + if(ua > 1) + return MP_GT; + + if(*ap < d) + return MP_LT; + else if(*ap > d) + return MP_GT; + else + return MP_EQ; + +} /* end s_mp_cmp_d() */ + +/* }}} */ + +/* {{{ s_mp_ispow2(v) */ + +/* + Returns -1 if the value is not a power of two; otherwise, it returns + k such that v = 2^k, i.e. lg(v). + */ +int s_mp_ispow2(mp_int *v) +{ + mp_digit d, *dp; + mp_size uv = USED(v); + int extra = 0, ix; + + d = DIGIT(v, uv - 1); /* most significant digit of v */ + + while(d && ((d & 1) == 0)) { + d >>= 1; + ++extra; + } + + if(d == 1) { + ix = uv - 2; + dp = DIGITS(v) + ix; + + while(ix >= 0) { + if(*dp) + return -1; /* not a power of two */ + + --dp; --ix; + } + + return ((uv - 1) * DIGIT_BIT) + extra; + } + + return -1; + +} /* end s_mp_ispow2() */ + +/* }}} */ + +/* {{{ s_mp_ispow2d(d) */ + +int s_mp_ispow2d(mp_digit d) +{ + int pow = 0; + + while((d & 1) == 0) { + ++pow; d >>= 1; + } + + if(d == 1) + return pow; + + return -1; + +} /* end s_mp_ispow2d() */ + +/* }}} */ + +/* }}} */ + +/* {{{ Primitive I/O helpers */ + +/* {{{ s_mp_tovalue(ch, r) */ + +/* + Convert the given character to its digit value, in the given radix. + If the given character is not understood in the given radix, -1 is + returned. Otherwise the digit's numeric value is returned. + + The results will be odd if you use a radix < 2 or > 62, you are + expected to know what you're up to. + */ +int s_mp_tovalue(char ch, int r) +{ + int val, xch; + + if(r > 36) + xch = ch; + else + xch = toupper(ch); + + if(isdigit(xch)) + val = xch - '0'; + else if(isupper(xch)) + val = xch - 'A' + 10; + else if(islower(xch)) + val = xch - 'a' + 36; + else if(xch == '+') + val = 62; + else if(xch == '/') + val = 63; + else + return -1; + + if(val < 0 || val >= r) + return -1; + + return val; + +} /* end s_mp_tovalue() */ + +/* }}} */ + +/* {{{ s_mp_todigit(val, r, low) */ + +/* + Convert val to a radix-r digit, if possible. If val is out of range + for r, returns zero. Otherwise, returns an ASCII character denoting + the value in the given radix. + + The results may be odd if you use a radix < 2 or > 64, you are + expected to know what you're doing. + */ + +char s_mp_todigit(int val, int r, int low) +{ + char ch; + + if(val < 0 || val >= r) + return 0; + + ch = s_dmap_1[val]; + + if(r <= 36 && low) + ch = tolower(ch); + + return ch; + +} /* end s_mp_todigit() */ + +/* }}} */ + +/* {{{ s_mp_outlen(bits, radix) */ + +/* + Return an estimate for how long a string is needed to hold a radix + r representation of a number with 'bits' significant bits. + + Does not include space for a sign or a NUL terminator. + */ +int s_mp_outlen(int bits, int r) +{ + return (int)((double)bits * LOG_V_2(r)); + +} /* end s_mp_outlen() */ + +/* }}} */ + +/* }}} */ + +/*------------------------------------------------------------------------*/ +/* HERE THERE BE DRAGONS */ +/* crc==4242132123, version==2, Sat Feb 02 06:43:52 2002 */ diff --git a/mtest/mpi.h b/mtest/mpi.h new file mode 100644 index 0000000..e19ecf8 --- /dev/null +++ b/mtest/mpi.h @@ -0,0 +1,227 @@ +/* + mpi.h + + by Michael J. Fromberger + Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved + + Arbitrary precision integer arithmetic library + + $ID$ + */ + +#ifndef _H_MPI_ +#define _H_MPI_ + +#include "mpi-config.h" + +#define MP_LT -1 +#define MP_EQ 0 +#define MP_GT 1 + +#if MP_DEBUG +#undef MP_IOFUNC +#define MP_IOFUNC 1 +#endif + +#if MP_IOFUNC +#include +#include +#endif + +#include + +#define MP_NEG 1 +#define MP_ZPOS 0 + +/* Included for compatibility... */ +#define NEG MP_NEG +#define ZPOS MP_ZPOS + +#define MP_OKAY 0 /* no error, all is well */ +#define MP_YES 0 /* yes (boolean result) */ +#define MP_NO -1 /* no (boolean result) */ +#define MP_MEM -2 /* out of memory */ +#define MP_RANGE -3 /* argument out of range */ +#define MP_BADARG -4 /* invalid parameter */ +#define MP_UNDEF -5 /* answer is undefined */ +#define MP_LAST_CODE MP_UNDEF + +#include "mpi-types.h" + +/* Included for compatibility... */ +#define DIGIT_BIT MP_DIGIT_BIT +#define DIGIT_MAX MP_DIGIT_MAX + +/* Macros for accessing the mp_int internals */ +#define SIGN(MP) ((MP)->sign) +#define USED(MP) ((MP)->used) +#define ALLOC(MP) ((MP)->alloc) +#define DIGITS(MP) ((MP)->dp) +#define DIGIT(MP,N) (MP)->dp[(N)] + +#if MP_ARGCHK == 1 +#define ARGCHK(X,Y) {if(!(X)){return (Y);}} +#elif MP_ARGCHK == 2 +#include +#define ARGCHK(X,Y) assert(X) +#else +#define ARGCHK(X,Y) /* */ +#endif + +/* This defines the maximum I/O base (minimum is 2) */ +#define MAX_RADIX 64 + +typedef struct { + mp_sign sign; /* sign of this quantity */ + mp_size alloc; /* how many digits allocated */ + mp_size used; /* how many digits used */ + mp_digit *dp; /* the digits themselves */ +} mp_int; + +/*------------------------------------------------------------------------*/ +/* Default precision */ + +unsigned int mp_get_prec(void); +void mp_set_prec(unsigned int prec); + +/*------------------------------------------------------------------------*/ +/* Memory management */ + +mp_err mp_init(mp_int *mp); +mp_err mp_init_array(mp_int mp[], int count); +mp_err mp_init_size(mp_int *mp, mp_size prec); +mp_err mp_init_copy(mp_int *mp, mp_int *from); +mp_err mp_copy(mp_int *from, mp_int *to); +void mp_exch(mp_int *mp1, mp_int *mp2); +void mp_clear(mp_int *mp); +void mp_clear_array(mp_int mp[], int count); +void mp_zero(mp_int *mp); +void mp_set(mp_int *mp, mp_digit d); +mp_err mp_set_int(mp_int *mp, long z); +mp_err mp_shrink(mp_int *a); + + +/*------------------------------------------------------------------------*/ +/* Single digit arithmetic */ + +mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b); +mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b); +mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b); +mp_err mp_mul_2(mp_int *a, mp_int *c); +mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r); +mp_err mp_div_2(mp_int *a, mp_int *c); +mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c); + +/*------------------------------------------------------------------------*/ +/* Sign manipulations */ + +mp_err mp_abs(mp_int *a, mp_int *b); +mp_err mp_neg(mp_int *a, mp_int *b); + +/*------------------------------------------------------------------------*/ +/* Full arithmetic */ + +mp_err mp_add(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c); +#if MP_SQUARE +mp_err mp_sqr(mp_int *a, mp_int *b); +#else +#define mp_sqr(a, b) mp_mul(a, a, b) +#endif +mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r); +mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r); +mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_2expt(mp_int *a, mp_digit k); +mp_err mp_sqrt(mp_int *a, mp_int *b); + +/*------------------------------------------------------------------------*/ +/* Modular arithmetic */ + +#if MP_MODARITH +mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c); +mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c); +mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); +mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); +mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); +#if MP_SQUARE +mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c); +#else +#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c) +#endif +mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c); +mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c); +#endif /* MP_MODARITH */ + +/*------------------------------------------------------------------------*/ +/* Comparisons */ + +int mp_cmp_z(mp_int *a); +int mp_cmp_d(mp_int *a, mp_digit d); +int mp_cmp(mp_int *a, mp_int *b); +int mp_cmp_mag(mp_int *a, mp_int *b); +int mp_cmp_int(mp_int *a, long z); +int mp_isodd(mp_int *a); +int mp_iseven(mp_int *a); + +/*------------------------------------------------------------------------*/ +/* Number theoretic */ + +#if MP_NUMTH +mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c); +mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y); +mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c); +#endif /* end MP_NUMTH */ + +/*------------------------------------------------------------------------*/ +/* Input and output */ + +#if MP_IOFUNC +void mp_print(mp_int *mp, FILE *ofp); +#endif /* end MP_IOFUNC */ + +/*------------------------------------------------------------------------*/ +/* Base conversion */ + +#define BITS 1 +#define BYTES CHAR_BIT + +mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len); +int mp_signed_bin_size(mp_int *mp); +mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str); + +mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len); +int mp_unsigned_bin_size(mp_int *mp); +mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str); + +int mp_count_bits(mp_int *mp); + +#if MP_COMPAT_MACROS +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) +#endif + +mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix); +int mp_radix_size(mp_int *mp, int radix); +int mp_value_radix_size(int num, int qty, int radix); +mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix); + +int mp_char2value(char ch, int r); + +#define mp_tobinary(M, S) mp_toradix((M), (S), 2) +#define mp_tooctal(M, S) mp_toradix((M), (S), 8) +#define mp_todecimal(M, S) mp_toradix((M), (S), 10) +#define mp_tohex(M, S) mp_toradix((M), (S), 16) + +/*------------------------------------------------------------------------*/ +/* Error strings */ + +const char *mp_strerror(mp_err ec); + +#endif /* end _H_MPI_ */ diff --git a/mtest/mtest.c b/mtest/mtest.c new file mode 100644 index 0000000..d9f919a --- /dev/null +++ b/mtest/mtest.c @@ -0,0 +1,218 @@ +/* makes a bignum test harness with NUM tests per operation + * + * the output is made in the following format [one parameter per line] + +operation +operand1 +operand2 +[... operandN] +result1 +result2 +[... resultN] + +So for example "a * b mod n" would be + +mulmod +a +b +n +a*b mod n + +e.g. if a=3, b=4 n=11 then + +mulmod +3 +4 +11 +1 + + */ + +#include +#include +#include +#include "mpi.c" + +FILE *rng; + +void rand_num(mp_int *a) +{ + int n, size; + unsigned char buf[512]; + +top: + size = 1 + (fgetc(rng) % 96); + buf[0] = (fgetc(rng)&1)?1:0; + fread(buf+1, 1, size, rng); + for (n = 0; n < size; n++) { + if (buf[n+1]) break; + } + if (n == size) goto top; + mp_read_raw(a, buf, 1+size); +} + +void rand_num2(mp_int *a) +{ + int n, size; + unsigned char buf[512]; + +top: + size = 1 + (fgetc(rng) % 128); + buf[0] = (fgetc(rng)&1)?1:0; + fread(buf+1, 1, size, rng); + for (n = 0; n < size; n++) { + if (buf[n+1]) break; + } + if (n == size) goto top; + mp_read_raw(a, buf, 1+size); +} + +int main(void) +{ + int n; + mp_int a, b, c, d, e; + char buf[4096]; + + mp_init(&a); + mp_init(&b); + mp_init(&c); + mp_init(&d); + mp_init(&e); + + rng = fopen("/dev/urandom", "rb"); + + for (;;) { + n = fgetc(rng) % 10; + + if (n == 0) { + /* add tests */ + rand_num(&a); + rand_num(&b); + mp_add(&a, &b, &c); + printf("add\n"); + mp_todecimal(&a, buf); + printf("%s\n", buf); + mp_todecimal(&b, buf); + printf("%s\n", buf); + mp_todecimal(&c, buf); + printf("%s\n", buf); + } else if (n == 1) { + /* sub tests */ + rand_num(&a); + rand_num(&b); + mp_sub(&a, &b, &c); + printf("sub\n"); + mp_todecimal(&a, buf); + printf("%s\n", buf); + mp_todecimal(&b, buf); + printf("%s\n", buf); + mp_todecimal(&c, buf); + printf("%s\n", buf); + } else if (n == 2) { + /* mul tests */ + rand_num(&a); + rand_num(&b); + mp_mul(&a, &b, &c); + printf("mul\n"); + mp_todecimal(&a, buf); + printf("%s\n", buf); + mp_todecimal(&b, buf); + printf("%s\n", buf); + mp_todecimal(&c, buf); + printf("%s\n", buf); + } else if (n == 3) { + /* div tests */ + rand_num(&a); + rand_num(&b); + mp_div(&a, &b, &c, &d); + printf("div\n"); + mp_todecimal(&a, buf); + printf("%s\n", buf); + mp_todecimal(&b, buf); + printf("%s\n", buf); + mp_todecimal(&c, buf); + printf("%s\n", buf); + mp_todecimal(&d, buf); + printf("%s\n", buf); + } else if (n == 4) { + /* sqr tests */ + rand_num(&a); + mp_sqr(&a, &b); + printf("sqr\n"); + mp_todecimal(&a, buf); + printf("%s\n", buf); + mp_todecimal(&b, buf); + printf("%s\n", buf); + } else if (n == 5) { + /* mul_2d test */ + rand_num(&a); + mp_copy(&a, &b); + n = fgetc(rng) & 63; + mp_mul_2d(&b, n, &b); + mp_todecimal(&a, buf); + printf("mul2d\n"); + printf("%s\n", buf); + printf("%d\n", n); + mp_todecimal(&b, buf); + printf("%s\n", buf); + } else if (n == 6) { + /* div_2d test */ + rand_num(&a); + mp_copy(&a, &b); + n = fgetc(rng) & 63; + mp_div_2d(&b, n, &b, NULL); + mp_todecimal(&a, buf); + printf("div2d\n"); + printf("%s\n", buf); + printf("%d\n", n); + mp_todecimal(&b, buf); + printf("%s\n", buf); + } else if (n == 7) { + /* gcd test */ + rand_num(&a); + rand_num(&b); + a.sign = MP_ZPOS; + b.sign = MP_ZPOS; + mp_gcd(&a, &b, &c); + printf("gcd\n"); + mp_todecimal(&a, buf); + printf("%s\n", buf); + mp_todecimal(&b, buf); + printf("%s\n", buf); + mp_todecimal(&c, buf); + printf("%s\n", buf); + } else if (n == 8) { + /* lcm test */ + rand_num(&a); + rand_num(&b); + a.sign = MP_ZPOS; + b.sign = MP_ZPOS; + mp_lcm(&a, &b, &c); + printf("lcm\n"); + mp_todecimal(&a, buf); + printf("%s\n", buf); + mp_todecimal(&b, buf); + printf("%s\n", buf); + mp_todecimal(&c, buf); + printf("%s\n", buf); + } else if (n == 9) { + /* lcm test */ + rand_num2(&a); + rand_num2(&b); + rand_num2(&c); + a.sign = b.sign = c.sign = 0; + mp_exptmod(&a, &b, &c, &d); + printf("expt\n"); + mp_todecimal(&a, buf); + printf("%s\n", buf); + mp_todecimal(&b, buf); + printf("%s\n", buf); + mp_todecimal(&c, buf); + printf("%s\n", buf); + mp_todecimal(&d, buf); + printf("%s\n", buf); + } + } + fclose(rng); + return 0; +}