added libtommath-0.29
This commit is contained in:
parent
455bb4db20
commit
6c48a9b3a6
6
bn.ilg
6
bn.ilg
@ -1,6 +1,6 @@
|
|||||||
This is makeindex, version 2.14 [02-Oct-2002] (kpathsea + Thai support).
|
This is makeindex, version 2.14 [02-Oct-2002] (kpathsea + Thai support).
|
||||||
Scanning input file bn.idx....done (53 entries accepted, 0 rejected).
|
Scanning input file bn.idx....done (57 entries accepted, 0 rejected).
|
||||||
Sorting entries....done (317 comparisons).
|
Sorting entries....done (342 comparisons).
|
||||||
Generating output file bn.ind....done (56 lines written, 0 warnings).
|
Generating output file bn.ind....done (60 lines written, 0 warnings).
|
||||||
Output written in bn.ind.
|
Output written in bn.ind.
|
||||||
Transcript written in bn.ilg.
|
Transcript written in bn.ilg.
|
||||||
|
6
bn.ind
6
bn.ind
@ -14,6 +14,7 @@
|
|||||||
\item mp\_error\_to\_string, \hyperpage{6}
|
\item mp\_error\_to\_string, \hyperpage{6}
|
||||||
\item mp\_expt\_d, \hyperpage{31}
|
\item mp\_expt\_d, \hyperpage{31}
|
||||||
\item mp\_exptmod, \hyperpage{31}
|
\item mp\_exptmod, \hyperpage{31}
|
||||||
|
\item mp\_exteuclid, \hyperpage{39}
|
||||||
\item mp\_gcd, \hyperpage{39}
|
\item mp\_gcd, \hyperpage{39}
|
||||||
\item mp\_grow, \hyperpage{12}
|
\item mp\_grow, \hyperpage{12}
|
||||||
\item MP\_GT, \hyperpage{17}
|
\item MP\_GT, \hyperpage{17}
|
||||||
@ -23,7 +24,7 @@
|
|||||||
\item mp\_init\_size, \hyperpage{10}
|
\item mp\_init\_size, \hyperpage{10}
|
||||||
\item mp\_int, \hyperpage{6}
|
\item mp\_int, \hyperpage{6}
|
||||||
\item mp\_invmod, \hyperpage{40}
|
\item mp\_invmod, \hyperpage{40}
|
||||||
\item mp\_jacobi, \hyperpage{39}
|
\item mp\_jacobi, \hyperpage{40}
|
||||||
\item mp\_lcm, \hyperpage{39}
|
\item mp\_lcm, \hyperpage{39}
|
||||||
\item mp\_lshd, \hyperpage{23}
|
\item mp\_lshd, \hyperpage{23}
|
||||||
\item MP\_LT, \hyperpage{17}
|
\item MP\_LT, \hyperpage{17}
|
||||||
@ -43,12 +44,15 @@
|
|||||||
\item mp\_prime\_next\_prime, \hyperpage{34}
|
\item mp\_prime\_next\_prime, \hyperpage{34}
|
||||||
\item mp\_prime\_rabin\_miller\_trials, \hyperpage{34}
|
\item mp\_prime\_rabin\_miller\_trials, \hyperpage{34}
|
||||||
\item mp\_prime\_random, \hyperpage{35}
|
\item mp\_prime\_random, \hyperpage{35}
|
||||||
|
\item mp\_radix\_size, \hyperpage{37}
|
||||||
|
\item mp\_read\_radix, \hyperpage{37}
|
||||||
\item mp\_rshd, \hyperpage{23}
|
\item mp\_rshd, \hyperpage{23}
|
||||||
\item mp\_set, \hyperpage{15}
|
\item mp\_set, \hyperpage{15}
|
||||||
\item mp\_set\_int, \hyperpage{16}
|
\item mp\_set\_int, \hyperpage{16}
|
||||||
\item mp\_shrink, \hyperpage{11}
|
\item mp\_shrink, \hyperpage{11}
|
||||||
\item mp\_sqr, \hyperpage{25}
|
\item mp\_sqr, \hyperpage{25}
|
||||||
\item mp\_sub, \hyperpage{23}
|
\item mp\_sub, \hyperpage{23}
|
||||||
|
\item mp\_toradix, \hyperpage{37}
|
||||||
\item MP\_VAL, \hyperpage{5}
|
\item MP\_VAL, \hyperpage{5}
|
||||||
\item mp\_xor, \hyperpage{23}
|
\item mp\_xor, \hyperpage{23}
|
||||||
\item MP\_YES, \hyperpage{5}
|
\item MP\_YES, \hyperpage{5}
|
||||||
|
44
bn.tex
44
bn.tex
@ -1001,10 +1001,10 @@ algorithms all which can be called from mp\_sqr().
|
|||||||
\section{Tuning Polynomial Basis Routines}
|
\section{Tuning Polynomial Basis Routines}
|
||||||
|
|
||||||
Both Toom-Cook and Karatsuba multiplication algorithms are faster than the traditional $O(n^2)$ approach that
|
Both Toom-Cook and Karatsuba multiplication algorithms are faster than the traditional $O(n^2)$ approach that
|
||||||
the Comba and baseline algorithms use. At $O(n^{1.46})$ and $O(n^{1.58})$ running times respectfully they require
|
the Comba and baseline algorithms use. At $O(n^{1.464973})$ and $O(n^{1.584962})$ running times respectfully they require
|
||||||
considerably less work. For example, a 10000-digit multiplication would take roughly 692,000 single precision
|
considerably less work. For example, a 10000-digit multiplication would take roughly 724,000 single precision
|
||||||
multiplications with Toom-Cook or 100,000,000 single precision multiplications with the standard Comba (a factor
|
multiplications with Toom-Cook or 100,000,000 single precision multiplications with the standard Comba (a factor
|
||||||
of 144).
|
of 138).
|
||||||
|
|
||||||
So why not always use Karatsuba or Toom-Cook? The simple answer is that they have so much overhead that they're not
|
So why not always use Karatsuba or Toom-Cook? The simple answer is that they have so much overhead that they're not
|
||||||
actually faster than Comba until you hit distinct ``cutoff'' points. For Karatsuba with the default configuration,
|
actually faster than Comba until you hit distinct ``cutoff'' points. For Karatsuba with the default configuration,
|
||||||
@ -1175,10 +1175,48 @@ there is no skew on the least significant bits.
|
|||||||
|
|
||||||
\chapter{Input and Output}
|
\chapter{Input and Output}
|
||||||
\section{ASCII Conversions}
|
\section{ASCII Conversions}
|
||||||
|
\subsection{To ASCII}
|
||||||
|
\index{mp\_toradix}
|
||||||
|
\begin{alltt}
|
||||||
|
int mp_toradix (mp_int * a, char *str, int radix);
|
||||||
|
\end{alltt}
|
||||||
|
This still store ``a'' in ``str'' as a base-``radix'' string of ASCII chars. This function appends a NUL character
|
||||||
|
to terminate the string. Valid values of ``radix'' line in the range $[2, 64]$. To determine the size (exact) required
|
||||||
|
by the conversion before storing any data use the following function.
|
||||||
|
|
||||||
|
\index{mp\_radix\_size}
|
||||||
|
\begin{alltt}
|
||||||
|
int mp_radix_size (mp_int * a, int radix, int *size)
|
||||||
|
\end{alltt}
|
||||||
|
This stores in ``size'' the number of characters (including space for the NUL terminator) required. Upon error this
|
||||||
|
function returns an error code and ``size'' will be zero.
|
||||||
|
|
||||||
|
\subsection{From ASCII}
|
||||||
|
\index{mp\_read\_radix}
|
||||||
|
\begin{alltt}
|
||||||
|
int mp_read_radix (mp_int * a, char *str, int radix);
|
||||||
|
\end{alltt}
|
||||||
|
This will read the base-``radix'' NUL terminated string from ``str'' into ``a''. It will stop reading when it reads a
|
||||||
|
character it does not recognize (which happens to include th NUL char... imagine that...). A single leading $-$ sign
|
||||||
|
can be used to denote a negative number.
|
||||||
|
|
||||||
\section{Binary Conversions}
|
\section{Binary Conversions}
|
||||||
\section{Stream Functions}
|
\section{Stream Functions}
|
||||||
|
|
||||||
\chapter{Algebraic Functions}
|
\chapter{Algebraic Functions}
|
||||||
|
\section{Extended Euclidean Algorithm}
|
||||||
|
\index{mp\_exteuclid}
|
||||||
|
\begin{alltt}
|
||||||
|
int mp_exteuclid(mp_int *a, mp_int *b,
|
||||||
|
mp_int *U1, mp_int *U2, mp_int *U3);
|
||||||
|
\end{alltt}
|
||||||
|
|
||||||
|
This finds the triple U1/U2/U3 using the Extended Euclidean algorithm such that the following equation holds.
|
||||||
|
|
||||||
|
\begin{equation}
|
||||||
|
a \cdot U1 + b \cdot U2 = U3
|
||||||
|
\end{equation}
|
||||||
|
|
||||||
\section{Greatest Common Divisor}
|
\section{Greatest Common Divisor}
|
||||||
\index{mp\_gcd}
|
\index{mp\_gcd}
|
||||||
\begin{alltt}
|
\begin{alltt}
|
||||||
|
@ -41,7 +41,7 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
|
|||||||
t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
|
t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
|
||||||
|
|
||||||
/* now subtract 3 * [w/3] from w, to get the remainder */
|
/* now subtract 3 * [w/3] from w, to get the remainder */
|
||||||
w -= (t << ((mp_word)1)) + t;
|
w -= t+t+t;
|
||||||
|
|
||||||
/* fixup the remainder as required since
|
/* fixup the remainder as required since
|
||||||
* the optimization is not exact.
|
* the optimization is not exact.
|
||||||
|
@ -28,8 +28,7 @@ static int s_is_power_of_two(mp_digit b, int *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* single digit division (based on routine from MPI) */
|
/* single digit division (based on routine from MPI) */
|
||||||
int
|
int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
||||||
mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
|
||||||
{
|
{
|
||||||
mp_int q;
|
mp_int q;
|
||||||
mp_word w;
|
mp_word w;
|
||||||
|
69
bn_mp_exteuclid.c
Normal file
69
bn_mp_exteuclid.c
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||||
|
*
|
||||||
|
* LibTomMath is a library that provides multiple-precision
|
||||||
|
* integer arithmetic as well as number theoretic functionality.
|
||||||
|
*
|
||||||
|
* The library was designed directly after the MPI library by
|
||||||
|
* Michael Fromberger but has been written from scratch with
|
||||||
|
* additional optimizations in place.
|
||||||
|
*
|
||||||
|
* The library is free for all purposes without any express
|
||||||
|
* guarantee it works.
|
||||||
|
*
|
||||||
|
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
|
||||||
|
*/
|
||||||
|
#include <tommath.h>
|
||||||
|
|
||||||
|
/* Extended euclidean algorithm of (a, b) produces
|
||||||
|
a*u1 + b*u2 = u3
|
||||||
|
*/
|
||||||
|
int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
|
||||||
|
{
|
||||||
|
mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize, (u1,u2,u3) = (1,0,a) */
|
||||||
|
mp_set(&u1, 1);
|
||||||
|
if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* initialize, (v1,v2,v3) = (0,1,b) */
|
||||||
|
mp_set(&v2, 1);
|
||||||
|
if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* loop while v3 != 0 */
|
||||||
|
while (mp_iszero(&v3) == MP_NO) {
|
||||||
|
/* q = u3/v3 */
|
||||||
|
if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
|
||||||
|
if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* (u1,u2,u3) = (v1,v2,v3) */
|
||||||
|
if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* (v1,v2,v3) = (t1,t2,t3) */
|
||||||
|
if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy result out */
|
||||||
|
if (U1 != NULL) { mp_exch(U1, &u1); }
|
||||||
|
if (U2 != NULL) { mp_exch(U2, &u2); }
|
||||||
|
if (U3 != NULL) { mp_exch(U3, &u3); }
|
||||||
|
|
||||||
|
err = MP_OKAY;
|
||||||
|
_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
|
||||||
|
return err;
|
||||||
|
}
|
@ -19,9 +19,8 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream)
|
|||||||
char *buf;
|
char *buf;
|
||||||
int err, len, x;
|
int err, len, x;
|
||||||
|
|
||||||
len = mp_radix_size(a, radix);
|
if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
|
||||||
if (len == 0) {
|
return err;
|
||||||
return MP_VAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = XMALLOC (len);
|
buf = XMALLOC (len);
|
||||||
|
@ -42,7 +42,6 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
|||||||
} else {
|
} else {
|
||||||
res = s_mp_mul (a, b, c);
|
res = s_mp_mul (a, b, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
c->sign = neg;
|
c->sign = neg;
|
||||||
return res;
|
return res;
|
||||||
|
@ -15,26 +15,28 @@
|
|||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* returns size of ASCII reprensentation */
|
/* returns size of ASCII reprensentation */
|
||||||
int
|
int mp_radix_size (mp_int * a, int radix, int *size)
|
||||||
mp_radix_size (mp_int * a, int radix)
|
|
||||||
{
|
{
|
||||||
int res, digs;
|
int res, digs;
|
||||||
mp_int t;
|
mp_int t;
|
||||||
mp_digit d;
|
mp_digit d;
|
||||||
|
|
||||||
|
*size = 0;
|
||||||
|
|
||||||
/* special case for binary */
|
/* special case for binary */
|
||||||
if (radix == 2) {
|
if (radix == 2) {
|
||||||
return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
|
*size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
|
||||||
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure the radix is in range */
|
/* make sure the radix is in range */
|
||||||
if (radix < 2 || radix > 64) {
|
if (radix < 2 || radix > 64) {
|
||||||
return 0;
|
return MP_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init a copy of the input */
|
/* init a copy of the input */
|
||||||
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
|
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
|
||||||
return 0;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* digs is the digit count */
|
/* digs is the digit count */
|
||||||
@ -57,6 +59,7 @@ mp_radix_size (mp_int * a, int radix)
|
|||||||
mp_clear (&t);
|
mp_clear (&t);
|
||||||
|
|
||||||
/* return digs + 1, the 1 is for the NULL byte that would be required. */
|
/* return digs + 1, the 1 is for the NULL byte that would be required. */
|
||||||
return digs + 1;
|
*size = digs + 1;
|
||||||
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* read a string [ASCII] in a given radix */
|
/* read a string [ASCII] in a given radix */
|
||||||
int
|
int mp_read_radix (mp_int * a, char *str, int radix)
|
||||||
mp_read_radix (mp_int * a, char *str, int radix)
|
|
||||||
{
|
{
|
||||||
int y, res, neg;
|
int y, res, neg;
|
||||||
char ch;
|
char ch;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
int mp_shrink (mp_int * a)
|
int mp_shrink (mp_int * a)
|
||||||
{
|
{
|
||||||
mp_digit *tmp;
|
mp_digit *tmp;
|
||||||
if (a->alloc != a->used) {
|
if (a->alloc != a->used && a->used > 0) {
|
||||||
if ((tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
|
if ((tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
|
||||||
return MP_MEM;
|
return MP_MEM;
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* get the size for an signed equivalent */
|
/* get the size for an signed equivalent */
|
||||||
int
|
int mp_signed_bin_size (mp_int * a)
|
||||||
mp_signed_bin_size (mp_int * a)
|
|
||||||
{
|
{
|
||||||
return 1 + mp_unsigned_bin_size (a);
|
return 1 + mp_unsigned_bin_size (a);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ int
|
|||||||
mp_sqr (mp_int * a, mp_int * b)
|
mp_sqr (mp_int * a, mp_int * b)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/* use Toom-Cook? */
|
/* use Toom-Cook? */
|
||||||
if (a->used >= TOOM_SQR_CUTOFF) {
|
if (a->used >= TOOM_SQR_CUTOFF) {
|
||||||
res = mp_toom_sqr(a, b);
|
res = mp_toom_sqr(a, b);
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* stores a bignum as a ASCII string in a given radix (2..64) */
|
/* stores a bignum as a ASCII string in a given radix (2..64) */
|
||||||
int
|
int mp_toradix (mp_int * a, char *str, int radix)
|
||||||
mp_toradix (mp_int * a, char *str, int radix)
|
|
||||||
{
|
{
|
||||||
int res, digs;
|
int res, digs;
|
||||||
mp_int t;
|
mp_int t;
|
||||||
|
@ -31,25 +31,7 @@ static const struct {
|
|||||||
{ 1408, 3 },
|
{ 1408, 3 },
|
||||||
{ 1536, 3 },
|
{ 1536, 3 },
|
||||||
{ 1664, 3 },
|
{ 1664, 3 },
|
||||||
{ 1792, 2 },
|
{ 1792, 2 } };
|
||||||
{ 1920, 2 },
|
|
||||||
{ 2048, 2 },
|
|
||||||
{ 2176, 2 },
|
|
||||||
{ 2304, 2 },
|
|
||||||
{ 2432, 2 },
|
|
||||||
{ 2560, 2 },
|
|
||||||
{ 2688, 2 },
|
|
||||||
{ 2816, 2 },
|
|
||||||
{ 2944, 2 },
|
|
||||||
{ 3072, 2 },
|
|
||||||
{ 3200, 2 },
|
|
||||||
{ 3328, 2 },
|
|
||||||
{ 3456, 2 },
|
|
||||||
{ 3584, 2 },
|
|
||||||
{ 3712, 2 },
|
|
||||||
{ 3840, 1 },
|
|
||||||
{ 3968, 1 },
|
|
||||||
{ 4096, 1 } };
|
|
||||||
|
|
||||||
/* returns # of RM trials required for a given bit size */
|
/* returns # of RM trials required for a given bit size */
|
||||||
int mp_prime_rabin_miller_trials(int size)
|
int mp_prime_rabin_miller_trials(int size)
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
#define TAB_SIZE 256
|
#define TAB_SIZE 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||||
s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
|
||||||
{
|
{
|
||||||
mp_int M[TAB_SIZE], res, mu;
|
mp_int M[TAB_SIZE], res, mu;
|
||||||
mp_digit buf;
|
mp_digit buf;
|
||||||
@ -185,10 +184,10 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
|||||||
|
|
||||||
/* then multiply */
|
/* then multiply */
|
||||||
if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
|
if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
|
||||||
goto __MU;
|
goto __RES;
|
||||||
}
|
}
|
||||||
if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
|
if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
|
||||||
goto __MU;
|
goto __RES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* empty window and reset */
|
/* empty window and reset */
|
||||||
|
15
changes.txt
15
changes.txt
@ -1,7 +1,18 @@
|
|||||||
|
Jan 25th, 2004
|
||||||
|
v0.29 ++ Note: "Henrik" from the v0.28 changelog refers to Henrik Goldman ;-)
|
||||||
|
-- Added fix to mp_shrink to prevent a realloc when used == 0 [e.g. realloc zero bytes???]
|
||||||
|
-- Made the mp_prime_rabin_miller_trials() function internal table smaller and also
|
||||||
|
set the minimum number of tests to two (sounds a bit safer).
|
||||||
|
-- Added a mp_exteuclid() which computes the extended euclidean algorithm.
|
||||||
|
-- Fixed a memory leak in s_mp_exptmod() [called when Barrett reduction is to be used] which would arise
|
||||||
|
if a multiplication or subsequent reduction failed [would not free the temp result].
|
||||||
|
-- Made an API change to mp_radix_size(). It now returns an error code and stores the required size
|
||||||
|
through an "int star" passed to it.
|
||||||
|
|
||||||
Dec 24th, 2003
|
Dec 24th, 2003
|
||||||
v0.28 -- Henrik suggested I add casts to the montomgery code [stores into mu...] so compilers wouldn't
|
v0.28 -- Henrik Goldman suggested I add casts to the montomgery code [stores into mu...] so compilers wouldn't
|
||||||
spew [erroneous] diagnostics... fixed.
|
spew [erroneous] diagnostics... fixed.
|
||||||
-- Henrik also spotted two typos. One in mp_radix_size() and another in mp_toradix().
|
-- Henrik Goldman also spotted two typos. One in mp_radix_size() and another in mp_toradix().
|
||||||
-- Added fix to mp_shrink() to avoid a memory leak.
|
-- Added fix to mp_shrink() to avoid a memory leak.
|
||||||
-- Added mp_prime_random() which requires a callback to make truly random primes of a given nature
|
-- Added mp_prime_random() which requires a callback to make truly random primes of a given nature
|
||||||
(idea from chat with Niels Ferguson at Crypto'03)
|
(idea from chat with Niels Ferguson at Crypto'03)
|
||||||
|
@ -138,15 +138,16 @@ int main(void)
|
|||||||
|
|
||||||
/* test mp_div_3 */
|
/* test mp_div_3 */
|
||||||
#if 0
|
#if 0
|
||||||
|
mp_set(&d, 3);
|
||||||
for (cnt = 0; cnt < 1000000; ) {
|
for (cnt = 0; cnt < 1000000; ) {
|
||||||
mp_digit r1, r2;
|
mp_digit r1, r2;
|
||||||
|
|
||||||
if (!(++cnt & 127)) printf("%9d\r", cnt);
|
if (!(++cnt & 127)) printf("%9d\r", cnt);
|
||||||
mp_rand(&a, abs(rand()) % 128 + 1);
|
mp_rand(&a, abs(rand()) % 128 + 1);
|
||||||
mp_div_d(&a, 3, &b, &r1);
|
mp_div(&a, &d, &b, &e);
|
||||||
mp_div_3(&a, &c, &r2);
|
mp_div_3(&a, &c, &r2);
|
||||||
|
|
||||||
if (mp_cmp(&b, &c) || r1 != r2) {
|
if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) {
|
||||||
printf("\n\nmp_div_3 => Failure\n");
|
printf("\n\nmp_div_3 => Failure\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,8 +229,8 @@ pprime (int k, int li, mp_int * p, mp_int * q)
|
|||||||
|
|
||||||
/* now loop making the single digit */
|
/* now loop making the single digit */
|
||||||
while (mp_count_bits (&a) < k) {
|
while (mp_count_bits (&a) < k) {
|
||||||
printf ("prime has %4d bits left\r", k - mp_count_bits (&a));
|
fprintf (stderr, "prime has %4d bits left\r", k - mp_count_bits (&a));
|
||||||
fflush (stdout);
|
fflush (stderr);
|
||||||
top:
|
top:
|
||||||
mp_set (&b, prime_digit ());
|
mp_set (&b, prime_digit ());
|
||||||
|
|
||||||
@ -322,7 +322,6 @@ pprime (int k, int li, mp_int * p, mp_int * q)
|
|||||||
if (ii == li)
|
if (ii == li)
|
||||||
goto top;
|
goto top;
|
||||||
|
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
|
|
||||||
@ -331,10 +330,9 @@ pprime (int k, int li, mp_int * p, mp_int * q)
|
|||||||
mp_toradix(&a, buf, 10);
|
mp_toradix(&a, buf, 10);
|
||||||
printf("A == \n%s\n\n", buf);
|
printf("A == \n%s\n\n", buf);
|
||||||
mp_toradix(&b, buf, 10);
|
mp_toradix(&b, buf, 10);
|
||||||
printf("B == \n%s\n", buf);
|
printf("B == \n%s\n\nG == %d\n", buf, bases[ii]);
|
||||||
printf("----------------------------------------------------------------\n");
|
printf("----------------------------------------------------------------\n");
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
/* a = n */
|
/* a = n */
|
||||||
mp_copy (&n, &a);
|
mp_copy (&n, &a);
|
||||||
|
414
etc/prime.1024
Normal file
414
etc/prime.1024
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
Enter # of bits:
|
||||||
|
Enter number of bases to try (1 to 8):
|
||||||
|
Certificate of primality for:
|
||||||
|
36360080703173363
|
||||||
|
|
||||||
|
A ==
|
||||||
|
89963569
|
||||||
|
|
||||||
|
B ==
|
||||||
|
202082249
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
4851595597739856136987139
|
||||||
|
|
||||||
|
A ==
|
||||||
|
36360080703173363
|
||||||
|
|
||||||
|
B ==
|
||||||
|
66715963
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
19550639734462621430325731591027
|
||||||
|
|
||||||
|
A ==
|
||||||
|
4851595597739856136987139
|
||||||
|
|
||||||
|
B ==
|
||||||
|
2014867
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
10409036141344317165691858509923818734539
|
||||||
|
|
||||||
|
A ==
|
||||||
|
19550639734462621430325731591027
|
||||||
|
|
||||||
|
B ==
|
||||||
|
266207047
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
1049829549988285012736475602118094726647504414203
|
||||||
|
|
||||||
|
A ==
|
||||||
|
10409036141344317165691858509923818734539
|
||||||
|
|
||||||
|
B ==
|
||||||
|
50428759
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
77194737385528288387712399596835459931920358844586615003
|
||||||
|
|
||||||
|
A ==
|
||||||
|
1049829549988285012736475602118094726647504414203
|
||||||
|
|
||||||
|
B ==
|
||||||
|
36765367
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
35663756695365208574443215955488689578374232732893628896541201763
|
||||||
|
|
||||||
|
A ==
|
||||||
|
77194737385528288387712399596835459931920358844586615003
|
||||||
|
|
||||||
|
B ==
|
||||||
|
230998627
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
16711831463502165169495622246023119698415848120292671294127567620396469803
|
||||||
|
|
||||||
|
A ==
|
||||||
|
35663756695365208574443215955488689578374232732893628896541201763
|
||||||
|
|
||||||
|
B ==
|
||||||
|
234297127
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
6163534781560285962890718925972249753147470953579266394395432475622345597103528739
|
||||||
|
|
||||||
|
A ==
|
||||||
|
16711831463502165169495622246023119698415848120292671294127567620396469803
|
||||||
|
|
||||||
|
B ==
|
||||||
|
184406323
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787
|
||||||
|
|
||||||
|
A ==
|
||||||
|
6163534781560285962890718925972249753147470953579266394395432475622345597103528739
|
||||||
|
|
||||||
|
B ==
|
||||||
|
66054487
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187
|
||||||
|
|
||||||
|
A ==
|
||||||
|
814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787
|
||||||
|
|
||||||
|
B ==
|
||||||
|
108362239
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419
|
||||||
|
|
||||||
|
A ==
|
||||||
|
176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187
|
||||||
|
|
||||||
|
B ==
|
||||||
|
127286707
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059
|
||||||
|
|
||||||
|
A ==
|
||||||
|
44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419
|
||||||
|
|
||||||
|
B ==
|
||||||
|
229284691
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979
|
||||||
|
|
||||||
|
A ==
|
||||||
|
20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059
|
||||||
|
|
||||||
|
B ==
|
||||||
|
152800771
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123
|
||||||
|
|
||||||
|
A ==
|
||||||
|
6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979
|
||||||
|
|
||||||
|
B ==
|
||||||
|
246595759
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499
|
||||||
|
|
||||||
|
A ==
|
||||||
|
3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123
|
||||||
|
|
||||||
|
B ==
|
||||||
|
4252063
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163
|
||||||
|
|
||||||
|
A ==
|
||||||
|
26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499
|
||||||
|
|
||||||
|
B ==
|
||||||
|
210605419
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187
|
||||||
|
|
||||||
|
A ==
|
||||||
|
11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163
|
||||||
|
|
||||||
|
B ==
|
||||||
|
74170111
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363
|
||||||
|
|
||||||
|
A ==
|
||||||
|
1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187
|
||||||
|
|
||||||
|
B ==
|
||||||
|
260016763
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283
|
||||||
|
|
||||||
|
A ==
|
||||||
|
857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363
|
||||||
|
|
||||||
|
B ==
|
||||||
|
102563707
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283
|
||||||
|
|
||||||
|
A ==
|
||||||
|
175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283
|
||||||
|
|
||||||
|
B ==
|
||||||
|
137747527
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403
|
||||||
|
|
||||||
|
A ==
|
||||||
|
48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283
|
||||||
|
|
||||||
|
B ==
|
||||||
|
135672847
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123
|
||||||
|
|
||||||
|
A ==
|
||||||
|
13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403
|
||||||
|
|
||||||
|
B ==
|
||||||
|
241523587
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083
|
||||||
|
|
||||||
|
A ==
|
||||||
|
6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123
|
||||||
|
|
||||||
|
B ==
|
||||||
|
248388667
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067
|
||||||
|
|
||||||
|
A ==
|
||||||
|
3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083
|
||||||
|
|
||||||
|
B ==
|
||||||
|
61849651
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739
|
||||||
|
|
||||||
|
A ==
|
||||||
|
390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067
|
||||||
|
|
||||||
|
B ==
|
||||||
|
62201707
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419
|
||||||
|
|
||||||
|
A ==
|
||||||
|
48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739
|
||||||
|
|
||||||
|
B ==
|
||||||
|
264832231
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387
|
||||||
|
|
||||||
|
A ==
|
||||||
|
25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419
|
||||||
|
|
||||||
|
B ==
|
||||||
|
54494047
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547
|
||||||
|
|
||||||
|
A ==
|
||||||
|
2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387
|
||||||
|
|
||||||
|
B ==
|
||||||
|
131594179
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683
|
||||||
|
|
||||||
|
A ==
|
||||||
|
738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547
|
||||||
|
|
||||||
|
B ==
|
||||||
|
266107603
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627
|
||||||
|
|
||||||
|
A ==
|
||||||
|
392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683
|
||||||
|
|
||||||
|
B ==
|
||||||
|
214408111
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643
|
||||||
|
|
||||||
|
A ==
|
||||||
|
168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627
|
||||||
|
|
||||||
|
B ==
|
||||||
|
44122723
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019
|
||||||
|
|
||||||
|
A ==
|
||||||
|
14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643
|
||||||
|
|
||||||
|
B ==
|
||||||
|
40808563
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843
|
||||||
|
|
||||||
|
A ==
|
||||||
|
1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019
|
||||||
|
|
||||||
|
B ==
|
||||||
|
77035759
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683
|
||||||
|
|
||||||
|
A ==
|
||||||
|
186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843
|
||||||
|
|
||||||
|
B ==
|
||||||
|
222383587
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443
|
||||||
|
|
||||||
|
A ==
|
||||||
|
83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683
|
||||||
|
|
||||||
|
B ==
|
||||||
|
23407687
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723
|
||||||
|
|
||||||
|
A ==
|
||||||
|
3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443
|
||||||
|
|
||||||
|
B ==
|
||||||
|
213701827
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Took 33057 ticks, 1048 bits
|
||||||
|
P == 1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723
|
||||||
|
Q == 3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443
|
205
etc/prime.512
Normal file
205
etc/prime.512
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
Enter # of bits:
|
||||||
|
Enter number of bases to try (1 to 8):
|
||||||
|
Certificate of primality for:
|
||||||
|
85933926807634727
|
||||||
|
|
||||||
|
A ==
|
||||||
|
253758023
|
||||||
|
|
||||||
|
B ==
|
||||||
|
169322581
|
||||||
|
|
||||||
|
G == 5
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
23930198825086241462113799
|
||||||
|
|
||||||
|
A ==
|
||||||
|
85933926807634727
|
||||||
|
|
||||||
|
B ==
|
||||||
|
139236037
|
||||||
|
|
||||||
|
G == 11
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
6401844647261612602378676572510019
|
||||||
|
|
||||||
|
A ==
|
||||||
|
23930198825086241462113799
|
||||||
|
|
||||||
|
B ==
|
||||||
|
133760791
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
269731366027728777712034888684015329354259
|
||||||
|
|
||||||
|
A ==
|
||||||
|
6401844647261612602378676572510019
|
||||||
|
|
||||||
|
B ==
|
||||||
|
21066691
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
37942338209025571690075025099189467992329684223707
|
||||||
|
|
||||||
|
A ==
|
||||||
|
269731366027728777712034888684015329354259
|
||||||
|
|
||||||
|
B ==
|
||||||
|
70333567
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
15306904714258982484473490774101705363308327436988160248323
|
||||||
|
|
||||||
|
A ==
|
||||||
|
37942338209025571690075025099189467992329684223707
|
||||||
|
|
||||||
|
B ==
|
||||||
|
201712723
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
1616744757018513392810355191503853040357155275733333124624513530099
|
||||||
|
|
||||||
|
A ==
|
||||||
|
15306904714258982484473490774101705363308327436988160248323
|
||||||
|
|
||||||
|
B ==
|
||||||
|
52810963
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
464222094814208047161771036072622485188658077940154689939306386289983787983
|
||||||
|
|
||||||
|
A ==
|
||||||
|
1616744757018513392810355191503853040357155275733333124624513530099
|
||||||
|
|
||||||
|
B ==
|
||||||
|
143566909
|
||||||
|
|
||||||
|
G == 5
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
187429931674053784626487560729643601208757374994177258429930699354770049369025096447
|
||||||
|
|
||||||
|
A ==
|
||||||
|
464222094814208047161771036072622485188658077940154689939306386289983787983
|
||||||
|
|
||||||
|
B ==
|
||||||
|
201875281
|
||||||
|
|
||||||
|
G == 5
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563
|
||||||
|
|
||||||
|
A ==
|
||||||
|
187429931674053784626487560729643601208757374994177258429930699354770049369025096447
|
||||||
|
|
||||||
|
B ==
|
||||||
|
268311523
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163
|
||||||
|
|
||||||
|
A ==
|
||||||
|
100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563
|
||||||
|
|
||||||
|
B ==
|
||||||
|
5834287
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623
|
||||||
|
|
||||||
|
A ==
|
||||||
|
1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163
|
||||||
|
|
||||||
|
B ==
|
||||||
|
81567097
|
||||||
|
|
||||||
|
G == 5
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519
|
||||||
|
|
||||||
|
A ==
|
||||||
|
191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623
|
||||||
|
|
||||||
|
B ==
|
||||||
|
151095433
|
||||||
|
|
||||||
|
G == 7
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803
|
||||||
|
|
||||||
|
A ==
|
||||||
|
57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519
|
||||||
|
|
||||||
|
B ==
|
||||||
|
119178679
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979
|
||||||
|
|
||||||
|
A ==
|
||||||
|
13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803
|
||||||
|
|
||||||
|
B ==
|
||||||
|
256552363
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463
|
||||||
|
|
||||||
|
A ==
|
||||||
|
7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979
|
||||||
|
|
||||||
|
B ==
|
||||||
|
86720989
|
||||||
|
|
||||||
|
G == 5
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763
|
||||||
|
|
||||||
|
A ==
|
||||||
|
1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463
|
||||||
|
|
||||||
|
B ==
|
||||||
|
182015287
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
Certificate of primality for:
|
||||||
|
5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243
|
||||||
|
|
||||||
|
A ==
|
||||||
|
446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763
|
||||||
|
|
||||||
|
B ==
|
||||||
|
5920567
|
||||||
|
|
||||||
|
G == 2
|
||||||
|
----------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
Took 3454 ticks, 521 bits
|
||||||
|
P == 5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243
|
||||||
|
Q == 446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763
|
12
makefile
12
makefile
@ -1,12 +1,18 @@
|
|||||||
#Makefile for GCC
|
#Makefile for GCC
|
||||||
#
|
#
|
||||||
#Tom St Denis
|
#Tom St Denis
|
||||||
CFLAGS += -I./ -Wall -W -Wshadow -O3 -funroll-loops
|
CFLAGS += -I./ -Wall -W -Wshadow
|
||||||
|
|
||||||
|
#for speed
|
||||||
|
CFLAGS += -O3 -funroll-loops
|
||||||
|
|
||||||
|
#for size
|
||||||
|
#CFLAGS += -Os
|
||||||
|
|
||||||
#x86 optimizations [should be valid for any GCC install though]
|
#x86 optimizations [should be valid for any GCC install though]
|
||||||
CFLAGS += -fomit-frame-pointer
|
CFLAGS += -fomit-frame-pointer
|
||||||
|
|
||||||
VERSION=0.28
|
VERSION=0.29
|
||||||
|
|
||||||
default: libtommath.a
|
default: libtommath.a
|
||||||
|
|
||||||
@ -44,7 +50,7 @@ bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \
|
|||||||
bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
|
bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
|
||||||
bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
|
bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
|
||||||
bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
|
bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
|
||||||
bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_prime_random.o bn_prime_sizes_tab.o
|
bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_prime_random.o bn_prime_sizes_tab.o bn_mp_exteuclid.o
|
||||||
|
|
||||||
libtommath.a: $(OBJECTS)
|
libtommath.a: $(OBJECTS)
|
||||||
$(AR) $(ARFLAGS) libtommath.a $(OBJECTS)
|
$(AR) $(ARFLAGS) libtommath.a $(OBJECTS)
|
||||||
|
@ -29,7 +29,7 @@ bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \
|
|||||||
bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \
|
bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \
|
||||||
bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \
|
bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \
|
||||||
bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \
|
bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \
|
||||||
bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_prime_random.obj bn_prime_sizes_tab.obj
|
bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_prime_random.obj bn_prime_sizes_tab.obj bn_mp_exteuclid.obj
|
||||||
|
|
||||||
TARGET = libtommath.lib
|
TARGET = libtommath.lib
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \
|
|||||||
bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
|
bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
|
||||||
bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
|
bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
|
||||||
bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
|
bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
|
||||||
bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_prime_random.o bn_prime_sizes_tab.o
|
bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_prime_random.o bn_prime_sizes_tab.o bn_mp_exteuclid.o
|
||||||
|
|
||||||
# make a Windows DLL via Cygwin
|
# make a Windows DLL via Cygwin
|
||||||
windll: $(OBJECTS)
|
windll: $(OBJECTS)
|
||||||
|
@ -28,7 +28,7 @@ bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \
|
|||||||
bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \
|
bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \
|
||||||
bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \
|
bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \
|
||||||
bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \
|
bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \
|
||||||
bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_prime_random.obj bn_prime_sizes_tab.obj
|
bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_prime_random.obj bn_prime_sizes_tab.obj bn_mp_exteuclid.obj
|
||||||
|
|
||||||
library: $(OBJECTS)
|
library: $(OBJECTS)
|
||||||
lib /out:tommath.lib $(OBJECTS)
|
lib /out:tommath.lib $(OBJECTS)
|
||||||
|
BIN
poster.pdf
BIN
poster.pdf
Binary file not shown.
138
pre_gen/mpi.c
138
pre_gen/mpi.c
@ -1902,7 +1902,7 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
|
|||||||
t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
|
t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
|
||||||
|
|
||||||
/* now subtract 3 * [w/3] from w, to get the remainder */
|
/* now subtract 3 * [w/3] from w, to get the remainder */
|
||||||
w -= (t << ((mp_word)1)) + t;
|
w -= t+t+t;
|
||||||
|
|
||||||
/* fixup the remainder as required since
|
/* fixup the remainder as required since
|
||||||
* the optimization is not exact.
|
* the optimization is not exact.
|
||||||
@ -1966,8 +1966,7 @@ static int s_is_power_of_two(mp_digit b, int *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* single digit division (based on routine from MPI) */
|
/* single digit division (based on routine from MPI) */
|
||||||
int
|
int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
||||||
mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
|
||||||
{
|
{
|
||||||
mp_int q;
|
mp_int q;
|
||||||
mp_word w;
|
mp_word w;
|
||||||
@ -2665,6 +2664,79 @@ __M:
|
|||||||
|
|
||||||
/* End: bn_mp_exptmod_fast.c */
|
/* End: bn_mp_exptmod_fast.c */
|
||||||
|
|
||||||
|
/* Start: bn_mp_exteuclid.c */
|
||||||
|
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||||
|
*
|
||||||
|
* LibTomMath is a library that provides multiple-precision
|
||||||
|
* integer arithmetic as well as number theoretic functionality.
|
||||||
|
*
|
||||||
|
* The library was designed directly after the MPI library by
|
||||||
|
* Michael Fromberger but has been written from scratch with
|
||||||
|
* additional optimizations in place.
|
||||||
|
*
|
||||||
|
* The library is free for all purposes without any express
|
||||||
|
* guarantee it works.
|
||||||
|
*
|
||||||
|
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
|
||||||
|
*/
|
||||||
|
#include <tommath.h>
|
||||||
|
|
||||||
|
/* Extended euclidean algorithm of (a, b) produces
|
||||||
|
a*u1 + b*u2 = u3
|
||||||
|
*/
|
||||||
|
int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
|
||||||
|
{
|
||||||
|
mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize, (u1,u2,u3) = (1,0,a) */
|
||||||
|
mp_set(&u1, 1);
|
||||||
|
if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* initialize, (v1,v2,v3) = (0,1,b) */
|
||||||
|
mp_set(&v2, 1);
|
||||||
|
if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* loop while v3 != 0 */
|
||||||
|
while (mp_iszero(&v3) == MP_NO) {
|
||||||
|
/* q = u3/v3 */
|
||||||
|
if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
|
||||||
|
if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* (u1,u2,u3) = (v1,v2,v3) */
|
||||||
|
if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
|
||||||
|
/* (v1,v2,v3) = (t1,t2,t3) */
|
||||||
|
if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; }
|
||||||
|
if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy result out */
|
||||||
|
if (U1 != NULL) { mp_exch(U1, &u1); }
|
||||||
|
if (U2 != NULL) { mp_exch(U2, &u2); }
|
||||||
|
if (U3 != NULL) { mp_exch(U3, &u3); }
|
||||||
|
|
||||||
|
err = MP_OKAY;
|
||||||
|
_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End: bn_mp_exteuclid.c */
|
||||||
|
|
||||||
/* Start: bn_mp_fread.c */
|
/* Start: bn_mp_fread.c */
|
||||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||||
*
|
*
|
||||||
@ -2752,9 +2824,8 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream)
|
|||||||
char *buf;
|
char *buf;
|
||||||
int err, len, x;
|
int err, len, x;
|
||||||
|
|
||||||
len = mp_radix_size(a, radix);
|
if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
|
||||||
if (len == 0) {
|
return err;
|
||||||
return MP_VAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = XMALLOC (len);
|
buf = XMALLOC (len);
|
||||||
@ -4201,7 +4272,6 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
|||||||
} else {
|
} else {
|
||||||
res = s_mp_mul (a, b, c);
|
res = s_mp_mul (a, b, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
c->sign = neg;
|
c->sign = neg;
|
||||||
return res;
|
return res;
|
||||||
@ -5251,26 +5321,28 @@ error:
|
|||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* returns size of ASCII reprensentation */
|
/* returns size of ASCII reprensentation */
|
||||||
int
|
int mp_radix_size (mp_int * a, int radix, int *size)
|
||||||
mp_radix_size (mp_int * a, int radix)
|
|
||||||
{
|
{
|
||||||
int res, digs;
|
int res, digs;
|
||||||
mp_int t;
|
mp_int t;
|
||||||
mp_digit d;
|
mp_digit d;
|
||||||
|
|
||||||
|
*size = 0;
|
||||||
|
|
||||||
/* special case for binary */
|
/* special case for binary */
|
||||||
if (radix == 2) {
|
if (radix == 2) {
|
||||||
return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
|
*size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
|
||||||
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure the radix is in range */
|
/* make sure the radix is in range */
|
||||||
if (radix < 2 || radix > 64) {
|
if (radix < 2 || radix > 64) {
|
||||||
return 0;
|
return MP_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init a copy of the input */
|
/* init a copy of the input */
|
||||||
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
|
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
|
||||||
return 0;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* digs is the digit count */
|
/* digs is the digit count */
|
||||||
@ -5293,7 +5365,8 @@ mp_radix_size (mp_int * a, int radix)
|
|||||||
mp_clear (&t);
|
mp_clear (&t);
|
||||||
|
|
||||||
/* return digs + 1, the 1 is for the NULL byte that would be required. */
|
/* return digs + 1, the 1 is for the NULL byte that would be required. */
|
||||||
return digs + 1;
|
*size = digs + 1;
|
||||||
|
return MP_OKAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5392,8 +5465,7 @@ mp_rand (mp_int * a, int digits)
|
|||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* read a string [ASCII] in a given radix */
|
/* read a string [ASCII] in a given radix */
|
||||||
int
|
int mp_read_radix (mp_int * a, char *str, int radix)
|
||||||
mp_read_radix (mp_int * a, char *str, int radix)
|
|
||||||
{
|
{
|
||||||
int y, res, neg;
|
int y, res, neg;
|
||||||
char ch;
|
char ch;
|
||||||
@ -5989,7 +6061,7 @@ int mp_set_int (mp_int * a, unsigned long b)
|
|||||||
int mp_shrink (mp_int * a)
|
int mp_shrink (mp_int * a)
|
||||||
{
|
{
|
||||||
mp_digit *tmp;
|
mp_digit *tmp;
|
||||||
if (a->alloc != a->used) {
|
if (a->alloc != a->used && a->used > 0) {
|
||||||
if ((tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
|
if ((tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
|
||||||
return MP_MEM;
|
return MP_MEM;
|
||||||
}
|
}
|
||||||
@ -6019,8 +6091,7 @@ int mp_shrink (mp_int * a)
|
|||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* get the size for an signed equivalent */
|
/* get the size for an signed equivalent */
|
||||||
int
|
int mp_signed_bin_size (mp_int * a)
|
||||||
mp_signed_bin_size (mp_int * a)
|
|
||||||
{
|
{
|
||||||
return 1 + mp_unsigned_bin_size (a);
|
return 1 + mp_unsigned_bin_size (a);
|
||||||
}
|
}
|
||||||
@ -6049,6 +6120,7 @@ int
|
|||||||
mp_sqr (mp_int * a, mp_int * b)
|
mp_sqr (mp_int * a, mp_int * b)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
/* use Toom-Cook? */
|
/* use Toom-Cook? */
|
||||||
if (a->used >= TOOM_SQR_CUTOFF) {
|
if (a->used >= TOOM_SQR_CUTOFF) {
|
||||||
res = mp_toom_sqr(a, b);
|
res = mp_toom_sqr(a, b);
|
||||||
@ -6892,8 +6964,7 @@ ERR:
|
|||||||
#include <tommath.h>
|
#include <tommath.h>
|
||||||
|
|
||||||
/* stores a bignum as a ASCII string in a given radix (2..64) */
|
/* stores a bignum as a ASCII string in a given radix (2..64) */
|
||||||
int
|
int mp_toradix (mp_int * a, char *str, int radix)
|
||||||
mp_toradix (mp_int * a, char *str, int radix)
|
|
||||||
{
|
{
|
||||||
int res, digs;
|
int res, digs;
|
||||||
mp_int t;
|
mp_int t;
|
||||||
@ -7086,25 +7157,7 @@ static const struct {
|
|||||||
{ 1408, 3 },
|
{ 1408, 3 },
|
||||||
{ 1536, 3 },
|
{ 1536, 3 },
|
||||||
{ 1664, 3 },
|
{ 1664, 3 },
|
||||||
{ 1792, 2 },
|
{ 1792, 2 } };
|
||||||
{ 1920, 2 },
|
|
||||||
{ 2048, 2 },
|
|
||||||
{ 2176, 2 },
|
|
||||||
{ 2304, 2 },
|
|
||||||
{ 2432, 2 },
|
|
||||||
{ 2560, 2 },
|
|
||||||
{ 2688, 2 },
|
|
||||||
{ 2816, 2 },
|
|
||||||
{ 2944, 2 },
|
|
||||||
{ 3072, 2 },
|
|
||||||
{ 3200, 2 },
|
|
||||||
{ 3328, 2 },
|
|
||||||
{ 3456, 2 },
|
|
||||||
{ 3584, 2 },
|
|
||||||
{ 3712, 2 },
|
|
||||||
{ 3840, 1 },
|
|
||||||
{ 3968, 1 },
|
|
||||||
{ 4096, 1 } };
|
|
||||||
|
|
||||||
/* returns # of RM trials required for a given bit size */
|
/* returns # of RM trials required for a given bit size */
|
||||||
int mp_prime_rabin_miller_trials(int size)
|
int mp_prime_rabin_miller_trials(int size)
|
||||||
@ -7351,8 +7404,7 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c)
|
|||||||
#define TAB_SIZE 256
|
#define TAB_SIZE 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||||
s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
|
||||||
{
|
{
|
||||||
mp_int M[TAB_SIZE], res, mu;
|
mp_int M[TAB_SIZE], res, mu;
|
||||||
mp_digit buf;
|
mp_digit buf;
|
||||||
@ -7516,10 +7568,10 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
|||||||
|
|
||||||
/* then multiply */
|
/* then multiply */
|
||||||
if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
|
if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
|
||||||
goto __MU;
|
goto __RES;
|
||||||
}
|
}
|
||||||
if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
|
if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
|
||||||
goto __MU;
|
goto __RES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* empty window and reset */
|
/* empty window and reset */
|
||||||
|
@ -338,6 +338,9 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
|
|||||||
/* c = (a, b) */
|
/* c = (a, b) */
|
||||||
int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
|
int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
|
||||||
|
|
||||||
|
/* produces value such that U1*a + U2*b = U3 */
|
||||||
|
int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
|
||||||
|
|
||||||
/* c = [a, b] or (a*b)/(a, b) */
|
/* c = [a, b] or (a*b)/(a, b) */
|
||||||
int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
|
int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
|
||||||
|
|
||||||
@ -466,7 +469,7 @@ int mp_to_signed_bin(mp_int *a, unsigned char *b);
|
|||||||
|
|
||||||
int mp_read_radix(mp_int *a, char *str, int radix);
|
int mp_read_radix(mp_int *a, char *str, int radix);
|
||||||
int mp_toradix(mp_int *a, char *str, int radix);
|
int mp_toradix(mp_int *a, char *str, int radix);
|
||||||
int mp_radix_size(mp_int *a, int radix);
|
int mp_radix_size(mp_int *a, int radix, int *size);
|
||||||
|
|
||||||
int mp_fread(mp_int *a, int radix, FILE *stream);
|
int mp_fread(mp_int *a, int radix, FILE *stream);
|
||||||
int mp_fwrite(mp_int *a, int radix, FILE *stream);
|
int mp_fwrite(mp_int *a, int radix, FILE *stream);
|
||||||
|
254
tommath.out
254
tommath.out
@ -1,7 +1,7 @@
|
|||||||
\BOOKMARK [0][-]{chapter.1}{Introduction}{}
|
\BOOKMARK [0][-]{chapter.1}{Introduction}{}
|
||||||
\BOOKMARK [1][-]{section.1.1}{Multiple Precision Arithmetic}{chapter.1}
|
\BOOKMARK [1][-]{section.1.1}{Multiple Precision Arithmetic}{chapter.1}
|
||||||
\BOOKMARK [2][-]{subsection.1.1.1}{The Need for Multiple Precision Arithmetic}{section.1.1}
|
\BOOKMARK [2][-]{subsection.1.1.1}{What is Multiple Precision Arithmetic?}{section.1.1}
|
||||||
\BOOKMARK [2][-]{subsection.1.1.2}{What is Multiple Precision Arithmetic?}{section.1.1}
|
\BOOKMARK [2][-]{subsection.1.1.2}{The Need for Multiple Precision Arithmetic}{section.1.1}
|
||||||
\BOOKMARK [2][-]{subsection.1.1.3}{Benefits of Multiple Precision Arithmetic}{section.1.1}
|
\BOOKMARK [2][-]{subsection.1.1.3}{Benefits of Multiple Precision Arithmetic}{section.1.1}
|
||||||
\BOOKMARK [1][-]{section.1.2}{Purpose of This Text}{chapter.1}
|
\BOOKMARK [1][-]{section.1.2}{Purpose of This Text}{chapter.1}
|
||||||
\BOOKMARK [1][-]{section.1.3}{Discussion and Notation}{chapter.1}
|
\BOOKMARK [1][-]{section.1.3}{Discussion and Notation}{chapter.1}
|
||||||
@ -11,129 +11,129 @@
|
|||||||
\BOOKMARK [2][-]{subsection.1.3.4}{Mathematical Expressions}{section.1.3}
|
\BOOKMARK [2][-]{subsection.1.3.4}{Mathematical Expressions}{section.1.3}
|
||||||
\BOOKMARK [2][-]{subsection.1.3.5}{Work Effort}{section.1.3}
|
\BOOKMARK [2][-]{subsection.1.3.5}{Work Effort}{section.1.3}
|
||||||
\BOOKMARK [1][-]{section.1.4}{Exercises}{chapter.1}
|
\BOOKMARK [1][-]{section.1.4}{Exercises}{chapter.1}
|
||||||
\BOOKMARK [0][-]{chapter.2}{Introduction to LibTomMath}{}
|
\BOOKMARK [1][-]{section.1.5}{Introduction to LibTomMath}{chapter.1}
|
||||||
\BOOKMARK [1][-]{section.2.1}{What is LibTomMath?}{chapter.2}
|
\BOOKMARK [2][-]{subsection.1.5.1}{What is LibTomMath?}{section.1.5}
|
||||||
\BOOKMARK [1][-]{section.2.2}{Goals of LibTomMath}{chapter.2}
|
\BOOKMARK [2][-]{subsection.1.5.2}{Goals of LibTomMath}{section.1.5}
|
||||||
\BOOKMARK [1][-]{section.2.3}{Choice of LibTomMath}{chapter.2}
|
\BOOKMARK [1][-]{section.1.6}{Choice of LibTomMath}{chapter.1}
|
||||||
\BOOKMARK [2][-]{subsection.2.3.1}{Code Base}{section.2.3}
|
\BOOKMARK [2][-]{subsection.1.6.1}{Code Base}{section.1.6}
|
||||||
\BOOKMARK [2][-]{subsection.2.3.2}{API Simplicity}{section.2.3}
|
\BOOKMARK [2][-]{subsection.1.6.2}{API Simplicity}{section.1.6}
|
||||||
\BOOKMARK [2][-]{subsection.2.3.3}{Optimizations}{section.2.3}
|
\BOOKMARK [2][-]{subsection.1.6.3}{Optimizations}{section.1.6}
|
||||||
\BOOKMARK [2][-]{subsection.2.3.4}{Portability and Stability}{section.2.3}
|
\BOOKMARK [2][-]{subsection.1.6.4}{Portability and Stability}{section.1.6}
|
||||||
\BOOKMARK [2][-]{subsection.2.3.5}{Choice}{section.2.3}
|
\BOOKMARK [2][-]{subsection.1.6.5}{Choice}{section.1.6}
|
||||||
\BOOKMARK [0][-]{chapter.3}{Getting Started}{}
|
\BOOKMARK [0][-]{chapter.2}{Getting Started}{}
|
||||||
\BOOKMARK [1][-]{section.3.1}{Library Basics}{chapter.3}
|
\BOOKMARK [1][-]{section.2.1}{Library Basics}{chapter.2}
|
||||||
\BOOKMARK [1][-]{section.3.2}{What is a Multiple Precision Integer?}{chapter.3}
|
\BOOKMARK [1][-]{section.2.2}{What is a Multiple Precision Integer?}{chapter.2}
|
||||||
\BOOKMARK [2][-]{subsection.3.2.1}{The mp\137int Structure}{section.3.2}
|
\BOOKMARK [2][-]{subsection.2.2.1}{The mp\137int Structure}{section.2.2}
|
||||||
\BOOKMARK [1][-]{section.3.3}{Argument Passing}{chapter.3}
|
\BOOKMARK [1][-]{section.2.3}{Argument Passing}{chapter.2}
|
||||||
\BOOKMARK [1][-]{section.3.4}{Return Values}{chapter.3}
|
\BOOKMARK [1][-]{section.2.4}{Return Values}{chapter.2}
|
||||||
\BOOKMARK [1][-]{section.3.5}{Initialization and Clearing}{chapter.3}
|
\BOOKMARK [1][-]{section.2.5}{Initialization and Clearing}{chapter.2}
|
||||||
\BOOKMARK [2][-]{subsection.3.5.1}{Initializing an mp\137int}{section.3.5}
|
\BOOKMARK [2][-]{subsection.2.5.1}{Initializing an mp\137int}{section.2.5}
|
||||||
\BOOKMARK [2][-]{subsection.3.5.2}{Clearing an mp\137int}{section.3.5}
|
\BOOKMARK [2][-]{subsection.2.5.2}{Clearing an mp\137int}{section.2.5}
|
||||||
\BOOKMARK [1][-]{section.3.6}{Maintenance Algorithms}{chapter.3}
|
\BOOKMARK [1][-]{section.2.6}{Maintenance Algorithms}{chapter.2}
|
||||||
\BOOKMARK [2][-]{subsection.3.6.1}{Augmenting an mp\137int's Precision}{section.3.6}
|
\BOOKMARK [2][-]{subsection.2.6.1}{Augmenting an mp\137int's Precision}{section.2.6}
|
||||||
\BOOKMARK [2][-]{subsection.3.6.2}{Initializing Variable Precision mp\137ints}{section.3.6}
|
\BOOKMARK [2][-]{subsection.2.6.2}{Initializing Variable Precision mp\137ints}{section.2.6}
|
||||||
\BOOKMARK [2][-]{subsection.3.6.3}{Multiple Integer Initializations and Clearings}{section.3.6}
|
\BOOKMARK [2][-]{subsection.2.6.3}{Multiple Integer Initializations and Clearings}{section.2.6}
|
||||||
\BOOKMARK [2][-]{subsection.3.6.4}{Clamping Excess Digits}{section.3.6}
|
\BOOKMARK [2][-]{subsection.2.6.4}{Clamping Excess Digits}{section.2.6}
|
||||||
\BOOKMARK [0][-]{chapter.4}{Basic Operations}{}
|
\BOOKMARK [0][-]{chapter.3}{Basic Operations}{}
|
||||||
|
\BOOKMARK [1][-]{section.3.1}{Introduction}{chapter.3}
|
||||||
|
\BOOKMARK [1][-]{section.3.2}{Assigning Values to mp\137int Structures}{chapter.3}
|
||||||
|
\BOOKMARK [2][-]{subsection.3.2.1}{Copying an mp\137int}{section.3.2}
|
||||||
|
\BOOKMARK [2][-]{subsection.3.2.2}{Creating a Clone}{section.3.2}
|
||||||
|
\BOOKMARK [1][-]{section.3.3}{Zeroing an Integer}{chapter.3}
|
||||||
|
\BOOKMARK [1][-]{section.3.4}{Sign Manipulation}{chapter.3}
|
||||||
|
\BOOKMARK [2][-]{subsection.3.4.1}{Absolute Value}{section.3.4}
|
||||||
|
\BOOKMARK [2][-]{subsection.3.4.2}{Integer Negation}{section.3.4}
|
||||||
|
\BOOKMARK [1][-]{section.3.5}{Small Constants}{chapter.3}
|
||||||
|
\BOOKMARK [2][-]{subsection.3.5.1}{Setting Small Constants}{section.3.5}
|
||||||
|
\BOOKMARK [2][-]{subsection.3.5.2}{Setting Large Constants}{section.3.5}
|
||||||
|
\BOOKMARK [1][-]{section.3.6}{Comparisons}{chapter.3}
|
||||||
|
\BOOKMARK [2][-]{subsection.3.6.1}{Unsigned Comparisions}{section.3.6}
|
||||||
|
\BOOKMARK [2][-]{subsection.3.6.2}{Signed Comparisons}{section.3.6}
|
||||||
|
\BOOKMARK [0][-]{chapter.4}{Basic Arithmetic}{}
|
||||||
\BOOKMARK [1][-]{section.4.1}{Introduction}{chapter.4}
|
\BOOKMARK [1][-]{section.4.1}{Introduction}{chapter.4}
|
||||||
\BOOKMARK [1][-]{section.4.2}{Assigning Values to mp\137int Structures}{chapter.4}
|
\BOOKMARK [1][-]{section.4.2}{Addition and Subtraction}{chapter.4}
|
||||||
\BOOKMARK [2][-]{subsection.4.2.1}{Copying an mp\137int}{section.4.2}
|
\BOOKMARK [2][-]{subsection.4.2.1}{Low Level Addition}{section.4.2}
|
||||||
\BOOKMARK [2][-]{subsection.4.2.2}{Creating a Clone}{section.4.2}
|
\BOOKMARK [2][-]{subsection.4.2.2}{Low Level Subtraction}{section.4.2}
|
||||||
\BOOKMARK [1][-]{section.4.3}{Zeroing an Integer}{chapter.4}
|
\BOOKMARK [2][-]{subsection.4.2.3}{High Level Addition}{section.4.2}
|
||||||
\BOOKMARK [1][-]{section.4.4}{Sign Manipulation}{chapter.4}
|
\BOOKMARK [2][-]{subsection.4.2.4}{High Level Subtraction}{section.4.2}
|
||||||
\BOOKMARK [2][-]{subsection.4.4.1}{Absolute Value}{section.4.4}
|
\BOOKMARK [1][-]{section.4.3}{Bit and Digit Shifting}{chapter.4}
|
||||||
\BOOKMARK [2][-]{subsection.4.4.2}{Integer Negation}{section.4.4}
|
\BOOKMARK [2][-]{subsection.4.3.1}{Multiplication by Two}{section.4.3}
|
||||||
\BOOKMARK [1][-]{section.4.5}{Small Constants}{chapter.4}
|
\BOOKMARK [2][-]{subsection.4.3.2}{Division by Two}{section.4.3}
|
||||||
\BOOKMARK [2][-]{subsection.4.5.1}{Setting Small Constants}{section.4.5}
|
\BOOKMARK [1][-]{section.4.4}{Polynomial Basis Operations}{chapter.4}
|
||||||
\BOOKMARK [2][-]{subsection.4.5.2}{Setting Large Constants}{section.4.5}
|
\BOOKMARK [2][-]{subsection.4.4.1}{Multiplication by x}{section.4.4}
|
||||||
\BOOKMARK [1][-]{section.4.6}{Comparisons}{chapter.4}
|
\BOOKMARK [2][-]{subsection.4.4.2}{Division by x}{section.4.4}
|
||||||
\BOOKMARK [2][-]{subsection.4.6.1}{Unsigned Comparisions}{section.4.6}
|
\BOOKMARK [1][-]{section.4.5}{Powers of Two}{chapter.4}
|
||||||
\BOOKMARK [2][-]{subsection.4.6.2}{Signed Comparisons}{section.4.6}
|
\BOOKMARK [2][-]{subsection.4.5.1}{Multiplication by Power of Two}{section.4.5}
|
||||||
\BOOKMARK [0][-]{chapter.5}{Basic Arithmetic}{}
|
\BOOKMARK [2][-]{subsection.4.5.2}{Division by Power of Two}{section.4.5}
|
||||||
\BOOKMARK [1][-]{section.5.1}{Introduction}{chapter.5}
|
\BOOKMARK [2][-]{subsection.4.5.3}{Remainder of Division by Power of Two}{section.4.5}
|
||||||
\BOOKMARK [1][-]{section.5.2}{Addition and Subtraction}{chapter.5}
|
\BOOKMARK [0][-]{chapter.5}{Multiplication and Squaring}{}
|
||||||
\BOOKMARK [2][-]{subsection.5.2.1}{Low Level Addition}{section.5.2}
|
\BOOKMARK [1][-]{section.5.1}{The Multipliers}{chapter.5}
|
||||||
\BOOKMARK [2][-]{subsection.5.2.2}{Low Level Subtraction}{section.5.2}
|
\BOOKMARK [1][-]{section.5.2}{Multiplication}{chapter.5}
|
||||||
\BOOKMARK [2][-]{subsection.5.2.3}{High Level Addition}{section.5.2}
|
\BOOKMARK [2][-]{subsection.5.2.1}{The Baseline Multiplication}{section.5.2}
|
||||||
\BOOKMARK [2][-]{subsection.5.2.4}{High Level Subtraction}{section.5.2}
|
\BOOKMARK [2][-]{subsection.5.2.2}{Faster Multiplication by the ``Comba'' Method}{section.5.2}
|
||||||
\BOOKMARK [1][-]{section.5.3}{Bit and Digit Shifting}{chapter.5}
|
\BOOKMARK [2][-]{subsection.5.2.3}{Polynomial Basis Multiplication}{section.5.2}
|
||||||
\BOOKMARK [2][-]{subsection.5.3.1}{Multiplication by Two}{section.5.3}
|
\BOOKMARK [2][-]{subsection.5.2.4}{Karatsuba Multiplication}{section.5.2}
|
||||||
\BOOKMARK [2][-]{subsection.5.3.2}{Division by Two}{section.5.3}
|
\BOOKMARK [2][-]{subsection.5.2.5}{Toom-Cook 3-Way Multiplication}{section.5.2}
|
||||||
\BOOKMARK [1][-]{section.5.4}{Polynomial Basis Operations}{chapter.5}
|
\BOOKMARK [2][-]{subsection.5.2.6}{Signed Multiplication}{section.5.2}
|
||||||
\BOOKMARK [2][-]{subsection.5.4.1}{Multiplication by x}{section.5.4}
|
\BOOKMARK [1][-]{section.5.3}{Squaring}{chapter.5}
|
||||||
\BOOKMARK [2][-]{subsection.5.4.2}{Division by x}{section.5.4}
|
\BOOKMARK [2][-]{subsection.5.3.1}{The Baseline Squaring Algorithm}{section.5.3}
|
||||||
\BOOKMARK [1][-]{section.5.5}{Powers of Two}{chapter.5}
|
\BOOKMARK [2][-]{subsection.5.3.2}{Faster Squaring by the ``Comba'' Method}{section.5.3}
|
||||||
\BOOKMARK [2][-]{subsection.5.5.1}{Multiplication by Power of Two}{section.5.5}
|
\BOOKMARK [2][-]{subsection.5.3.3}{Polynomial Basis Squaring}{section.5.3}
|
||||||
\BOOKMARK [2][-]{subsection.5.5.2}{Division by Power of Two}{section.5.5}
|
\BOOKMARK [2][-]{subsection.5.3.4}{Karatsuba Squaring}{section.5.3}
|
||||||
\BOOKMARK [2][-]{subsection.5.5.3}{Remainder of Division by Power of Two}{section.5.5}
|
\BOOKMARK [2][-]{subsection.5.3.5}{Toom-Cook Squaring}{section.5.3}
|
||||||
\BOOKMARK [0][-]{chapter.6}{Multiplication and Squaring}{}
|
\BOOKMARK [2][-]{subsection.5.3.6}{High Level Squaring}{section.5.3}
|
||||||
\BOOKMARK [1][-]{section.6.1}{The Multipliers}{chapter.6}
|
\BOOKMARK [0][-]{chapter.6}{Modular Reduction}{}
|
||||||
\BOOKMARK [1][-]{section.6.2}{Multiplication}{chapter.6}
|
\BOOKMARK [1][-]{section.6.1}{Basics of Modular Reduction}{chapter.6}
|
||||||
\BOOKMARK [2][-]{subsection.6.2.1}{The Baseline Multiplication}{section.6.2}
|
\BOOKMARK [1][-]{section.6.2}{The Barrett Reduction}{chapter.6}
|
||||||
\BOOKMARK [2][-]{subsection.6.2.2}{Faster Multiplication by the ``Comba'' Method}{section.6.2}
|
\BOOKMARK [2][-]{subsection.6.2.1}{Fixed Point Arithmetic}{section.6.2}
|
||||||
\BOOKMARK [2][-]{subsection.6.2.3}{Polynomial Basis Multiplication}{section.6.2}
|
\BOOKMARK [2][-]{subsection.6.2.2}{Choosing a Radix Point}{section.6.2}
|
||||||
\BOOKMARK [2][-]{subsection.6.2.4}{Karatsuba Multiplication}{section.6.2}
|
\BOOKMARK [2][-]{subsection.6.2.3}{Trimming the Quotient}{section.6.2}
|
||||||
\BOOKMARK [2][-]{subsection.6.2.5}{Toom-Cook 3-Way Multiplication}{section.6.2}
|
\BOOKMARK [2][-]{subsection.6.2.4}{Trimming the Residue}{section.6.2}
|
||||||
\BOOKMARK [2][-]{subsection.6.2.6}{Signed Multiplication}{section.6.2}
|
\BOOKMARK [2][-]{subsection.6.2.5}{The Barrett Algorithm}{section.6.2}
|
||||||
\BOOKMARK [1][-]{section.6.3}{Squaring}{chapter.6}
|
\BOOKMARK [2][-]{subsection.6.2.6}{The Barrett Setup Algorithm}{section.6.2}
|
||||||
\BOOKMARK [2][-]{subsection.6.3.1}{The Baseline Squaring Algorithm}{section.6.3}
|
\BOOKMARK [1][-]{section.6.3}{The Montgomery Reduction}{chapter.6}
|
||||||
\BOOKMARK [2][-]{subsection.6.3.2}{Faster Squaring by the ``Comba'' Method}{section.6.3}
|
\BOOKMARK [2][-]{subsection.6.3.1}{Digit Based Montgomery Reduction}{section.6.3}
|
||||||
\BOOKMARK [2][-]{subsection.6.3.3}{Polynomial Basis Squaring}{section.6.3}
|
\BOOKMARK [2][-]{subsection.6.3.2}{Baseline Montgomery Reduction}{section.6.3}
|
||||||
\BOOKMARK [2][-]{subsection.6.3.4}{Karatsuba Squaring}{section.6.3}
|
\BOOKMARK [2][-]{subsection.6.3.3}{Faster ``Comba'' Montgomery Reduction}{section.6.3}
|
||||||
\BOOKMARK [2][-]{subsection.6.3.5}{Toom-Cook Squaring}{section.6.3}
|
\BOOKMARK [2][-]{subsection.6.3.4}{Montgomery Setup}{section.6.3}
|
||||||
\BOOKMARK [2][-]{subsection.6.3.6}{High Level Squaring}{section.6.3}
|
\BOOKMARK [1][-]{section.6.4}{The Diminished Radix Algorithm}{chapter.6}
|
||||||
\BOOKMARK [0][-]{chapter.7}{Modular Reduction}{}
|
\BOOKMARK [2][-]{subsection.6.4.1}{Choice of Moduli}{section.6.4}
|
||||||
\BOOKMARK [1][-]{section.7.1}{Basics of Modular Reduction}{chapter.7}
|
\BOOKMARK [2][-]{subsection.6.4.2}{Choice of k}{section.6.4}
|
||||||
\BOOKMARK [1][-]{section.7.2}{The Barrett Reduction}{chapter.7}
|
\BOOKMARK [2][-]{subsection.6.4.3}{Restricted Diminished Radix Reduction}{section.6.4}
|
||||||
\BOOKMARK [2][-]{subsection.7.2.1}{Fixed Point Arithmetic}{section.7.2}
|
\BOOKMARK [2][-]{subsection.6.4.4}{Unrestricted Diminished Radix Reduction}{section.6.4}
|
||||||
\BOOKMARK [2][-]{subsection.7.2.2}{Choosing a Radix Point}{section.7.2}
|
\BOOKMARK [1][-]{section.6.5}{Algorithm Comparison}{chapter.6}
|
||||||
\BOOKMARK [2][-]{subsection.7.2.3}{Trimming the Quotient}{section.7.2}
|
\BOOKMARK [0][-]{chapter.7}{Exponentiation}{}
|
||||||
\BOOKMARK [2][-]{subsection.7.2.4}{Trimming the Residue}{section.7.2}
|
\BOOKMARK [1][-]{section.7.1}{Exponentiation Basics}{chapter.7}
|
||||||
\BOOKMARK [2][-]{subsection.7.2.5}{The Barrett Algorithm}{section.7.2}
|
\BOOKMARK [2][-]{subsection.7.1.1}{Single Digit Exponentiation}{section.7.1}
|
||||||
\BOOKMARK [2][-]{subsection.7.2.6}{The Barrett Setup Algorithm}{section.7.2}
|
\BOOKMARK [1][-]{section.7.2}{k-ary Exponentiation}{chapter.7}
|
||||||
\BOOKMARK [1][-]{section.7.3}{The Montgomery Reduction}{chapter.7}
|
\BOOKMARK [2][-]{subsection.7.2.1}{Optimal Values of k}{section.7.2}
|
||||||
\BOOKMARK [2][-]{subsection.7.3.1}{Digit Based Montgomery Reduction}{section.7.3}
|
\BOOKMARK [2][-]{subsection.7.2.2}{Sliding-Window Exponentiation}{section.7.2}
|
||||||
\BOOKMARK [2][-]{subsection.7.3.2}{Baseline Montgomery Reduction}{section.7.3}
|
\BOOKMARK [1][-]{section.7.3}{Modular Exponentiation}{chapter.7}
|
||||||
\BOOKMARK [2][-]{subsection.7.3.3}{Faster ``Comba'' Montgomery Reduction}{section.7.3}
|
\BOOKMARK [2][-]{subsection.7.3.1}{Barrett Modular Exponentiation}{section.7.3}
|
||||||
\BOOKMARK [2][-]{subsection.7.3.4}{Montgomery Setup}{section.7.3}
|
\BOOKMARK [1][-]{section.7.4}{Quick Power of Two}{chapter.7}
|
||||||
\BOOKMARK [1][-]{section.7.4}{The Diminished Radix Algorithm}{chapter.7}
|
\BOOKMARK [0][-]{chapter.8}{Higher Level Algorithms}{}
|
||||||
\BOOKMARK [2][-]{subsection.7.4.1}{Choice of Moduli}{section.7.4}
|
\BOOKMARK [1][-]{section.8.1}{Integer Division with Remainder}{chapter.8}
|
||||||
\BOOKMARK [2][-]{subsection.7.4.2}{Choice of k}{section.7.4}
|
\BOOKMARK [2][-]{subsection.8.1.1}{Quotient Estimation}{section.8.1}
|
||||||
\BOOKMARK [2][-]{subsection.7.4.3}{Restricted Diminished Radix Reduction}{section.7.4}
|
\BOOKMARK [2][-]{subsection.8.1.2}{Normalized Integers}{section.8.1}
|
||||||
\BOOKMARK [2][-]{subsection.7.4.4}{Unrestricted Diminished Radix Reduction}{section.7.4}
|
\BOOKMARK [2][-]{subsection.8.1.3}{Radix- Division with Remainder}{section.8.1}
|
||||||
\BOOKMARK [1][-]{section.7.5}{Algorithm Comparison}{chapter.7}
|
\BOOKMARK [1][-]{section.8.2}{Single Digit Helpers}{chapter.8}
|
||||||
\BOOKMARK [0][-]{chapter.8}{Exponentiation}{}
|
\BOOKMARK [2][-]{subsection.8.2.1}{Single Digit Addition and Subtraction}{section.8.2}
|
||||||
\BOOKMARK [1][-]{section.8.1}{Exponentiation Basics}{chapter.8}
|
\BOOKMARK [2][-]{subsection.8.2.2}{Single Digit Multiplication}{section.8.2}
|
||||||
\BOOKMARK [2][-]{subsection.8.1.1}{Single Digit Exponentiation}{section.8.1}
|
\BOOKMARK [2][-]{subsection.8.2.3}{Single Digit Division}{section.8.2}
|
||||||
\BOOKMARK [1][-]{section.8.2}{k-ary Exponentiation}{chapter.8}
|
\BOOKMARK [2][-]{subsection.8.2.4}{Single Digit Root Extraction}{section.8.2}
|
||||||
\BOOKMARK [2][-]{subsection.8.2.1}{Optimal Values of k}{section.8.2}
|
\BOOKMARK [1][-]{section.8.3}{Random Number Generation}{chapter.8}
|
||||||
\BOOKMARK [2][-]{subsection.8.2.2}{Sliding-Window Exponentiation}{section.8.2}
|
\BOOKMARK [1][-]{section.8.4}{Formatted Representations}{chapter.8}
|
||||||
\BOOKMARK [1][-]{section.8.3}{Modular Exponentiation}{chapter.8}
|
\BOOKMARK [2][-]{subsection.8.4.1}{Reading Radix-n Input}{section.8.4}
|
||||||
\BOOKMARK [2][-]{subsection.8.3.1}{Barrett Modular Exponentiation}{section.8.3}
|
\BOOKMARK [2][-]{subsection.8.4.2}{Generating Radix-n Output}{section.8.4}
|
||||||
\BOOKMARK [1][-]{section.8.4}{Quick Power of Two}{chapter.8}
|
\BOOKMARK [0][-]{chapter.9}{Number Theoretic Algorithms}{}
|
||||||
\BOOKMARK [0][-]{chapter.9}{Higher Level Algorithms}{}
|
\BOOKMARK [1][-]{section.9.1}{Greatest Common Divisor}{chapter.9}
|
||||||
\BOOKMARK [1][-]{section.9.1}{Integer Division with Remainder}{chapter.9}
|
\BOOKMARK [2][-]{subsection.9.1.1}{Complete Greatest Common Divisor}{section.9.1}
|
||||||
\BOOKMARK [2][-]{subsection.9.1.1}{Quotient Estimation}{section.9.1}
|
\BOOKMARK [1][-]{section.9.2}{Least Common Multiple}{chapter.9}
|
||||||
\BOOKMARK [2][-]{subsection.9.1.2}{Normalized Integers}{section.9.1}
|
\BOOKMARK [1][-]{section.9.3}{Jacobi Symbol Computation}{chapter.9}
|
||||||
\BOOKMARK [2][-]{subsection.9.1.3}{Radix- Division with Remainder}{section.9.1}
|
\BOOKMARK [2][-]{subsection.9.3.1}{Jacobi Symbol}{section.9.3}
|
||||||
\BOOKMARK [1][-]{section.9.2}{Single Digit Helpers}{chapter.9}
|
\BOOKMARK [1][-]{section.9.4}{Modular Inverse}{chapter.9}
|
||||||
\BOOKMARK [2][-]{subsection.9.2.1}{Single Digit Addition and Subtraction}{section.9.2}
|
\BOOKMARK [2][-]{subsection.9.4.1}{General Case}{section.9.4}
|
||||||
\BOOKMARK [2][-]{subsection.9.2.2}{Single Digit Multiplication}{section.9.2}
|
\BOOKMARK [1][-]{section.9.5}{Primality Tests}{chapter.9}
|
||||||
\BOOKMARK [2][-]{subsection.9.2.3}{Single Digit Division}{section.9.2}
|
\BOOKMARK [2][-]{subsection.9.5.1}{Trial Division}{section.9.5}
|
||||||
\BOOKMARK [2][-]{subsection.9.2.4}{Single Digit Root Extraction}{section.9.2}
|
\BOOKMARK [2][-]{subsection.9.5.2}{The Fermat Test}{section.9.5}
|
||||||
\BOOKMARK [1][-]{section.9.3}{Random Number Generation}{chapter.9}
|
\BOOKMARK [2][-]{subsection.9.5.3}{The Miller-Rabin Test}{section.9.5}
|
||||||
\BOOKMARK [1][-]{section.9.4}{Formatted Representations}{chapter.9}
|
|
||||||
\BOOKMARK [2][-]{subsection.9.4.1}{Reading Radix-n Input}{section.9.4}
|
|
||||||
\BOOKMARK [2][-]{subsection.9.4.2}{Generating Radix-n Output}{section.9.4}
|
|
||||||
\BOOKMARK [0][-]{chapter.10}{Number Theoretic Algorithms}{}
|
|
||||||
\BOOKMARK [1][-]{section.10.1}{Greatest Common Divisor}{chapter.10}
|
|
||||||
\BOOKMARK [2][-]{subsection.10.1.1}{Complete Greatest Common Divisor}{section.10.1}
|
|
||||||
\BOOKMARK [1][-]{section.10.2}{Least Common Multiple}{chapter.10}
|
|
||||||
\BOOKMARK [1][-]{section.10.3}{Jacobi Symbol Computation}{chapter.10}
|
|
||||||
\BOOKMARK [2][-]{subsection.10.3.1}{Jacobi Symbol}{section.10.3}
|
|
||||||
\BOOKMARK [1][-]{section.10.4}{Modular Inverse}{chapter.10}
|
|
||||||
\BOOKMARK [2][-]{subsection.10.4.1}{General Case}{section.10.4}
|
|
||||||
\BOOKMARK [1][-]{section.10.5}{Primality Tests}{chapter.10}
|
|
||||||
\BOOKMARK [2][-]{subsection.10.5.1}{Trial Division}{section.10.5}
|
|
||||||
\BOOKMARK [2][-]{subsection.10.5.2}{The Fermat Test}{section.10.5}
|
|
||||||
\BOOKMARK [2][-]{subsection.10.5.3}{The Miller-Rabin Test}{section.10.5}
|
|
||||||
|
24275
tommath.pdf
24275
tommath.pdf
File diff suppressed because one or more lines are too long
192
tommath.src
192
tommath.src
@ -201,12 +201,27 @@ Greg Rose, Sydney, Australia, June 2003.
|
|||||||
\pagestyle{headings}
|
\pagestyle{headings}
|
||||||
\chapter{Introduction}
|
\chapter{Introduction}
|
||||||
\section{Multiple Precision Arithmetic}
|
\section{Multiple Precision Arithmetic}
|
||||||
|
|
||||||
|
\subsection{What is Multiple Precision Arithmetic?}
|
||||||
|
When we think of long-hand arithmetic such as addition or multiplication we rarely consider the fact that we instinctively
|
||||||
|
raise or lower the precision of the numbers we are dealing with. For example, in decimal we almost immediate can
|
||||||
|
reason that $7$ times $6$ is $42$. However, $42$ has two digits of precision as opposed to one digit we started with.
|
||||||
|
Further multiplications of say $3$ result in a larger precision result $126$. In these few examples we have multiple
|
||||||
|
precisions for the numbers we are working with. Despite the various levels of precision a single subset\footnote{With the occasional optimization.}
|
||||||
|
of algorithms can be designed to accomodate them.
|
||||||
|
|
||||||
|
By way of comparison a fixed or single precision operation would lose precision on various operations. For example, in
|
||||||
|
the decimal system with fixed precision $6 \cdot 7 = 2$.
|
||||||
|
|
||||||
|
Essentially at the heart of computer based multiple precision arithmetic are the same long-hand algorithms taught in
|
||||||
|
schools to manually add, subtract, multiply and divide.
|
||||||
|
|
||||||
\subsection{The Need for Multiple Precision Arithmetic}
|
\subsection{The Need for Multiple Precision Arithmetic}
|
||||||
The most prevalent need for multiple precision arithmetic, often referred to as ``bignum'' math, is within the implementation
|
The most prevalent need for multiple precision arithmetic, often referred to as ``bignum'' math, is within the implementation
|
||||||
of public-key cryptography algorithms. Algorithms such as RSA \cite{RSAREF} and Diffie-Hellman \cite{DHREF} require
|
of public-key cryptography algorithms. Algorithms such as RSA \cite{RSAREF} and Diffie-Hellman \cite{DHREF} require
|
||||||
integers of significant magnitude to resist known cryptanalytic attacks. For example, at the time of this writing a
|
integers of significant magnitude to resist known cryptanalytic attacks. For example, at the time of this writing a
|
||||||
typical RSA modulus would be at greater than $10^{309}$. However, modern programming languages such as ISO C \ref{ISOC} and
|
typical RSA modulus would be at least greater than $10^{309}$. However, modern programming languages such as ISO C \cite{ISOC} and
|
||||||
Java \ref{JAVA} only provide instrinsic support for integers which are relatively small and are single precision.
|
Java \cite{JAVA} only provide instrinsic support for integers which are relatively small and single precision.
|
||||||
|
|
||||||
\begin{figure}[!here]
|
\begin{figure}[!here]
|
||||||
\begin{center}
|
\begin{center}
|
||||||
@ -227,9 +242,9 @@ The largest data type guaranteed to be provided by the ISO C programming
|
|||||||
language\footnote{As per the ISO C standard. However, each compiler vendor is allowed to augment the precision as they
|
language\footnote{As per the ISO C standard. However, each compiler vendor is allowed to augment the precision as they
|
||||||
see fit.} can only represent values up to $10^{19}$ as shown in figure \ref{fig:ISOC}. On its own the C language is
|
see fit.} can only represent values up to $10^{19}$ as shown in figure \ref{fig:ISOC}. On its own the C language is
|
||||||
insufficient to accomodate the magnitude required for the problem at hand. An RSA modulus of magnitude $10^{19}$ could be
|
insufficient to accomodate the magnitude required for the problem at hand. An RSA modulus of magnitude $10^{19}$ could be
|
||||||
trivially factored on the average desktop computer, rendering any protocol based on the algorithm insecure. Multiple
|
trivially factored\footnote{A Pollard-Rho factoring would take only $2^{16}$ time.} on the average desktop computer,
|
||||||
precision algorithms solve this very problem by extending the range of representable integers while using single precision
|
rendering any protocol based on the algorithm insecure. Multiple precision algorithms solve this very problem by
|
||||||
data types.
|
extending the range of representable integers while using single precision data types.
|
||||||
|
|
||||||
Most advancements in fast multiple precision arithmetic stem from the need for faster and more efficient cryptographic
|
Most advancements in fast multiple precision arithmetic stem from the need for faster and more efficient cryptographic
|
||||||
primitives. Faster modular reduction and exponentiation algorithms such as Barrett's algorithm, which have appeared in
|
primitives. Faster modular reduction and exponentiation algorithms such as Barrett's algorithm, which have appeared in
|
||||||
@ -246,27 +261,16 @@ floating point is meant to be implemented in hardware the precision of the manti
|
|||||||
a mantissa of much larger precision than hardware alone can efficiently support. This approach could be useful where
|
a mantissa of much larger precision than hardware alone can efficiently support. This approach could be useful where
|
||||||
scientific applications must minimize the total output error over long calculations.
|
scientific applications must minimize the total output error over long calculations.
|
||||||
|
|
||||||
\subsection{What is Multiple Precision Arithmetic?}
|
Another use for large integers is within arithmetic on polynomials of large characteristic (i.e. $GF(p)[x]$ for large $p$).
|
||||||
At the heart of all multiple precision integer operations are the ``long-hand'' algorithms taught to children in grade
|
In fact the library discussed within this text has already been used to form a polynomial basis library\footnote{See \url{http://poly.libtomcrypt.org} for more details.}.
|
||||||
school. For example, to multiply $1,234$ by $981$ the student is not taught to memorize the times table for
|
|
||||||
$1,234$. Instead, they are taught how to long-multiply one digit at a time. That is to multiply each column using
|
|
||||||
simple single digit multiplications, line up the partial results, and add the resulting products by column. The
|
|
||||||
representation that most are familiar with is known as decimal or more formally as radix-10. A radix-$n$ representation
|
|
||||||
simply means there are $n$ possible values per digit. For example, binary would be a radix-2 representation.
|
|
||||||
|
|
||||||
In essence computer based multiple precision arithmetic is very much the same. In most cases the same algorithms
|
|
||||||
which seem instinctive are the basis of computer based algorithms. The most notable difference is the usage
|
|
||||||
of a binary friendly radix, that is, to use a radix of the form $2^k$ where $k$ is typically the size of a computer
|
|
||||||
machine register\footnote{For example, with an x86 based processor $k$ could be $32$ while on an Alpha it would likely
|
|
||||||
be $64$.}.
|
|
||||||
|
|
||||||
\subsection{Benefits of Multiple Precision Arithmetic}
|
\subsection{Benefits of Multiple Precision Arithmetic}
|
||||||
\index{precision}
|
\index{precision}
|
||||||
The benefit of multiple precision representations over single or fixed precision representations is that
|
The benefit of multiple precision representations over single or fixed precision representations is that
|
||||||
often no precision is lost while representing the result of an operation which requires excess precision. For example,
|
no precision is lost while representing the result of an operation which requires excess precision. For example,
|
||||||
the product of two $n$-bit integers requires at least $2n$ bits of resolution to be precisely represented.
|
the product of two $n$-bit integers requires at least $2n$ bits of precision to be represented faithfully. A multiple
|
||||||
A multiple precision algorithm would augment the precision of the destination to accomodate the result while a single
|
precision algorithm would augment the precision of the destination to accomodate the result while a single precision system
|
||||||
precision system would truncate excess bits to maintain a fixed level of precision.
|
would truncate excess bits to maintain a fixed level of precision.
|
||||||
|
|
||||||
It is possible to implement algorithms which require large integers with fixed precision algorithms. For example, elliptic
|
It is possible to implement algorithms which require large integers with fixed precision algorithms. For example, elliptic
|
||||||
curve cryptography (\textit{ECC}) is often implemented on smartcards by fixing the precision of the integers to the maximum
|
curve cryptography (\textit{ECC}) is often implemented on smartcards by fixing the precision of the integers to the maximum
|
||||||
@ -279,11 +283,12 @@ Multiple precision algorithms have the most overhead of any style of arithmetic.
|
|||||||
overhead can be kept to a minimum with careful planning, but overall, it is not well suited for most memory starved
|
overhead can be kept to a minimum with careful planning, but overall, it is not well suited for most memory starved
|
||||||
platforms. However, multiple precision algorithms do offer the most flexibility in terms of the magnitude of the
|
platforms. However, multiple precision algorithms do offer the most flexibility in terms of the magnitude of the
|
||||||
inputs. That is, the same algorithms based on multiple precision integers can accomodate any reasonable size input
|
inputs. That is, the same algorithms based on multiple precision integers can accomodate any reasonable size input
|
||||||
without the designer's explicit forethought.
|
without the designer's explicit forethought. This leads to lower cost of ownership for the code as it only has to
|
||||||
|
be written and tested once.
|
||||||
|
|
||||||
\section{Purpose of This Text}
|
\section{Purpose of This Text}
|
||||||
The purpose of this text is to instruct the reader regarding how to implement multiple precision algorithms. That is
|
The purpose of this text is to instruct the reader regarding how to implement efficient multiple precision algorithms.
|
||||||
to not only explain a limited subset of the core theory behind the algorithms but also the various ``house keeping''
|
That is to not only explain a limited subset of the core theory behind the algorithms but also the various ``house keeping''
|
||||||
elements that are neglected by authors of other texts on the subject. Several well reknowned texts \cite{TAOCPV2,HAC}
|
elements that are neglected by authors of other texts on the subject. Several well reknowned texts \cite{TAOCPV2,HAC}
|
||||||
give considerably detailed explanations of the theoretical aspects of algorithms and often very little information
|
give considerably detailed explanations of the theoretical aspects of algorithms and often very little information
|
||||||
regarding the practical implementation aspects.
|
regarding the practical implementation aspects.
|
||||||
@ -309,6 +314,9 @@ The algorithms that are presented will always include at least one ``pseudo-code
|
|||||||
by the actual C source code that implements the algorithm. The pseudo-code can be used to implement the same
|
by the actual C source code that implements the algorithm. The pseudo-code can be used to implement the same
|
||||||
algorithm in other programming languages as the reader sees fit.
|
algorithm in other programming languages as the reader sees fit.
|
||||||
|
|
||||||
|
This text shall also serve as a walkthrough of the creation of multiple precision algorithms from scratch. Showing
|
||||||
|
the reader how the algorithms fit together as well as where to start on various taskings.
|
||||||
|
|
||||||
\section{Discussion and Notation}
|
\section{Discussion and Notation}
|
||||||
\subsection{Notation}
|
\subsection{Notation}
|
||||||
A multiple precision integer of $n$-digits shall be denoted as $x = (x_{n-1} ... x_1 x_0)_{ \beta }$ and represent
|
A multiple precision integer of $n$-digits shall be denoted as $x = (x_{n-1} ... x_1 x_0)_{ \beta }$ and represent
|
||||||
@ -368,41 +376,36 @@ The $\lfloor \mbox{ } \rfloor$ brackets imply an expression truncated to an inte
|
|||||||
itself. For example, $\lfloor 5.7 \rfloor = 5$. Similarly the $\lceil \mbox{ } \rceil$ brackets imply an expression
|
itself. For example, $\lfloor 5.7 \rfloor = 5$. Similarly the $\lceil \mbox{ } \rceil$ brackets imply an expression
|
||||||
rounded to an integer not less than the expression itself. For example, $\lceil 5.1 \rceil = 6$. Typically when
|
rounded to an integer not less than the expression itself. For example, $\lceil 5.1 \rceil = 6$. Typically when
|
||||||
the $/$ division symbol is used the intention is to perform an integer division with truncation. For example,
|
the $/$ division symbol is used the intention is to perform an integer division with truncation. For example,
|
||||||
$5/2 = 2$ which will often be written as $\lfloor 5/2 \rfloor = 2$ for clarity. When a value is presented as a
|
$5/2 = 2$ which will often be written as $\lfloor 5/2 \rfloor = 2$ for clarity. When an expression is written as a
|
||||||
fraction such as $5 \over 2$ a real value division is implied.
|
fraction a real value division is implied, for example ${5 \over 2} = 2.5$.
|
||||||
|
|
||||||
The norm of a multiple precision integer, for example, $\vert \vert x \vert \vert$ will be used to represent the number of digits in the representation
|
The norm of a multiple precision integer, for example, $\vert \vert x \vert \vert$ will be used to represent the number of digits in the representation
|
||||||
of the integer. For example, $\vert \vert 123 \vert \vert = 3$.
|
of the integer. For example, $\vert \vert 123 \vert \vert = 3$ and $\vert \vert 79452 \vert \vert = 5$.
|
||||||
|
|
||||||
\subsection{Work Effort}
|
\subsection{Work Effort}
|
||||||
\index{big-O}
|
\index{big-Oh}
|
||||||
To measure the efficiency of the specified algorithms, a modified big-O notation is used. In this system all
|
To measure the efficiency of the specified algorithms, a modified big-Oh notation is used. In this system all
|
||||||
single precision operations are considered to have the same cost\footnote{Except where explicitly noted.}.
|
single precision operations are considered to have the same cost\footnote{Except where explicitly noted.}.
|
||||||
That is a single precision addition, multiplication and division are assumed to take the same time to
|
That is a single precision addition, multiplication and division are assumed to take the same time to
|
||||||
complete. While this is generally not true in practice, it will simplify the discussions considerably.
|
complete. While this is generally not true in practice, it will simplify the discussions considerably.
|
||||||
|
|
||||||
Some algorithms have slight advantages over others which is why some constants will not be removed in
|
Some algorithms have slight advantages over others which is why some constants will not be removed in
|
||||||
the notation. For example, a normal multiplication requires $O(n^2)$ work while a squaring requires
|
the notation. For example, a normal baseline multiplication (section \ref{sec:basemult}) requires $O(n^2)$ work while a
|
||||||
$O({{n^2 + n}\over 2})$ work. In standard big-O notation these would both be said to be equivalent to $O(n^2)$. However,
|
baseline squaring (section \ref{sec:basesquare}) requires $O({{n^2 + n}\over 2})$ work. In standard big-Oh notation these
|
||||||
|
would both be said to be equivalent to $O(n^2)$. However,
|
||||||
in the context of the this text this is not the case as the magnitude of the inputs will typically be rather small. As a
|
in the context of the this text this is not the case as the magnitude of the inputs will typically be rather small. As a
|
||||||
result small constant factors in the work effort will make an observable difference in algorithm efficiency.
|
result small constant factors in the work effort will make an observable difference in algorithm efficiency.
|
||||||
|
|
||||||
Throughout the discussions various ``work levels'' will be discussed. The term work level shall refer to
|
All of the algorithms presented in this text have a polynomial time work level. That is, of the form
|
||||||
the complexity of an algorithm with respect to its time requirements. For example,
|
$O(n^k)$ for $n, k \in \Z^{+}$. This will help make useful comparisons in terms of the speed of the algorithms and how
|
||||||
$O(1)$, $O(n)$, $O(n^2)$, ..., $O(n^k)$ are various possible work levels that will be of concern in this text. Any
|
various optimizations will help pay off in the long run.
|
||||||
sequence of operations said to be at the $O(n^k)$ work level will often be nested $k-$deep within loops and are performed
|
|
||||||
$n^k$ times.
|
|
||||||
|
|
||||||
Operations which are deeply nested within algorithms will have a higher big-O rating and be the target of the most
|
|
||||||
optimizatons. For example, in integer multiplication, by moving the carry propagation from the innermost
|
|
||||||
$O(n^2)$ nesting to the $O(n)$ nesting level the algorithm becomes vastly more
|
|
||||||
efficient\footnote{This is known as Comba multiplication.}.
|
|
||||||
|
|
||||||
\section{Exercises}
|
\section{Exercises}
|
||||||
Within the more advanced chapters a section will be set aside to give the reader some challenging exercises. These
|
Within the more advanced chapters a section will be set aside to give the reader some challenging exercises related to
|
||||||
exercises are not designed to be prize winning problems, but instead to be thought provoking. Wherever possible the
|
the discussion at hand. These exercises are not designed to be prize winning problems, but instead to be thought
|
||||||
problems are forward minded, stating problems that will be answered in subsequent chapters. The reader is encouraged to
|
provoking. Wherever possible the problems are forward minded, stating problems that will be answered in subsequent
|
||||||
finish the exercises as they appear to get a better understanding of the subject material.
|
chapters. The reader is encouraged to finish the exercises as they appear to get a better understanding of the
|
||||||
|
subject material.
|
||||||
|
|
||||||
That being said, the problems are designed to affirm knowledge of a particular subject matter. Students in particular
|
That being said, the problems are designed to affirm knowledge of a particular subject matter. Students in particular
|
||||||
are encouraged to verify they can answer the problems correctly before moving on.
|
are encouraged to verify they can answer the problems correctly before moving on.
|
||||||
@ -410,52 +413,60 @@ are encouraged to verify they can answer the problems correctly before moving on
|
|||||||
Similar to the exercises of \cite[pp. ix]{TAOCPV2} these exercises are given a scoring system based on the difficulty of
|
Similar to the exercises of \cite[pp. ix]{TAOCPV2} these exercises are given a scoring system based on the difficulty of
|
||||||
the problem. However, unlike \cite{TAOCPV2} the problems do not get nearly as hard. The scoring of these
|
the problem. However, unlike \cite{TAOCPV2} the problems do not get nearly as hard. The scoring of these
|
||||||
exercises ranges from one (the easiest) to five (the hardest). The following table sumarizes the
|
exercises ranges from one (the easiest) to five (the hardest). The following table sumarizes the
|
||||||
scoring.
|
scoring system used.
|
||||||
|
|
||||||
\begin{tabular}{cl}
|
\begin{figure}[here]
|
||||||
$\left [ 1 \right ]$ & An easy problem that should only take the reader a manner of \\
|
\begin{center}
|
||||||
|
\begin{small}
|
||||||
|
\begin{tabular}{|c|l|}
|
||||||
|
\hline $\left [ 1 \right ]$ & An easy problem that should only take the reader a manner of \\
|
||||||
& minutes to solve. Usually does not involve much computer time \\
|
& minutes to solve. Usually does not involve much computer time \\
|
||||||
& to solve. \\
|
& to solve. \\
|
||||||
& \\
|
\hline $\left [ 2 \right ]$ & An easy problem that involves a marginal amount of computer \\
|
||||||
$\left [ 2 \right ]$ & An easy problem that involves a marginal amount of computer \\
|
|
||||||
& time usage. Usually requires a program to be written to \\
|
& time usage. Usually requires a program to be written to \\
|
||||||
& solve the problem. \\
|
& solve the problem. \\
|
||||||
& \\
|
\hline $\left [ 3 \right ]$ & A moderately hard problem that requires a non-trivial amount \\
|
||||||
$\left [ 3 \right ]$ & A moderately hard problem that requires a non-trivial amount \\
|
|
||||||
& of work. Usually involves trivial research and development of \\
|
& of work. Usually involves trivial research and development of \\
|
||||||
& new theory from the perspective of a student. \\
|
& new theory from the perspective of a student. \\
|
||||||
& \\
|
\hline $\left [ 4 \right ]$ & A moderately hard problem that involves a non-trivial amount \\
|
||||||
$\left [ 4 \right ]$ & A moderately hard problem that involves a non-trivial amount \\
|
|
||||||
& of work and research, the solution to which will demonstrate \\
|
& of work and research, the solution to which will demonstrate \\
|
||||||
& a higher mastery of the subject matter. \\
|
& a higher mastery of the subject matter. \\
|
||||||
& \\
|
\hline $\left [ 5 \right ]$ & A hard problem that involves concepts that are difficult for a \\
|
||||||
$\left [ 5 \right ]$ & A hard problem that involves concepts that are difficult for a \\
|
|
||||||
& novice to solve. Solutions to these problems will demonstrate a \\
|
& novice to solve. Solutions to these problems will demonstrate a \\
|
||||||
& complete mastery of the given subject. \\
|
& complete mastery of the given subject. \\
|
||||||
& \\
|
\hline
|
||||||
\end{tabular}
|
\end{tabular}
|
||||||
|
\end{small}
|
||||||
|
\end{center}
|
||||||
|
\caption{Exercise Scoring System}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
Essentially problems at the first level are meant to be simple questions that the reader can answer quickly without programming a solution or
|
Problems at the first level are meant to be simple questions that the reader can answer quickly without programming a solution or
|
||||||
devising new theory. These problems are quick tests to see if the material is understood. Problems at the second level are also
|
devising new theory. These problems are quick tests to see if the material is understood. Problems at the second level
|
||||||
designed to be easy but will require a program or algorithm to be implemented to arrive at the answer.
|
are also designed to be easy but will require a program or algorithm to be implemented to arrive at the answer. These
|
||||||
|
two levels are essentially entry level questions.
|
||||||
|
|
||||||
Problems at the third level are meant to be a bit more difficult. Often the answer is fairly obvious but arriving at an exacting solution
|
Problems at the third level are meant to be a bit more difficult than the first two levels. The answer is often
|
||||||
requires some thought and skill. These problems will almost always involve devising a new algorithm or implementing a variation of
|
fairly obvious but arriving at an exacting solution requires some thought and skill. These problems will almost always
|
||||||
another algorithm.
|
involve devising a new algorithm or implementing a variation of another algorithm previously presented. Readers who can
|
||||||
|
answer these questions will feel comfortable with the concepts behind the topic at hand.
|
||||||
|
|
||||||
Problems at the fourth level are meant to be even more difficult as well as involve some research. The reader will most
|
Problems at the fourth level are meant to be similar to those of the level three questions except they will require
|
||||||
likely not know the answer right away, nor will the text provide the exact details of the answer until a subsequent
|
additional research to be completed. The reader will most likely not know the answer right away, nor will the text provide
|
||||||
chapter. Problems at the fifth level are meant to be the hardest problems relative to all the other problems in the
|
the exact details of the answer until a subsequent chapter.
|
||||||
chapter. People who can correctly answer fifth level problems have a mastery of the subject matter at hand.
|
|
||||||
|
Problems at the fifth level are meant to be the hardest
|
||||||
|
problems relative to all the other problems in the chapter. People who can correctly answer fifth level problems have a
|
||||||
|
mastery of the subject matter at hand.
|
||||||
|
|
||||||
Often problems will be tied together. The purpose of this is to start a chain of thought that will be discussed in future chapters. The reader
|
Often problems will be tied together. The purpose of this is to start a chain of thought that will be discussed in future chapters. The reader
|
||||||
is encouraged to answer the follow-up problems and try to draw the relevance of problems.
|
is encouraged to answer the follow-up problems and try to draw the relevance of problems.
|
||||||
|
|
||||||
\chapter{Introduction to LibTomMath}
|
\section{Introduction to LibTomMath}
|
||||||
|
|
||||||
\section{What is LibTomMath?}
|
\subsection{What is LibTomMath?}
|
||||||
LibTomMath is a free and open source multiple precision library written in portable ISO C. By portable it is
|
LibTomMath is a free and open source multiple precision integer library written entirely in portable ISO C. By portable it
|
||||||
meant that the library does not contain any code that is computer platform dependent or otherwise problematic to use on
|
is meant that the library does not contain any code that is computer platform dependent or otherwise problematic to use on
|
||||||
any given platform.
|
any given platform.
|
||||||
|
|
||||||
The library has been successfully tested under numerous operating systems including Unix\footnote{All of these
|
The library has been successfully tested under numerous operating systems including Unix\footnote{All of these
|
||||||
@ -463,7 +474,7 @@ trademarks belong to their respective rightful owners.}, MacOS, Windows, Linux,
|
|||||||
as the Gameboy Advance. The library is designed to contain enough functionality to be able to develop applications such
|
as the Gameboy Advance. The library is designed to contain enough functionality to be able to develop applications such
|
||||||
as public key cryptosystems and still maintain a relatively small footprint.
|
as public key cryptosystems and still maintain a relatively small footprint.
|
||||||
|
|
||||||
\section{Goals of LibTomMath}
|
\subsection{Goals of LibTomMath}
|
||||||
|
|
||||||
Libraries which obtain the most efficiency are rarely written in a high level programming language such as C. However,
|
Libraries which obtain the most efficiency are rarely written in a high level programming language such as C. However,
|
||||||
even though this library is written entirely in ISO C, considerable care has been taken to optimize the algorithm implementations within the
|
even though this library is written entirely in ISO C, considerable care has been taken to optimize the algorithm implementations within the
|
||||||
@ -479,13 +490,13 @@ based on the magnitude of the inputs and the configuration of the library.
|
|||||||
|
|
||||||
Making LibTomMath as efficient as possible is not the only goal of the LibTomMath project. Ideally the library should
|
Making LibTomMath as efficient as possible is not the only goal of the LibTomMath project. Ideally the library should
|
||||||
be source compatible with another popular library which makes it more attractive for developers to use. In this case the
|
be source compatible with another popular library which makes it more attractive for developers to use. In this case the
|
||||||
MPI library was used as a API template for all the basic functions. MPI was chosen as the template because it is
|
MPI library was used as a API template for all the basic functions. MPI was chosen because it is another library that fits
|
||||||
another library that fits in the same niche as LibTomMath. Even though LibTomMath uses MPI as the template for the
|
in the same niche as LibTomMath. Even though LibTomMath uses MPI as the template for the function names and argument
|
||||||
function names and argument passing conventions, LibTomMath has been written from scratch by Tom St Denis.
|
passing conventions, it has been written from scratch by Tom St Denis.
|
||||||
|
|
||||||
The project is also meant to act as a learning tool for students, the logic being that no easy-to-follow ``bignum''
|
The project is also meant to act as a learning tool for students, the logic being that no easy-to-follow ``bignum''
|
||||||
library exists which can be used to teach computer science students how to perform fast and reliable multiple precision
|
library exists which can be used to teach computer science students how to perform fast and reliable multiple precision
|
||||||
arithmetic. To this end the source code has been given quite a few comments and algorithm discussion points.
|
integer arithmetic. To this end the source code has been given quite a few comments and algorithm discussion points.
|
||||||
|
|
||||||
\section{Choice of LibTomMath}
|
\section{Choice of LibTomMath}
|
||||||
LibTomMath was chosen as the case study of this text not only because the author of both projects is one and the same but
|
LibTomMath was chosen as the case study of this text not only because the author of both projects is one and the same but
|
||||||
@ -500,15 +511,13 @@ developer can more readily discern the true intent of a given section of source
|
|||||||
what conditional code will be used.
|
what conditional code will be used.
|
||||||
|
|
||||||
The code base of LibTomMath is also well organized. Each function is in its own separate source code file
|
The code base of LibTomMath is also well organized. Each function is in its own separate source code file
|
||||||
which allows the reader to find a given function very quickly. When compiled with GCC for the x86 processor the entire
|
which allows the reader to find a given function very quickly. On average there are about $76$ lines of code per source
|
||||||
library is a mere 87,760 bytes ($116,182$ bytes for ARMv4 processors). This includes every single function
|
file which makes the source very easily to follow. By comparison MPI and LIP are single file projects making code tracing
|
||||||
LibTomMath provides from basic arithmetic to various number theoretic functions such as modular exponentiation, various
|
very hard. GMP has many conditional code segments which also hinder tracing.
|
||||||
reduction algorithms and Jacobi symbol computation.
|
|
||||||
|
|
||||||
By comparison MPI, which has fewer functions than LibTomMath, compiled with the same conditions occupied 45,429 bytes
|
When compiled with GCC for the x86 processor and optimized for speed the entire library is approximately $66$KiB\footnote{The notation ``KiB'' means $2^{10}$ octets, similarly ``MiB'' means $2^{20}$ octets.}
|
||||||
($54,536$ for ARMv4). GMP which has a rather large collection of functions with the default configuration on an
|
which is fairly small compared to GMP (over $250$KiB). LibTomMath is slightly larger than MPI (which compiles to about
|
||||||
x86 Athlon is 2,950,688 bytes. Note that while LibTomMath has fewer functions than GMP it has been used as the sole basis
|
$50$KiB) but LibTomMath is also much faster and more complete than MPI.
|
||||||
for several public key cryptosystems without having to seek additional outside functions to supplement the library.
|
|
||||||
|
|
||||||
\subsection{API Simplicity}
|
\subsection{API Simplicity}
|
||||||
LibTomMath is designed after the MPI library and shares the API design. Quite often programs that use MPI will build
|
LibTomMath is designed after the MPI library and shares the API design. Quite often programs that use MPI will build
|
||||||
@ -519,6 +528,11 @@ which is an extremely valuable benefit for the student and developer alike.
|
|||||||
The LIP library is an example of a library with an API that is awkward to work with. LIP uses function names that are often ``compressed'' to
|
The LIP library is an example of a library with an API that is awkward to work with. LIP uses function names that are often ``compressed'' to
|
||||||
illegible short hand. LibTomMath does not share this characteristic.
|
illegible short hand. LibTomMath does not share this characteristic.
|
||||||
|
|
||||||
|
The GMP library also does not return error codes. Instead it uses a POSIX.1 \cite{POSIX1} signal system where errors
|
||||||
|
are signaled to the host application. This happens to be the fastest approach but definitely not the most versatile. In
|
||||||
|
effect a math error (i.e. invalid input, heap error, etc) can cause a program to stop functioning which is definitely
|
||||||
|
undersireable in many situations.
|
||||||
|
|
||||||
\subsection{Optimizations}
|
\subsection{Optimizations}
|
||||||
While LibTomMath is certainly not the fastest library (GMP often beats LibTomMath by a factor of two) it does
|
While LibTomMath is certainly not the fastest library (GMP often beats LibTomMath by a factor of two) it does
|
||||||
feature a set of optimal algorithms for tasks such as modular reduction, exponentiation, multiplication and squaring. GMP
|
feature a set of optimal algorithms for tasks such as modular reduction, exponentiation, multiplication and squaring. GMP
|
||||||
@ -2320,6 +2334,7 @@ This technique led to the discovery of polynomial basis algorithms (\textit{good
|
|||||||
|
|
||||||
\section{Multiplication}
|
\section{Multiplication}
|
||||||
\subsection{The Baseline Multiplication}
|
\subsection{The Baseline Multiplication}
|
||||||
|
\label{sec:basemult}
|
||||||
\index{baseline multiplication}
|
\index{baseline multiplication}
|
||||||
Computing the product of two integers in software can be achieved using a trivial adaptation of the standard $O(n^2)$ long-hand multiplication
|
Computing the product of two integers in software can be achieved using a trivial adaptation of the standard $O(n^2)$ long-hand multiplication
|
||||||
algorithm that school children are taught. The algorithm is considered an $O(n^2)$ algorithm since for two $n$-digit inputs $n^2$ single precision
|
algorithm that school children are taught. The algorithm is considered an $O(n^2)$ algorithm since for two $n$-digit inputs $n^2$ single precision
|
||||||
@ -2985,6 +3000,7 @@ The implementation is rather simplistic and is not particularly noteworthy. Lin
|
|||||||
operator from the C programming language. Line @37,<<@ computes $\delta$ using the fact that $1 << k$ is equal to $2^k$.
|
operator from the C programming language. Line @37,<<@ computes $\delta$ using the fact that $1 << k$ is equal to $2^k$.
|
||||||
|
|
||||||
\section{Squaring}
|
\section{Squaring}
|
||||||
|
\label{sec:basesquare}
|
||||||
|
|
||||||
Squaring is a special case of multiplication where both multiplicands are equal. At first it may seem like there is no significant optimization
|
Squaring is a special case of multiplication where both multiplicands are equal. At first it may seem like there is no significant optimization
|
||||||
available but in fact there is. Consider the multiplication of $576$ against $241$. In total there will be nine single precision multiplications
|
available but in fact there is. Consider the multiplication of $576$ against $241$. In total there will be nine single precision multiplications
|
||||||
@ -6261,6 +6277,12 @@ OpenSSL Cryptographic Toolkit, \url{http://openssl.org}
|
|||||||
\bibitem[17]{LIP}
|
\bibitem[17]{LIP}
|
||||||
Large Integer Package, \url{http://home.hetnet.nl/~ecstr/LIP.zip}
|
Large Integer Package, \url{http://home.hetnet.nl/~ecstr/LIP.zip}
|
||||||
|
|
||||||
|
\bibitem[18]{ISOC}
|
||||||
|
JTC1/SC22/WG14, ISO/IEC 9899:1999, ``A draft rationale for the C99 standard.''
|
||||||
|
|
||||||
|
\bibitem[19]{JAVA}
|
||||||
|
The Sun Java Website, \url{http://java.sun.com/}
|
||||||
|
|
||||||
\end{thebibliography}
|
\end{thebibliography}
|
||||||
|
|
||||||
\input{tommath.ind}
|
\input{tommath.ind}
|
||||||
|
1038
tommath.tex
1038
tommath.tex
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user