added libtommath-0.29

This commit is contained in:
Tom St Denis 2004-01-25 17:40:21 +00:00 committed by Steffen Jaeckel
parent 455bb4db20
commit 6c48a9b3a6
33 changed files with 13855 additions and 12934 deletions

6
bn.ilg
View File

@ -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
View File

@ -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}

BIN
bn.pdf

Binary file not shown.

44
bn.tex
View File

@ -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}

View File

@ -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.

View File

@ -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
View 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;
}

View File

@ -19,11 +19,10 @@ 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);
if (buf == NULL) {
return MP_MEM;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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 */

View File

@ -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)

View File

@ -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");
}
}

View File

@ -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
View 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
View 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

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

Binary file not shown.

View File

@ -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,11 +2824,10 @@ 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);
if (buf == NULL) {
return MP_MEM;
@ -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 */

View File

@ -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);

View File

@ -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

File diff suppressed because one or more lines are too long

View File

@ -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 \\
& 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 \\
\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. \\
\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}

File diff suppressed because it is too large Load Diff