Permalink
Browse files

added libtommath-0.29

  • Loading branch information...
1 parent 455bb4d commit 6c48a9b3a634fef0c5b5b5f3b190b4a4c437cf9f Tom St Denis committed with sjaeckel Jan 25, 2004
Showing with 1,667 additions and 847 deletions.
  1. +3 −3 bn.ilg
  2. +5 −1 bn.ind
  3. BIN bn.pdf
  4. +41 −3 bn.tex
  5. +1 −1 bn_mp_div_3.c
  6. +1 −2 bn_mp_div_d.c
  7. +69 −0 bn_mp_exteuclid.c
  8. +3 −4 bn_mp_fwrite.c
  9. +0 −1 bn_mp_mul.c
  10. +9 −6 bn_mp_radix_size.c
  11. +1 −2 bn_mp_read_radix.c
  12. +1 −1 bn_mp_shrink.c
  13. +1 −2 bn_mp_signed_bin_size.c
  14. +1 −0 bn_mp_sqr.c
  15. +1 −2 bn_mp_toradix.c
  16. +1 −19 bn_prime_sizes_tab.c
  17. +3 −4 bn_s_mp_exptmod.c
  18. +13 −2 changes.txt
  19. +3 −2 demo/demo.c
  20. +3 −5 etc/pprime.c
  21. +414 −0 etc/prime.1024
  22. +205 −0 etc/prime.512
  23. +9 −3 makefile
  24. +1 −1 makefile.bcc
  25. +1 −1 makefile.cygwin_dll
  26. +1 −1 makefile.msvc
  27. BIN poster.pdf
  28. +96 −44 pre_gen/mpi.c
  29. +4 −1 tommath.h
  30. +127 −127 tommath.out
  31. BIN tommath.pdf
  32. +109 −87 tommath.src
  33. +540 −522 tommath.tex
View
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.
View
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}
View
BIN bn.pdf
Binary file not shown.
View
44 bn.tex
@@ -1001,10 +1001,10 @@ \section{Squaring}
\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 @@ \section{Random Primes}
\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
@@ -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
@@ -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;
View
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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");
}
}
Oops, something went wrong.

0 comments on commit 6c48a9b

Please sign in to comment.