Permalink
Browse files

added libtommath-0.24

  • Loading branch information...
1 parent eed6765 commit 03cc01b5782df0d91fbc6ccf13279097d0e9b6f0 Tom St Denis committed with sjaeckel Jul 16, 2003
Showing with 398 additions and 71 deletions.
  1. BIN bn.pdf
  2. +6 −4 bn.tex
  3. +77 −8 bn_mp_add_d.c
  4. +1 −1 bn_mp_gcd.c
  5. +1 −1 bn_mp_prime_miller_rabin.c
  6. +1 −1 bn_mp_prime_next_prime.c
  7. +53 −8 bn_mp_sub_d.c
  8. +9 −0 changes.txt
  9. +30 −5 demo/demo.c
  10. +1 −1 etc/makefile
  11. +54 −18 etc/pprime.c
  12. +6 −3 makefile
  13. +26 −2 mtest/mtest.c
  14. BIN poster.pdf
  15. +133 −19 pre_gen/mpi.c
View
BIN bn.pdf
Binary file not shown.
View
10 bn.tex
@@ -1,7 +1,7 @@
\documentclass[]{article}
\begin{document}
-\title{LibTomMath v0.23 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
+\title{LibTomMath v0.24 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
\author{Tom St Denis \\ tomstdenis@iahu.ca}
\maketitle
\newpage
@@ -389,7 +389,7 @@ \subsection{Primality Routines}
/* finds the next prime after the number "a" using "t" trials
* of Miller-Rabin.
*/
-int mp_prime_next_prime(mp_int *a, int t);
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
\end{verbatim}
\subsection{Radix Conversions}
@@ -832,9 +832,11 @@ \subsubsection{mp\_prime\_is\_prime(mp\_int *a, int t, int *result)}
function will always set $result$ to $1$. If $a$ is composite then it will almost always set $result$
to $0$. The probability of error is given in figure two.
-\subsubsection{mp\_prime\_next\_prime(mp\_int *a, int t)}
+\subsubsection{mp\_prime\_next\_prime(mp\_int *a, int t, int bbs\_style)}
This function will find the next prime \textbf{after} $a$ by using trial division and $t$ trials of
-Miller-Rabin.
+Miller-Rabin. If $bbs\_style$ is set to one than $a$ will be the next prime such that $a \equiv 3 \mbox{ (mod }4\mbox{)}$
+which is useful for certain algorithms. Otherwise, $a$ will be the next prime greater than the initial input
+value and may be $\lbrace 1, 3 \rbrace \equiv a \mbox{ (mod }4\mbox{)}$.
\section{Timing Analysis}
View
@@ -18,15 +18,84 @@
int
mp_add_d (mp_int * a, mp_digit b, mp_int * c)
{
- mp_int t;
- int res;
+ int res, ix, oldused;
+ mp_digit *tmpa, *tmpc, mu;
- if ((res = mp_init_size(&t, 1)) != MP_OKAY) {
- return res;
+ /* grow c as required */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
}
- mp_set (&t, b);
- res = mp_add (a, &t, c);
- mp_clear (&t);
- return res;
+ /* if a is negative and |a| >= b, call c = |a| - b */
+ if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
+ /* temporarily fix sign of a */
+ a->sign = MP_ZPOS;
+
+ /* c = |a| - b */
+ res = mp_sub_d(a, b, c);
+
+ /* fix sign */
+ a->sign = c->sign = MP_NEG;
+
+ return res;
+ }
+
+
+ /* old number of used digits in c */
+ oldused = c->used;
+
+ /* sign always positive */
+ c->sign = MP_ZPOS;
+
+ /* source alias */
+ tmpa = a->dp;
+
+ /* destination alias */
+ tmpc = c->dp;
+
+ /* if a is positive */
+ if (a->sign == MP_ZPOS) {
+ /* setup size */
+ c->used = a->used + 1;
+
+ /* add digit, after this we're propagating
+ * the carry.
+ */
+ *tmpc = *tmpa++ + b;
+ mu = *tmpc >> DIGIT_BIT;
+ *tmpc++ &= MP_MASK;
+
+ /* now handle rest of the digits */
+ for (ix = 1; ix < a->used; ix++) {
+ *tmpc = *tmpa++ + mu;
+ mu = *tmpc >> DIGIT_BIT;
+ *tmpc++ &= MP_MASK;
+ }
+ /* set final carry */
+ ix++;
+ *tmpc++ = mu;
+
+ } else {
+ /* a was negative and |a| < b */
+ c->used = 1;
+
+ /* the result is a single digit */
+ *tmpc++ = b - a->dp[0];
+
+ /* setup count so the clearing of oldused
+ * can fall through correctly
+ */
+ ix = 1;
+ }
+
+ /* now zero to oldused */
+ while (ix++ < oldused) {
+ *tmpc++ = 0;
+ }
+ mp_clamp(c);
+
+ return MP_OKAY;
}
+
View
@@ -29,7 +29,7 @@ mp_gcd (mp_int * a, mp_int * b, mp_int * c)
return mp_copy (a, c);
}
if (mp_iszero (a) == 1 && mp_iszero (b) == 1) {
- mp_set (c, 1);
+ mp_zero(c);
return MP_OKAY;
}
@@ -53,7 +53,7 @@ mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
*/
s = mp_cnt_lsb(&r);
- /* now divide n - 1 by 2^s */
+ /* now divide n - 1 by 2**s */
if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
goto __R;
}
View
@@ -112,7 +112,7 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
/* y == 1 if any residue was zero [e.g. cannot be prime] */
y = 0;
- /* increase step to next odd */
+ /* increase step to next candidate */
step += kstep;
/* compute the new residue without using division */
View
@@ -18,16 +18,61 @@
int
mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
{
- mp_int t;
- int res;
+ mp_digit *tmpa, *tmpc, mu;
+ int res, ix, oldused;
+ /* grow c as required */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
- if ((res = mp_init (&t)) != MP_OKAY) {
- return res;
+ /* if a is negative just do an unsigned
+ * addition [with fudged signs]
+ */
+ if (a->sign == MP_NEG) {
+ a->sign = MP_ZPOS;
+ res = mp_add_d(a, b, c);
+ a->sign = c->sign = MP_NEG;
+ return res;
}
- mp_set (&t, b);
- res = mp_sub (a, &t, c);
- mp_clear (&t);
- return res;
+ /* setup regs */
+ oldused = c->used;
+ tmpa = a->dp;
+ tmpc = c->dp;
+
+ /* if a <= b simply fix the single digit */
+ if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
+ *tmpc++ = b - *tmpa;
+ ix = 1;
+
+ /* negative/1digit */
+ c->sign = MP_NEG;
+ c->used = 1;
+ } else {
+ /* positive/size */
+ c->sign = MP_ZPOS;
+ c->used = a->used;
+
+ /* subtract first digit */
+ *tmpc = *tmpa++ - b;
+ mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+ *tmpc++ &= MP_MASK;
+
+ /* handle rest of the digits */
+ for (ix = 1; ix < a->used; ix++) {
+ *tmpc = *tmpa++ - mu;
+ mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+ *tmpc++ &= MP_MASK;
+ }
+ }
+
+ for (; ix < oldused; ix++) {
+ *tmpc++ = 0;
+ }
+ mp_clamp(c);
+ return MP_OKAY;
}
+
View
@@ -1,3 +1,12 @@
+July 15th, 2003
+v0.24 -- Optimized mp_add_d and mp_sub_d to not allocate temporary variables
+ -- Fixed mp_gcd() so the gcd of 0,0 is 0. Allows the gcd operation to be chained
+ e.g. (0,0,a) == a [instead of 1]
+ -- Should be one of the last release for a while. Working on LibTomMath book now.
+ -- optimized the pprime demo [/etc/pprime.c] to first make a huge table of single
+ digit primes then it reads them randomly instead of randomly choosing/testing single
+ digit primes.
+
July 12th, 2003
v0.23 -- Optimized mp_prime_next_prime() to not use mp_mod [via is_divisible()] in each
iteration. Instead now a smaller table is kept of the residues which can be updated
View
@@ -46,7 +46,7 @@ int main(void)
{
mp_int a, b, c, d, e, f;
unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, inv_n,
- div2_n, mul2_n;
+ div2_n, mul2_n, add_d_n, sub_d_n;
unsigned rr;
int cnt, ix, old_kara_m, old_kara_s;
@@ -190,7 +190,7 @@ int main(void)
mp_rand(&b, cnt);
reset();
rr = 0;
- do {
+ do {
DO(mp_add(&a,&b,&c));
rr += 16;
} while (rdtsc() < (CLOCKS_PER_SEC * 2));
@@ -355,7 +355,7 @@ int main(void)
#endif
div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n =
- sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = 0;
+ sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n = sub_d_n= 0;
/* force KARA and TOOM to enable despite cutoffs */
KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 110;
@@ -374,7 +374,7 @@ int main(void)
}
- printf("%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu/%7lu ", add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, expt_n, inv_n, div2_n, mul2_n);
+ printf("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ", add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n, expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n);
fgets(cmd, 4095, stdin);
cmd[strlen(cmd)-1] = 0;
printf("%s ]\r",cmd); fflush(stdout);
@@ -559,8 +559,33 @@ draw(&a);draw(&b);draw(&c);draw(&d);
draw(&c);
return 0;
}
+ } else if (!strcmp(cmd, "add_d")) { ++add_d_n;
+ fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64);
+ fgets(buf, 4095, stdin); sscanf(buf, "%d", &ix);
+ fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64);
+ mp_add_d(&a, ix, &c);
+ if (mp_cmp(&b, &c) != MP_EQ) {
+ printf("add_d %lu failure\n", add_d_n);
+ draw(&a);
+ draw(&b);
+ draw(&c);
+ printf("d == %d\n", ix);
+ return 0;
+ }
+ } else if (!strcmp(cmd, "sub_d")) { ++sub_d_n;
+ fgets(buf, 4095, stdin); mp_read_radix(&a, buf, 64);
+ fgets(buf, 4095, stdin); sscanf(buf, "%d", &ix);
+ fgets(buf, 4095, stdin); mp_read_radix(&b, buf, 64);
+ mp_sub_d(&a, ix, &c);
+ if (mp_cmp(&b, &c) != MP_EQ) {
+ printf("sub_d %lu failure\n", sub_d_n);
+ draw(&a);
+ draw(&b);
+ draw(&c);
+ printf("d == %d\n", ix);
+ return 0;
+ }
}
-
}
return 0;
}
View
@@ -41,4 +41,4 @@ mont: mont.o
clean:
- rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime
+ rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat
Oops, something went wrong.

0 comments on commit 03cc01b

Please sign in to comment.