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).
|
||||
Scanning input file bn.idx....done (53 entries accepted, 0 rejected).
|
||||
Sorting entries....done (317 comparisons).
|
||||
Generating output file bn.ind....done (56 lines written, 0 warnings).
|
||||
Scanning input file bn.idx....done (57 entries accepted, 0 rejected).
|
||||
Sorting entries....done (342 comparisons).
|
||||
Generating output file bn.ind....done (60 lines written, 0 warnings).
|
||||
Output written in bn.ind.
|
||||
Transcript written in bn.ilg.
|
||||
|
6
bn.ind
6
bn.ind
@ -14,6 +14,7 @@
|
||||
\item mp\_error\_to\_string, \hyperpage{6}
|
||||
\item mp\_expt\_d, \hyperpage{31}
|
||||
\item mp\_exptmod, \hyperpage{31}
|
||||
\item mp\_exteuclid, \hyperpage{39}
|
||||
\item mp\_gcd, \hyperpage{39}
|
||||
\item mp\_grow, \hyperpage{12}
|
||||
\item MP\_GT, \hyperpage{17}
|
||||
@ -23,7 +24,7 @@
|
||||
\item mp\_init\_size, \hyperpage{10}
|
||||
\item mp\_int, \hyperpage{6}
|
||||
\item mp\_invmod, \hyperpage{40}
|
||||
\item mp\_jacobi, \hyperpage{39}
|
||||
\item mp\_jacobi, \hyperpage{40}
|
||||
\item mp\_lcm, \hyperpage{39}
|
||||
\item mp\_lshd, \hyperpage{23}
|
||||
\item MP\_LT, \hyperpage{17}
|
||||
@ -43,12 +44,15 @@
|
||||
\item mp\_prime\_next\_prime, \hyperpage{34}
|
||||
\item mp\_prime\_rabin\_miller\_trials, \hyperpage{34}
|
||||
\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\_set, \hyperpage{15}
|
||||
\item mp\_set\_int, \hyperpage{16}
|
||||
\item mp\_shrink, \hyperpage{11}
|
||||
\item mp\_sqr, \hyperpage{25}
|
||||
\item mp\_sub, \hyperpage{23}
|
||||
\item mp\_toradix, \hyperpage{37}
|
||||
\item MP\_VAL, \hyperpage{5}
|
||||
\item mp\_xor, \hyperpage{23}
|
||||
\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}
|
||||
|
||||
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
|
||||
considerably less work. For example, a 10000-digit multiplication would take roughly 692,000 single precision
|
||||
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 724,000 single precision
|
||||
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
|
||||
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}
|
||||
\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{Stream 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}
|
||||
\index{mp\_gcd}
|
||||
\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);
|
||||
|
||||
/* 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
|
||||
* 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) */
|
||||
int
|
||||
mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
||||
int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
||||
{
|
||||
mp_int q;
|
||||
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;
|
||||
int err, len, x;
|
||||
|
||||
len = mp_radix_size(a, radix);
|
||||
if (len == 0) {
|
||||
return MP_VAL;
|
||||
if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
|
||||
return err;
|
||||
}
|
||||
|
||||
buf = XMALLOC (len);
|
||||
|
@ -42,7 +42,6 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
||||
} else {
|
||||
res = s_mp_mul (a, b, c);
|
||||
}
|
||||
|
||||
}
|
||||
c->sign = neg;
|
||||
return res;
|
||||
|
@ -15,26 +15,28 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* returns size of ASCII reprensentation */
|
||||
int
|
||||
mp_radix_size (mp_int * a, int radix)
|
||||
int mp_radix_size (mp_int * a, int radix, int *size)
|
||||
{
|
||||
int res, digs;
|
||||
mp_int t;
|
||||
mp_digit d;
|
||||
|
||||
*size = 0;
|
||||
|
||||
/* special case for binary */
|
||||
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 */
|
||||
if (radix < 2 || radix > 64) {
|
||||
return 0;
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
/* init a copy of the input */
|
||||
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* digs is the digit count */
|
||||
@ -57,6 +59,7 @@ mp_radix_size (mp_int * a, int radix)
|
||||
mp_clear (&t);
|
||||
|
||||
/* 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>
|
||||
|
||||
/* read a string [ASCII] in a given radix */
|
||||
int
|
||||
mp_read_radix (mp_int * a, char *str, int radix)
|
||||
int mp_read_radix (mp_int * a, char *str, int radix)
|
||||
{
|
||||
int y, res, neg;
|
||||
char ch;
|
||||
|
@ -18,7 +18,7 @@
|
||||
int mp_shrink (mp_int * a)
|
||||
{
|
||||
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) {
|
||||
return MP_MEM;
|
||||
}
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* get the size for an signed equivalent */
|
||||
int
|
||||
mp_signed_bin_size (mp_int * a)
|
||||
int mp_signed_bin_size (mp_int * a)
|
||||
{
|
||||
return 1 + mp_unsigned_bin_size (a);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ int
|
||||
mp_sqr (mp_int * a, mp_int * b)
|
||||
{
|
||||
int res;
|
||||
|
||||
/* use Toom-Cook? */
|
||||
if (a->used >= TOOM_SQR_CUTOFF) {
|
||||
res = mp_toom_sqr(a, b);
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* stores a bignum as a ASCII string in a given radix (2..64) */
|
||||
int
|
||||
mp_toradix (mp_int * a, char *str, int radix)
|
||||
int mp_toradix (mp_int * a, char *str, int radix)
|
||||
{
|
||||
int res, digs;
|
||||
mp_int t;
|
||||
|
@ -31,25 +31,7 @@ static const struct {
|
||||
{ 1408, 3 },
|
||||
{ 1536, 3 },
|
||||
{ 1664, 3 },
|
||||
{ 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 } };
|
||||
{ 1792, 2 } };
|
||||
|
||||
/* returns # of RM trials required for a given bit size */
|
||||
int mp_prime_rabin_miller_trials(int size)
|
||||
|
@ -20,8 +20,7 @@
|
||||
#define TAB_SIZE 256
|
||||
#endif
|
||||
|
||||
int
|
||||
s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
{
|
||||
mp_int M[TAB_SIZE], res, mu;
|
||||
mp_digit buf;
|
||||
@ -185,10 +184,10 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
|
||||
/* then multiply */
|
||||
if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
|
||||
goto __MU;
|
||||
goto __RES;
|
||||
}
|
||||
if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
|
||||
goto __MU;
|
||||
goto __RES;
|
||||
}
|
||||
|
||||
/* 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
|
||||
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.
|
||||
-- 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 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)
|
||||
|
@ -138,15 +138,16 @@ int main(void)
|
||||
|
||||
/* test mp_div_3 */
|
||||
#if 0
|
||||
mp_set(&d, 3);
|
||||
for (cnt = 0; cnt < 1000000; ) {
|
||||
mp_digit r1, r2;
|
||||
|
||||
if (!(++cnt & 127)) printf("%9d\r", cnt);
|
||||
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);
|
||||
|
||||
if (mp_cmp(&b, &c) || r1 != r2) {
|
||||
if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) {
|
||||
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 */
|
||||
while (mp_count_bits (&a) < k) {
|
||||
printf ("prime has %4d bits left\r", k - mp_count_bits (&a));
|
||||
fflush (stdout);
|
||||
fprintf (stderr, "prime has %4d bits left\r", k - mp_count_bits (&a));
|
||||
fflush (stderr);
|
||||
top:
|
||||
mp_set (&b, prime_digit ());
|
||||
|
||||
@ -322,7 +322,6 @@ pprime (int k, int li, mp_int * p, mp_int * q)
|
||||
if (ii == li)
|
||||
goto top;
|
||||
|
||||
/*
|
||||
{
|
||||
char buf[4096];
|
||||
|
||||
@ -331,10 +330,9 @@ pprime (int k, int li, mp_int * p, mp_int * q)
|
||||
mp_toradix(&a, buf, 10);
|
||||
printf("A == \n%s\n\n", buf);
|
||||
mp_toradix(&b, buf, 10);
|
||||
printf("B == \n%s\n", buf);
|
||||
printf("B == \n%s\n\nG == %d\n", buf, bases[ii]);
|
||||
printf("----------------------------------------------------------------\n");
|
||||
}
|
||||
*/
|
||||
|
||||
/* a = n */
|
||||
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
|
||||
#
|
||||
#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]
|
||||
CFLAGS += -fomit-frame-pointer
|
||||
|
||||
VERSION=0.28
|
||||
VERSION=0.29
|
||||
|
||||
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_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_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)
|
||||
$(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_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_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
|
||||
|
||||
|
@ -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_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_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
|
||||
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_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_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)
|
||||
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);
|
||||
|
||||
/* 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
|
||||
* 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) */
|
||||
int
|
||||
mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
||||
int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
||||
{
|
||||
mp_int q;
|
||||
mp_word w;
|
||||
@ -2665,6 +2664,79 @@ __M:
|
||||
|
||||
/* 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 */
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
@ -2752,9 +2824,8 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream)
|
||||
char *buf;
|
||||
int err, len, x;
|
||||
|
||||
len = mp_radix_size(a, radix);
|
||||
if (len == 0) {
|
||||
return MP_VAL;
|
||||
if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
|
||||
return err;
|
||||
}
|
||||
|
||||
buf = XMALLOC (len);
|
||||
@ -4201,7 +4272,6 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
||||
} else {
|
||||
res = s_mp_mul (a, b, c);
|
||||
}
|
||||
|
||||
}
|
||||
c->sign = neg;
|
||||
return res;
|
||||
@ -5251,26 +5321,28 @@ error:
|
||||
#include <tommath.h>
|
||||
|
||||
/* returns size of ASCII reprensentation */
|
||||
int
|
||||
mp_radix_size (mp_int * a, int radix)
|
||||
int mp_radix_size (mp_int * a, int radix, int *size)
|
||||
{
|
||||
int res, digs;
|
||||
mp_int t;
|
||||
mp_digit d;
|
||||
|
||||
*size = 0;
|
||||
|
||||
/* special case for binary */
|
||||
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 */
|
||||
if (radix < 2 || radix > 64) {
|
||||
return 0;
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
/* init a copy of the input */
|
||||
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
/* digs is the digit count */
|
||||
@ -5293,7 +5365,8 @@ mp_radix_size (mp_int * a, int radix)
|
||||
mp_clear (&t);
|
||||
|
||||
/* 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>
|
||||
|
||||
/* read a string [ASCII] in a given radix */
|
||||
int
|
||||
mp_read_radix (mp_int * a, char *str, int radix)
|
||||
int mp_read_radix (mp_int * a, char *str, int radix)
|
||||
{
|
||||
int y, res, neg;
|
||||
char ch;
|
||||
@ -5989,7 +6061,7 @@ int mp_set_int (mp_int * a, unsigned long b)
|
||||
int mp_shrink (mp_int * a)
|
||||
{
|
||||
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) {
|
||||
return MP_MEM;
|
||||
}
|
||||
@ -6019,8 +6091,7 @@ int mp_shrink (mp_int * a)
|
||||
#include <tommath.h>
|
||||
|
||||
/* get the size for an signed equivalent */
|
||||
int
|
||||
mp_signed_bin_size (mp_int * a)
|
||||
int mp_signed_bin_size (mp_int * a)
|
||||
{
|
||||
return 1 + mp_unsigned_bin_size (a);
|
||||
}
|
||||
@ -6049,6 +6120,7 @@ int
|
||||
mp_sqr (mp_int * a, mp_int * b)
|
||||
{
|
||||
int res;
|
||||
|
||||
/* use Toom-Cook? */
|
||||
if (a->used >= TOOM_SQR_CUTOFF) {
|
||||
res = mp_toom_sqr(a, b);
|
||||
@ -6892,8 +6964,7 @@ ERR:
|
||||
#include <tommath.h>
|
||||
|
||||
/* stores a bignum as a ASCII string in a given radix (2..64) */
|
||||
int
|
||||
mp_toradix (mp_int * a, char *str, int radix)
|
||||
int mp_toradix (mp_int * a, char *str, int radix)
|
||||
{
|
||||
int res, digs;
|
||||
mp_int t;
|
||||
@ -7086,25 +7157,7 @@ static const struct {
|
||||
{ 1408, 3 },
|
||||
{ 1536, 3 },
|
||||
{ 1664, 3 },
|
||||
{ 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 } };
|
||||
{ 1792, 2 } };
|
||||
|
||||
/* returns # of RM trials required for a given bit 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
|
||||
#endif
|
||||
|
||||
int
|
||||
s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
{
|
||||
mp_int M[TAB_SIZE], res, mu;
|
||||
mp_digit buf;
|
||||
@ -7516,10 +7568,10 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
|
||||
/* then multiply */
|
||||
if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
|
||||
goto __MU;
|
||||
goto __RES;
|
||||
}
|
||||
if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
|
||||
goto __MU;
|
||||
goto __RES;
|
||||
}
|
||||
|
||||
/* empty window and reset */
|
||||
|
@ -338,6 +338,9 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
|
||||
/* c = (a, b) */
|
||||
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) */
|
||||
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_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_fwrite(mp_int *a, int radix, FILE *stream);
|
||||
|
254
tommath.out
254
tommath.out
@ -1,7 +1,7 @@
|
||||
\BOOKMARK [0][-]{chapter.1}{Introduction}{}
|
||||
\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.2}{What is 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}{The Need for 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.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.5}{Work Effort}{section.1.3}
|
||||
\BOOKMARK [1][-]{section.1.4}{Exercises}{chapter.1}
|
||||
\BOOKMARK [0][-]{chapter.2}{Introduction to LibTomMath}{}
|
||||
\BOOKMARK [1][-]{section.2.1}{What is LibTomMath?}{chapter.2}
|
||||
\BOOKMARK [1][-]{section.2.2}{Goals of LibTomMath}{chapter.2}
|
||||
\BOOKMARK [1][-]{section.2.3}{Choice of LibTomMath}{chapter.2}
|
||||
\BOOKMARK [2][-]{subsection.2.3.1}{Code Base}{section.2.3}
|
||||
\BOOKMARK [2][-]{subsection.2.3.2}{API Simplicity}{section.2.3}
|
||||
\BOOKMARK [2][-]{subsection.2.3.3}{Optimizations}{section.2.3}
|
||||
\BOOKMARK [2][-]{subsection.2.3.4}{Portability and Stability}{section.2.3}
|
||||
\BOOKMARK [2][-]{subsection.2.3.5}{Choice}{section.2.3}
|
||||
\BOOKMARK [0][-]{chapter.3}{Getting Started}{}
|
||||
\BOOKMARK [1][-]{section.3.1}{Library Basics}{chapter.3}
|
||||
\BOOKMARK [1][-]{section.3.2}{What is a Multiple Precision Integer?}{chapter.3}
|
||||
\BOOKMARK [2][-]{subsection.3.2.1}{The mp\137int Structure}{section.3.2}
|
||||
\BOOKMARK [1][-]{section.3.3}{Argument Passing}{chapter.3}
|
||||
\BOOKMARK [1][-]{section.3.4}{Return Values}{chapter.3}
|
||||
\BOOKMARK [1][-]{section.3.5}{Initialization and Clearing}{chapter.3}
|
||||
\BOOKMARK [2][-]{subsection.3.5.1}{Initializing an mp\137int}{section.3.5}
|
||||
\BOOKMARK [2][-]{subsection.3.5.2}{Clearing an mp\137int}{section.3.5}
|
||||
\BOOKMARK [1][-]{section.3.6}{Maintenance Algorithms}{chapter.3}
|
||||
\BOOKMARK [2][-]{subsection.3.6.1}{Augmenting an mp\137int's Precision}{section.3.6}
|
||||
\BOOKMARK [2][-]{subsection.3.6.2}{Initializing Variable Precision mp\137ints}{section.3.6}
|
||||
\BOOKMARK [2][-]{subsection.3.6.3}{Multiple Integer Initializations and Clearings}{section.3.6}
|
||||
\BOOKMARK [2][-]{subsection.3.6.4}{Clamping Excess Digits}{section.3.6}
|
||||
\BOOKMARK [0][-]{chapter.4}{Basic Operations}{}
|
||||
\BOOKMARK [1][-]{section.1.5}{Introduction to LibTomMath}{chapter.1}
|
||||
\BOOKMARK [2][-]{subsection.1.5.1}{What is LibTomMath?}{section.1.5}
|
||||
\BOOKMARK [2][-]{subsection.1.5.2}{Goals of LibTomMath}{section.1.5}
|
||||
\BOOKMARK [1][-]{section.1.6}{Choice of LibTomMath}{chapter.1}
|
||||
\BOOKMARK [2][-]{subsection.1.6.1}{Code Base}{section.1.6}
|
||||
\BOOKMARK [2][-]{subsection.1.6.2}{API Simplicity}{section.1.6}
|
||||
\BOOKMARK [2][-]{subsection.1.6.3}{Optimizations}{section.1.6}
|
||||
\BOOKMARK [2][-]{subsection.1.6.4}{Portability and Stability}{section.1.6}
|
||||
\BOOKMARK [2][-]{subsection.1.6.5}{Choice}{section.1.6}
|
||||
\BOOKMARK [0][-]{chapter.2}{Getting Started}{}
|
||||
\BOOKMARK [1][-]{section.2.1}{Library Basics}{chapter.2}
|
||||
\BOOKMARK [1][-]{section.2.2}{What is a Multiple Precision Integer?}{chapter.2}
|
||||
\BOOKMARK [2][-]{subsection.2.2.1}{The mp\137int Structure}{section.2.2}
|
||||
\BOOKMARK [1][-]{section.2.3}{Argument Passing}{chapter.2}
|
||||
\BOOKMARK [1][-]{section.2.4}{Return Values}{chapter.2}
|
||||
\BOOKMARK [1][-]{section.2.5}{Initialization and Clearing}{chapter.2}
|
||||
\BOOKMARK [2][-]{subsection.2.5.1}{Initializing an mp\137int}{section.2.5}
|
||||
\BOOKMARK [2][-]{subsection.2.5.2}{Clearing an mp\137int}{section.2.5}
|
||||
\BOOKMARK [1][-]{section.2.6}{Maintenance Algorithms}{chapter.2}
|
||||
\BOOKMARK [2][-]{subsection.2.6.1}{Augmenting an mp\137int's Precision}{section.2.6}
|
||||
\BOOKMARK [2][-]{subsection.2.6.2}{Initializing Variable Precision mp\137ints}{section.2.6}
|
||||
\BOOKMARK [2][-]{subsection.2.6.3}{Multiple Integer Initializations and Clearings}{section.2.6}
|
||||
\BOOKMARK [2][-]{subsection.2.6.4}{Clamping Excess Digits}{section.2.6}
|
||||
\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.2}{Assigning Values to mp\137int Structures}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.2.1}{Copying an mp\137int}{section.4.2}
|
||||
\BOOKMARK [2][-]{subsection.4.2.2}{Creating a Clone}{section.4.2}
|
||||
\BOOKMARK [1][-]{section.4.3}{Zeroing an Integer}{chapter.4}
|
||||
\BOOKMARK [1][-]{section.4.4}{Sign Manipulation}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.4.1}{Absolute Value}{section.4.4}
|
||||
\BOOKMARK [2][-]{subsection.4.4.2}{Integer Negation}{section.4.4}
|
||||
\BOOKMARK [1][-]{section.4.5}{Small Constants}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.5.1}{Setting Small Constants}{section.4.5}
|
||||
\BOOKMARK [2][-]{subsection.4.5.2}{Setting Large Constants}{section.4.5}
|
||||
\BOOKMARK [1][-]{section.4.6}{Comparisons}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.6.1}{Unsigned Comparisions}{section.4.6}
|
||||
\BOOKMARK [2][-]{subsection.4.6.2}{Signed Comparisons}{section.4.6}
|
||||
\BOOKMARK [0][-]{chapter.5}{Basic Arithmetic}{}
|
||||
\BOOKMARK [1][-]{section.5.1}{Introduction}{chapter.5}
|
||||
\BOOKMARK [1][-]{section.5.2}{Addition and Subtraction}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.2.1}{Low Level Addition}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.2}{Low Level Subtraction}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.3}{High Level Addition}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.4}{High Level Subtraction}{section.5.2}
|
||||
\BOOKMARK [1][-]{section.5.3}{Bit and Digit Shifting}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.3.1}{Multiplication by Two}{section.5.3}
|
||||
\BOOKMARK [2][-]{subsection.5.3.2}{Division by Two}{section.5.3}
|
||||
\BOOKMARK [1][-]{section.5.4}{Polynomial Basis Operations}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.4.1}{Multiplication by x}{section.5.4}
|
||||
\BOOKMARK [2][-]{subsection.5.4.2}{Division by x}{section.5.4}
|
||||
\BOOKMARK [1][-]{section.5.5}{Powers of Two}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.5.1}{Multiplication by Power of Two}{section.5.5}
|
||||
\BOOKMARK [2][-]{subsection.5.5.2}{Division by Power of Two}{section.5.5}
|
||||
\BOOKMARK [2][-]{subsection.5.5.3}{Remainder of Division by Power of Two}{section.5.5}
|
||||
\BOOKMARK [0][-]{chapter.6}{Multiplication and Squaring}{}
|
||||
\BOOKMARK [1][-]{section.6.1}{The Multipliers}{chapter.6}
|
||||
\BOOKMARK [1][-]{section.6.2}{Multiplication}{chapter.6}
|
||||
\BOOKMARK [2][-]{subsection.6.2.1}{The Baseline Multiplication}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.2}{Faster Multiplication by the ``Comba'' Method}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.3}{Polynomial Basis Multiplication}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.4}{Karatsuba Multiplication}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.5}{Toom-Cook 3-Way Multiplication}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.6}{Signed Multiplication}{section.6.2}
|
||||
\BOOKMARK [1][-]{section.6.3}{Squaring}{chapter.6}
|
||||
\BOOKMARK [2][-]{subsection.6.3.1}{The Baseline Squaring Algorithm}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.2}{Faster Squaring by the ``Comba'' Method}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.3}{Polynomial Basis Squaring}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.4}{Karatsuba Squaring}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.5}{Toom-Cook Squaring}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.6}{High Level Squaring}{section.6.3}
|
||||
\BOOKMARK [0][-]{chapter.7}{Modular Reduction}{}
|
||||
\BOOKMARK [1][-]{section.7.1}{Basics of Modular Reduction}{chapter.7}
|
||||
\BOOKMARK [1][-]{section.7.2}{The Barrett Reduction}{chapter.7}
|
||||
\BOOKMARK [2][-]{subsection.7.2.1}{Fixed Point Arithmetic}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.2}{Choosing a Radix Point}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.3}{Trimming the Quotient}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.4}{Trimming the Residue}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.5}{The Barrett Algorithm}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.6}{The Barrett Setup Algorithm}{section.7.2}
|
||||
\BOOKMARK [1][-]{section.7.3}{The Montgomery Reduction}{chapter.7}
|
||||
\BOOKMARK [2][-]{subsection.7.3.1}{Digit Based Montgomery Reduction}{section.7.3}
|
||||
\BOOKMARK [2][-]{subsection.7.3.2}{Baseline Montgomery Reduction}{section.7.3}
|
||||
\BOOKMARK [2][-]{subsection.7.3.3}{Faster ``Comba'' Montgomery Reduction}{section.7.3}
|
||||
\BOOKMARK [2][-]{subsection.7.3.4}{Montgomery Setup}{section.7.3}
|
||||
\BOOKMARK [1][-]{section.7.4}{The Diminished Radix Algorithm}{chapter.7}
|
||||
\BOOKMARK [2][-]{subsection.7.4.1}{Choice of Moduli}{section.7.4}
|
||||
\BOOKMARK [2][-]{subsection.7.4.2}{Choice of k}{section.7.4}
|
||||
\BOOKMARK [2][-]{subsection.7.4.3}{Restricted Diminished Radix Reduction}{section.7.4}
|
||||
\BOOKMARK [2][-]{subsection.7.4.4}{Unrestricted Diminished Radix Reduction}{section.7.4}
|
||||
\BOOKMARK [1][-]{section.7.5}{Algorithm Comparison}{chapter.7}
|
||||
\BOOKMARK [0][-]{chapter.8}{Exponentiation}{}
|
||||
\BOOKMARK [1][-]{section.8.1}{Exponentiation Basics}{chapter.8}
|
||||
\BOOKMARK [2][-]{subsection.8.1.1}{Single Digit Exponentiation}{section.8.1}
|
||||
\BOOKMARK [1][-]{section.8.2}{k-ary Exponentiation}{chapter.8}
|
||||
\BOOKMARK [2][-]{subsection.8.2.1}{Optimal Values of k}{section.8.2}
|
||||
\BOOKMARK [2][-]{subsection.8.2.2}{Sliding-Window Exponentiation}{section.8.2}
|
||||
\BOOKMARK [1][-]{section.8.3}{Modular Exponentiation}{chapter.8}
|
||||
\BOOKMARK [2][-]{subsection.8.3.1}{Barrett Modular Exponentiation}{section.8.3}
|
||||
\BOOKMARK [1][-]{section.8.4}{Quick Power of Two}{chapter.8}
|
||||
\BOOKMARK [0][-]{chapter.9}{Higher Level Algorithms}{}
|
||||
\BOOKMARK [1][-]{section.9.1}{Integer Division with Remainder}{chapter.9}
|
||||
\BOOKMARK [2][-]{subsection.9.1.1}{Quotient Estimation}{section.9.1}
|
||||
\BOOKMARK [2][-]{subsection.9.1.2}{Normalized Integers}{section.9.1}
|
||||
\BOOKMARK [2][-]{subsection.9.1.3}{Radix- Division with Remainder}{section.9.1}
|
||||
\BOOKMARK [1][-]{section.9.2}{Single Digit Helpers}{chapter.9}
|
||||
\BOOKMARK [2][-]{subsection.9.2.1}{Single Digit Addition and Subtraction}{section.9.2}
|
||||
\BOOKMARK [2][-]{subsection.9.2.2}{Single Digit Multiplication}{section.9.2}
|
||||
\BOOKMARK [2][-]{subsection.9.2.3}{Single Digit Division}{section.9.2}
|
||||
\BOOKMARK [2][-]{subsection.9.2.4}{Single Digit Root Extraction}{section.9.2}
|
||||
\BOOKMARK [1][-]{section.9.3}{Random Number Generation}{chapter.9}
|
||||
\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}
|
||||
\BOOKMARK [1][-]{section.4.2}{Addition and Subtraction}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.2.1}{Low Level Addition}{section.4.2}
|
||||
\BOOKMARK [2][-]{subsection.4.2.2}{Low Level Subtraction}{section.4.2}
|
||||
\BOOKMARK [2][-]{subsection.4.2.3}{High Level Addition}{section.4.2}
|
||||
\BOOKMARK [2][-]{subsection.4.2.4}{High Level Subtraction}{section.4.2}
|
||||
\BOOKMARK [1][-]{section.4.3}{Bit and Digit Shifting}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.3.1}{Multiplication by Two}{section.4.3}
|
||||
\BOOKMARK [2][-]{subsection.4.3.2}{Division by Two}{section.4.3}
|
||||
\BOOKMARK [1][-]{section.4.4}{Polynomial Basis Operations}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.4.1}{Multiplication by x}{section.4.4}
|
||||
\BOOKMARK [2][-]{subsection.4.4.2}{Division by x}{section.4.4}
|
||||
\BOOKMARK [1][-]{section.4.5}{Powers of Two}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.5.1}{Multiplication by Power of Two}{section.4.5}
|
||||
\BOOKMARK [2][-]{subsection.4.5.2}{Division by Power of Two}{section.4.5}
|
||||
\BOOKMARK [2][-]{subsection.4.5.3}{Remainder of Division by Power of Two}{section.4.5}
|
||||
\BOOKMARK [0][-]{chapter.5}{Multiplication and Squaring}{}
|
||||
\BOOKMARK [1][-]{section.5.1}{The Multipliers}{chapter.5}
|
||||
\BOOKMARK [1][-]{section.5.2}{Multiplication}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.2.1}{The Baseline Multiplication}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.2}{Faster Multiplication by the ``Comba'' Method}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.3}{Polynomial Basis Multiplication}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.4}{Karatsuba Multiplication}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.5}{Toom-Cook 3-Way Multiplication}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.6}{Signed Multiplication}{section.5.2}
|
||||
\BOOKMARK [1][-]{section.5.3}{Squaring}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.3.1}{The Baseline Squaring Algorithm}{section.5.3}
|
||||
\BOOKMARK [2][-]{subsection.5.3.2}{Faster Squaring by the ``Comba'' Method}{section.5.3}
|
||||
\BOOKMARK [2][-]{subsection.5.3.3}{Polynomial Basis Squaring}{section.5.3}
|
||||
\BOOKMARK [2][-]{subsection.5.3.4}{Karatsuba Squaring}{section.5.3}
|
||||
\BOOKMARK [2][-]{subsection.5.3.5}{Toom-Cook Squaring}{section.5.3}
|
||||
\BOOKMARK [2][-]{subsection.5.3.6}{High Level Squaring}{section.5.3}
|
||||
\BOOKMARK [0][-]{chapter.6}{Modular Reduction}{}
|
||||
\BOOKMARK [1][-]{section.6.1}{Basics of Modular Reduction}{chapter.6}
|
||||
\BOOKMARK [1][-]{section.6.2}{The Barrett Reduction}{chapter.6}
|
||||
\BOOKMARK [2][-]{subsection.6.2.1}{Fixed Point Arithmetic}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.2}{Choosing a Radix Point}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.3}{Trimming the Quotient}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.4}{Trimming the Residue}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.5}{The Barrett Algorithm}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.6}{The Barrett Setup Algorithm}{section.6.2}
|
||||
\BOOKMARK [1][-]{section.6.3}{The Montgomery Reduction}{chapter.6}
|
||||
\BOOKMARK [2][-]{subsection.6.3.1}{Digit Based Montgomery Reduction}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.2}{Baseline Montgomery Reduction}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.3}{Faster ``Comba'' Montgomery Reduction}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.4}{Montgomery Setup}{section.6.3}
|
||||
\BOOKMARK [1][-]{section.6.4}{The Diminished Radix Algorithm}{chapter.6}
|
||||
\BOOKMARK [2][-]{subsection.6.4.1}{Choice of Moduli}{section.6.4}
|
||||
\BOOKMARK [2][-]{subsection.6.4.2}{Choice of k}{section.6.4}
|
||||
\BOOKMARK [2][-]{subsection.6.4.3}{Restricted Diminished Radix Reduction}{section.6.4}
|
||||
\BOOKMARK [2][-]{subsection.6.4.4}{Unrestricted Diminished Radix Reduction}{section.6.4}
|
||||
\BOOKMARK [1][-]{section.6.5}{Algorithm Comparison}{chapter.6}
|
||||
\BOOKMARK [0][-]{chapter.7}{Exponentiation}{}
|
||||
\BOOKMARK [1][-]{section.7.1}{Exponentiation Basics}{chapter.7}
|
||||
\BOOKMARK [2][-]{subsection.7.1.1}{Single Digit Exponentiation}{section.7.1}
|
||||
\BOOKMARK [1][-]{section.7.2}{k-ary Exponentiation}{chapter.7}
|
||||
\BOOKMARK [2][-]{subsection.7.2.1}{Optimal Values of k}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.2}{Sliding-Window Exponentiation}{section.7.2}
|
||||
\BOOKMARK [1][-]{section.7.3}{Modular Exponentiation}{chapter.7}
|
||||
\BOOKMARK [2][-]{subsection.7.3.1}{Barrett Modular Exponentiation}{section.7.3}
|
||||
\BOOKMARK [1][-]{section.7.4}{Quick Power of Two}{chapter.7}
|
||||
\BOOKMARK [0][-]{chapter.8}{Higher Level Algorithms}{}
|
||||
\BOOKMARK [1][-]{section.8.1}{Integer Division with Remainder}{chapter.8}
|
||||
\BOOKMARK [2][-]{subsection.8.1.1}{Quotient Estimation}{section.8.1}
|
||||
\BOOKMARK [2][-]{subsection.8.1.2}{Normalized Integers}{section.8.1}
|
||||
\BOOKMARK [2][-]{subsection.8.1.3}{Radix- Division with Remainder}{section.8.1}
|
||||
\BOOKMARK [1][-]{section.8.2}{Single Digit Helpers}{chapter.8}
|
||||
\BOOKMARK [2][-]{subsection.8.2.1}{Single Digit Addition and Subtraction}{section.8.2}
|
||||
\BOOKMARK [2][-]{subsection.8.2.2}{Single Digit Multiplication}{section.8.2}
|
||||
\BOOKMARK [2][-]{subsection.8.2.3}{Single Digit Division}{section.8.2}
|
||||
\BOOKMARK [2][-]{subsection.8.2.4}{Single Digit Root Extraction}{section.8.2}
|
||||
\BOOKMARK [1][-]{section.8.3}{Random Number Generation}{chapter.8}
|
||||
\BOOKMARK [1][-]{section.8.4}{Formatted Representations}{chapter.8}
|
||||
\BOOKMARK [2][-]{subsection.8.4.1}{Reading Radix-n Input}{section.8.4}
|
||||
\BOOKMARK [2][-]{subsection.8.4.2}{Generating Radix-n Output}{section.8.4}
|
||||
\BOOKMARK [0][-]{chapter.9}{Number Theoretic Algorithms}{}
|
||||
\BOOKMARK [1][-]{section.9.1}{Greatest Common Divisor}{chapter.9}
|
||||
\BOOKMARK [2][-]{subsection.9.1.1}{Complete Greatest Common Divisor}{section.9.1}
|
||||
\BOOKMARK [1][-]{section.9.2}{Least Common Multiple}{chapter.9}
|
||||
\BOOKMARK [1][-]{section.9.3}{Jacobi Symbol Computation}{chapter.9}
|
||||
\BOOKMARK [2][-]{subsection.9.3.1}{Jacobi Symbol}{section.9.3}
|
||||
\BOOKMARK [1][-]{section.9.4}{Modular Inverse}{chapter.9}
|
||||
\BOOKMARK [2][-]{subsection.9.4.1}{General Case}{section.9.4}
|
||||
\BOOKMARK [1][-]{section.9.5}{Primality Tests}{chapter.9}
|
||||
\BOOKMARK [2][-]{subsection.9.5.1}{Trial Division}{section.9.5}
|
||||
\BOOKMARK [2][-]{subsection.9.5.2}{The Fermat Test}{section.9.5}
|
||||
\BOOKMARK [2][-]{subsection.9.5.3}{The Miller-Rabin Test}{section.9.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}
|
||||
\chapter{Introduction}
|
||||
\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}
|
||||
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
|
||||
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
|
||||
Java \ref{JAVA} only provide instrinsic support for integers which are relatively small and are single precision.
|
||||
typical RSA modulus would be at least greater than $10^{309}$. However, modern programming languages such as ISO C \cite{ISOC} and
|
||||
Java \cite{JAVA} only provide instrinsic support for integers which are relatively small and single precision.
|
||||
|
||||
\begin{figure}[!here]
|
||||
\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
|
||||
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
|
||||
trivially factored on the average desktop computer, rendering any protocol based on the algorithm insecure. Multiple
|
||||
precision algorithms solve this very problem by extending the range of representable integers while using single precision
|
||||
data types.
|
||||
trivially factored\footnote{A Pollard-Rho factoring would take only $2^{16}$ time.} on the average desktop computer,
|
||||
rendering any protocol based on the algorithm insecure. Multiple precision algorithms solve this very problem by
|
||||
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
|
||||
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
|
||||
scientific applications must minimize the total output error over long calculations.
|
||||
|
||||
\subsection{What is Multiple Precision Arithmetic?}
|
||||
At the heart of all multiple precision integer operations are the ``long-hand'' algorithms taught to children in grade
|
||||
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$.}.
|
||||
Another use for large integers is within arithmetic on polynomials of large characteristic (i.e. $GF(p)[x]$ for large $p$).
|
||||
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.}.
|
||||
|
||||
\subsection{Benefits of Multiple Precision Arithmetic}
|
||||
\index{precision}
|
||||
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,
|
||||
the product of two $n$-bit integers requires at least $2n$ bits of resolution to be precisely represented.
|
||||
A multiple precision algorithm would augment the precision of the destination to accomodate the result while a single
|
||||
precision system would truncate excess bits to maintain a fixed level of precision.
|
||||
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 precision to be represented faithfully. A multiple
|
||||
precision algorithm would augment the precision of the destination to accomodate the result while a single precision system
|
||||
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
|
||||
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
|
||||
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
|
||||
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}
|
||||
The purpose of this text is to instruct the reader regarding how to implement multiple precision algorithms. That is
|
||||
to not only explain a limited subset of the core theory behind the algorithms but also the various ``house keeping''
|
||||
The purpose of this text is to instruct the reader regarding how to implement efficient multiple precision algorithms.
|
||||
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}
|
||||
give considerably detailed explanations of the theoretical aspects of algorithms and often very little information
|
||||
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
|
||||
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}
|
||||
\subsection{Notation}
|
||||
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
|
||||
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,
|
||||
$5/2 = 2$ which will often be written as $\lfloor 5/2 \rfloor = 2$ for clarity. When a value is presented as a
|
||||
fraction such as $5 \over 2$ a real value division is implied.
|
||||
$5/2 = 2$ which will often be written as $\lfloor 5/2 \rfloor = 2$ for clarity. When an expression is written as a
|
||||
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
|
||||
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}
|
||||
\index{big-O}
|
||||
To measure the efficiency of the specified algorithms, a modified big-O notation is used. In this system all
|
||||
\index{big-Oh}
|
||||
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.}.
|
||||
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.
|
||||
|
||||
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
|
||||
$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,
|
||||
the notation. For example, a normal baseline multiplication (section \ref{sec:basemult}) requires $O(n^2)$ work while a
|
||||
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
|
||||
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
|
||||
the complexity of an algorithm with respect to its time requirements. For example,
|
||||
$O(1)$, $O(n)$, $O(n^2)$, ..., $O(n^k)$ are various possible work levels that will be of concern in this text. Any
|
||||
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.}.
|
||||
All of the algorithms presented in this text have a polynomial time work level. That is, of the form
|
||||
$O(n^k)$ for $n, k \in \Z^{+}$. This will help make useful comparisons in terms of the speed of the algorithms and how
|
||||
various optimizations will help pay off in the long run.
|
||||
|
||||
\section{Exercises}
|
||||
Within the more advanced chapters a section will be set aside to give the reader some challenging exercises. These
|
||||
exercises are not designed to be prize winning problems, but instead to be thought provoking. Wherever possible the
|
||||
problems are forward minded, stating problems that will be answered in subsequent chapters. The reader is encouraged to
|
||||
finish the exercises as they appear to get a better understanding of the subject material.
|
||||
Within the more advanced chapters a section will be set aside to give the reader some challenging exercises related to
|
||||
the discussion at hand. These exercises are not designed to be prize winning problems, but instead to be thought
|
||||
provoking. Wherever possible the problems are forward minded, stating problems that will be answered in subsequent
|
||||
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
|
||||
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
|
||||
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
|
||||
scoring.
|
||||
scoring system used.
|
||||
|
||||
\begin{tabular}{cl}
|
||||
$\left [ 1 \right ]$ & An easy problem that should only take the reader a manner of \\
|
||||
\begin{figure}[here]
|
||||
\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 \\
|
||||
& to solve. \\
|
||||
& \\
|
||||
$\left [ 2 \right ]$ & An easy problem that involves a marginal amount of computer \\
|
||||
\hline $\left [ 2 \right ]$ & An easy problem that involves a marginal amount of computer \\
|
||||
& time usage. Usually requires a program to be written to \\
|
||||
& solve the problem. \\
|
||||
& \\
|
||||
$\left [ 3 \right ]$ & A moderately hard problem that requires a non-trivial amount \\
|
||||
\hline $\left [ 3 \right ]$ & A moderately hard problem that requires a non-trivial amount \\
|
||||
& of work. Usually involves trivial research and development of \\
|
||||
& new theory from the perspective of a student. \\
|
||||
& \\
|
||||
$\left [ 4 \right ]$ & A moderately hard problem that involves a non-trivial amount \\
|
||||
\hline $\left [ 4 \right ]$ & A moderately hard problem that involves a non-trivial amount \\
|
||||
& of work and research, the solution to which will demonstrate \\
|
||||
& a higher mastery of the subject matter. \\
|
||||
& \\
|
||||
$\left [ 5 \right ]$ & A hard problem that involves concepts that are difficult for a \\
|
||||
\hline $\left [ 5 \right ]$ & A hard problem that involves concepts that are difficult for a \\
|
||||
& novice to solve. Solutions to these problems will demonstrate a \\
|
||||
& complete mastery of the given subject. \\
|
||||
& \\
|
||||
\hline
|
||||
\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
|
||||
devising new theory. These problems are quick tests to see if the material is understood. Problems at the second level are also
|
||||
designed to be easy but will require a program or algorithm to be implemented to arrive at the answer.
|
||||
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 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
|
||||
requires some thought and skill. These problems will almost always involve devising a new algorithm or implementing a variation of
|
||||
another algorithm.
|
||||
Problems at the third level are meant to be a bit more difficult than the first two levels. The answer is often
|
||||
fairly obvious but arriving at an exacting solution requires some thought and skill. These problems will almost always
|
||||
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
|
||||
likely not know the answer right away, nor will the text provide the exact details of the answer until a subsequent
|
||||
chapter. 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.
|
||||
Problems at the fourth level are meant to be similar to those of the level three questions except they will require
|
||||
additional research to be completed. The reader will most likely not know the answer right away, nor will the text provide
|
||||
the exact details of the answer until a subsequent chapter.
|
||||
|
||||
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
|
||||
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?}
|
||||
LibTomMath is a free and open source multiple precision library written in portable ISO C. By portable it is
|
||||
meant that the library does not contain any code that is computer platform dependent or otherwise problematic to use on
|
||||
\subsection{What is LibTomMath?}
|
||||
LibTomMath is a free and open source multiple precision integer library written entirely in portable ISO C. By portable it
|
||||
is meant that the library does not contain any code that is computer platform dependent or otherwise problematic to use on
|
||||
any given platform.
|
||||
|
||||
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 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,
|
||||
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
|
||||
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
|
||||
another library that fits in the same niche as LibTomMath. Even though LibTomMath uses MPI as the template for the
|
||||
function names and argument passing conventions, LibTomMath has been written from scratch by Tom St Denis.
|
||||
MPI library was used as a API template for all the basic functions. MPI was chosen because it is another library that fits
|
||||
in the same niche as LibTomMath. Even though LibTomMath uses MPI as the template for the function names and argument
|
||||
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''
|
||||
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}
|
||||
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.
|
||||
|
||||
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
|
||||
library is a mere 87,760 bytes ($116,182$ bytes for ARMv4 processors). This includes every single function
|
||||
LibTomMath provides from basic arithmetic to various number theoretic functions such as modular exponentiation, various
|
||||
reduction algorithms and Jacobi symbol computation.
|
||||
which allows the reader to find a given function very quickly. On average there are about $76$ lines of code per source
|
||||
file which makes the source very easily to follow. By comparison MPI and LIP are single file projects making code tracing
|
||||
very hard. GMP has many conditional code segments which also hinder tracing.
|
||||
|
||||
By comparison MPI, which has fewer functions than LibTomMath, compiled with the same conditions occupied 45,429 bytes
|
||||
($54,536$ for ARMv4). GMP which has a rather large collection of functions with the default configuration on an
|
||||
x86 Athlon is 2,950,688 bytes. Note that while LibTomMath has fewer functions than GMP it has been used as the sole basis
|
||||
for several public key cryptosystems without having to seek additional outside functions to supplement the library.
|
||||
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.}
|
||||
which is fairly small compared to GMP (over $250$KiB). LibTomMath is slightly larger than MPI (which compiles to about
|
||||
$50$KiB) but LibTomMath is also much faster and more complete than MPI.
|
||||
|
||||
\subsection{API Simplicity}
|
||||
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
|
||||
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}
|
||||
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
|
||||
@ -2320,6 +2334,7 @@ This technique led to the discovery of polynomial basis algorithms (\textit{good
|
||||
|
||||
\section{Multiplication}
|
||||
\subsection{The Baseline Multiplication}
|
||||
\label{sec:basemult}
|
||||
\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
|
||||
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$.
|
||||
|
||||
\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
|
||||
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}
|
||||
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}
|
||||
|
||||
\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