added libtommath-0.19
This commit is contained in:
		
							parent
							
								
									0ef44cea9b
								
							
						
					
					
						commit
						ef490f30f6
					
				
							
								
								
									
										2
									
								
								bn.tex
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								bn.tex
									
									
									
									
									
								
							@ -1,7 +1,7 @@
 | 
				
			|||||||
\documentclass[]{article}
 | 
					\documentclass[]{article}
 | 
				
			||||||
\begin{document}
 | 
					\begin{document}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\title{LibTomMath v0.18 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
 | 
					\title{LibTomMath v0.19 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
 | 
				
			||||||
\author{Tom St Denis \\ tomstdenis@iahu.ca}
 | 
					\author{Tom St Denis \\ tomstdenis@iahu.ca}
 | 
				
			||||||
\maketitle
 | 
					\maketitle
 | 
				
			||||||
\newpage
 | 
					\newpage
 | 
				
			||||||
 | 
				
			|||||||
@ -65,8 +65,8 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
 | 
				
			|||||||
     dr = mp_reduce_is_2k(P) << 1;
 | 
					     dr = mp_reduce_is_2k(P) << 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  /* if the modulus is odd use the fast method */
 | 
					  /* if the modulus is odd or dr != 0 use the fast method */
 | 
				
			||||||
  if ((mp_isodd (P) == 1 || dr !=  0) && P->used > 4) {
 | 
					  if (mp_isodd (P) == 1 || dr !=  0) {
 | 
				
			||||||
    return mp_exptmod_fast (G, X, P, Y, dr);
 | 
					    return mp_exptmod_fast (G, X, P, Y, dr);
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    return s_mp_exptmod (G, X, P, Y);
 | 
					    return s_mp_exptmod (G, X, P, Y);
 | 
				
			||||||
 | 
				
			|||||||
@ -80,6 +80,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
 | 
				
			|||||||
     if (((P->used * 2 + 1) < MP_WARRAY) &&
 | 
					     if (((P->used * 2 + 1) < MP_WARRAY) &&
 | 
				
			||||||
          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
 | 
					          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
 | 
				
			||||||
        redux = fast_mp_montgomery_reduce;
 | 
					        redux = fast_mp_montgomery_reduce;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     } else {
 | 
					     } else {
 | 
				
			||||||
        /* use slower baselien method */
 | 
					        /* use slower baselien method */
 | 
				
			||||||
        redux = mp_montgomery_reduce;
 | 
					        redux = mp_montgomery_reduce;
 | 
				
			||||||
 | 
				
			|||||||
@ -49,6 +49,7 @@ mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
 | 
				
			|||||||
  mp_int  x0, x1, y0, y1, t1, x0y0, x1y1;
 | 
					  mp_int  x0, x1, y0, y1, t1, x0y0, x1y1;
 | 
				
			||||||
  int     B, err;
 | 
					  int     B, err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* default the return code to an error */
 | 
				
			||||||
  err = MP_MEM;
 | 
					  err = MP_MEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* min # of digits */
 | 
					  /* min # of digits */
 | 
				
			||||||
@ -149,6 +150,7 @@ mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
 | 
				
			|||||||
  if (mp_add (&t1, &x1y1, c) != MP_OKAY)
 | 
					  if (mp_add (&t1, &x1y1, c) != MP_OKAY)
 | 
				
			||||||
    goto X1Y1;          /* t1 = x0y0 + t1 + x1y1 */
 | 
					    goto X1Y1;          /* t1 = x0y0 + t1 + x1y1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Algorithm succeeded set the return code to MP_OKAY */
 | 
				
			||||||
  err = MP_OKAY;
 | 
					  err = MP_OKAY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
X1Y1:mp_clear (&x1y1);
 | 
					X1Y1:mp_clear (&x1y1);
 | 
				
			||||||
 | 
				
			|||||||
@ -76,6 +76,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* x = x/b**n.used */
 | 
					  /* x = x/b**n.used */
 | 
				
			||||||
 | 
					  mp_clamp(x);
 | 
				
			||||||
  mp_rshd (x, n->used);
 | 
					  mp_rshd (x, n->used);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* if A >= m then A = A - m */
 | 
					  /* if A >= m then A = A - m */
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,8 @@ mp_reduce_is_2k(mp_int *a)
 | 
				
			|||||||
   } else if (a->used > 1) {
 | 
					   } else if (a->used > 1) {
 | 
				
			||||||
      iy = mp_count_bits(a);
 | 
					      iy = mp_count_bits(a);
 | 
				
			||||||
      for (ix = DIGIT_BIT; ix < iy; ix++) {
 | 
					      for (ix = DIGIT_BIT; ix < iy; ix++) {
 | 
				
			||||||
          if ((a->dp[ix/DIGIT_BIT] & ((mp_digit)1 << (mp_digit)(ix % DIGIT_BIT))) == 0) {
 | 
					          if ((a->dp[ix/DIGIT_BIT] & 
 | 
				
			||||||
 | 
					              ((mp_digit)1 << (mp_digit)(ix % DIGIT_BIT))) == 0) {
 | 
				
			||||||
             return 0;
 | 
					             return 0;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
#include <tommath.h>
 | 
					#include <tommath.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* multiplication using Toom-Cook 3-way algorithm */
 | 
					/* multiplication using the Toom-Cook 3-way algorithm */
 | 
				
			||||||
int 
 | 
					int 
 | 
				
			||||||
mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
					mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -22,14 +22,16 @@ mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			|||||||
    int res, B;
 | 
					    int res, B;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    /* init temps */
 | 
					    /* init temps */
 | 
				
			||||||
    if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &b0, &b1, &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
 | 
					    if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, 
 | 
				
			||||||
 | 
					                             &a0, &a1, &a2, &b0, &b1, 
 | 
				
			||||||
 | 
					                             &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
 | 
				
			||||||
       return res;
 | 
					       return res;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* B */
 | 
					    /* B */
 | 
				
			||||||
    B = MIN(a->used, b->used) / 3;
 | 
					    B = MIN(a->used, b->used) / 3;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* a = a2 * B^2 + a1 * B + a0 */
 | 
					    /* a = a2 * B**2 + a1 * B + a0 */
 | 
				
			||||||
    if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
 | 
					    if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
 | 
				
			||||||
       goto ERR;
 | 
					       goto ERR;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -45,7 +47,7 @@ mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    mp_rshd(&a2, B*2);
 | 
					    mp_rshd(&a2, B*2);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* b = b2 * B^2 + b1 * B + b0 */
 | 
					    /* b = b2 * B**2 + b1 * B + b0 */
 | 
				
			||||||
    if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
 | 
					    if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
 | 
				
			||||||
       goto ERR;
 | 
					       goto ERR;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -159,7 +161,8 @@ mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			|||||||
       16 8  4  2  1
 | 
					       16 8  4  2  1
 | 
				
			||||||
       1  0  0  0  0
 | 
					       1  0  0  0  0
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
       using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication 
 | 
					       using 12 subtractions, 4 shifts, 
 | 
				
			||||||
 | 
					              2 small divisions and 1 small multiplication 
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
     /* r1 - r4 */
 | 
					     /* r1 - r4 */
 | 
				
			||||||
@ -262,7 +265,9 @@ mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			|||||||
     }     
 | 
					     }     
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
ERR:
 | 
					ERR:
 | 
				
			||||||
     mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &b0, &b1, &b2, &tmp1, &tmp2, NULL);
 | 
					     mp_clear_multi(&w0, &w1, &w2, &w3, &w4, 
 | 
				
			||||||
 | 
					                    &a0, &a1, &a2, &b0, &b1, 
 | 
				
			||||||
 | 
					                    &b2, &tmp1, &tmp2, NULL);
 | 
				
			||||||
     return res;
 | 
					     return res;
 | 
				
			||||||
}     
 | 
					}     
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
 | 
				
			|||||||
@ -73,6 +73,14 @@ mp_toradix (mp_int * a, char *str, int radix)
 | 
				
			|||||||
    return MP_VAL;
 | 
					    return MP_VAL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  /* quick out if its zero */
 | 
				
			||||||
 | 
					  if (mp_iszero(a) == 1) {
 | 
				
			||||||
 | 
					     *str++ = '0';
 | 
				
			||||||
 | 
					     *str = '\0';
 | 
				
			||||||
 | 
					     return MP_OKAY;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
 | 
					  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -65,21 +65,26 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* create M table
 | 
					  /* create M table
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   * The M table contains powers of the input base, e.g. M[x] = G**x mod P
 | 
					   * The M table contains powers of the base, 
 | 
				
			||||||
 | 
					   * e.g. M[x] = G**x mod P
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   * The first half of the table is not computed though accept for M[0] and M[1]
 | 
					   * The first half of the table is not 
 | 
				
			||||||
 | 
					   * computed though accept for M[0] and M[1]
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
 | 
					  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
 | 
				
			||||||
    goto __MU;
 | 
					    goto __MU;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
 | 
					  /* compute the value at M[1<<(winsize-1)] by squaring 
 | 
				
			||||||
 | 
					   * M[1] (winsize-1) times 
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
 | 
					  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
 | 
				
			||||||
    goto __MU;
 | 
					    goto __MU;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (x = 0; x < (winsize - 1); x++) {
 | 
					  for (x = 0; x < (winsize - 1); x++) {
 | 
				
			||||||
    if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
 | 
					    if ((err = mp_sqr (&M[1 << (winsize - 1)], 
 | 
				
			||||||
 | 
					                       &M[1 << (winsize - 1)])) != MP_OKAY) {
 | 
				
			||||||
      goto __MU;
 | 
					      goto __MU;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if ((err = mp_reduce (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
 | 
					    if ((err = mp_reduce (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
 | 
				
			||||||
 | 
				
			|||||||
@ -24,19 +24,19 @@ s_mp_sqr (mp_int * a, mp_int * b)
 | 
				
			|||||||
  mp_digit u, tmpx, *tmpt;
 | 
					  mp_digit u, tmpx, *tmpt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pa = a->used;
 | 
					  pa = a->used;
 | 
				
			||||||
  if ((res = mp_init_size (&t, pa + pa + 1)) != MP_OKAY) {
 | 
					  if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  t.used = pa + pa + 1;
 | 
					  t.used = 2*pa + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (ix = 0; ix < pa; ix++) {
 | 
					  for (ix = 0; ix < pa; ix++) {
 | 
				
			||||||
    /* first calculate the digit at 2*ix */
 | 
					    /* first calculate the digit at 2*ix */
 | 
				
			||||||
    /* calculate double precision result */
 | 
					    /* calculate double precision result */
 | 
				
			||||||
    r = ((mp_word) t.dp[ix + ix]) + 
 | 
					    r = ((mp_word) t.dp[2*ix]) + 
 | 
				
			||||||
        ((mp_word) a->dp[ix]) * ((mp_word) a->dp[ix]);
 | 
					        ((mp_word) a->dp[ix]) * ((mp_word) a->dp[ix]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* store lower part in result */
 | 
					    /* store lower part in result */
 | 
				
			||||||
    t.dp[ix + ix] = (mp_digit) (r & ((mp_word) MP_MASK));
 | 
					    t.dp[2*ix] = (mp_digit) (r & ((mp_word) MP_MASK));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* get the carry */
 | 
					    /* get the carry */
 | 
				
			||||||
    u = (r >> ((mp_word) DIGIT_BIT));
 | 
					    u = (r >> ((mp_word) DIGIT_BIT));
 | 
				
			||||||
@ -45,14 +45,14 @@ s_mp_sqr (mp_int * a, mp_int * b)
 | 
				
			|||||||
    tmpx = a->dp[ix];
 | 
					    tmpx = a->dp[ix];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* alias for where to store the results */
 | 
					    /* alias for where to store the results */
 | 
				
			||||||
    tmpt = t.dp + (ix + ix + 1);
 | 
					    tmpt = t.dp + (2*ix + 1);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for (iy = ix + 1; iy < pa; iy++) {
 | 
					    for (iy = ix + 1; iy < pa; iy++) {
 | 
				
			||||||
      /* first calculate the product */
 | 
					      /* first calculate the product */
 | 
				
			||||||
      r = ((mp_word) tmpx) * ((mp_word) a->dp[iy]);
 | 
					      r = ((mp_word) tmpx) * ((mp_word) a->dp[iy]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /* now calculate the double precision result, note we use
 | 
					      /* now calculate the double precision result, note we use
 | 
				
			||||||
       * addition instead of *2 since its easier to optimize
 | 
					       * addition instead of *2 since it's easier to optimize
 | 
				
			||||||
       */
 | 
					       */
 | 
				
			||||||
      r = ((mp_word) * tmpt) + r + r + ((mp_word) u);
 | 
					      r = ((mp_word) * tmpt) + r + r + ((mp_word) u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,10 @@
 | 
				
			|||||||
 | 
					June 6th, 2003
 | 
				
			||||||
 | 
					v0.19  -- Fixed a bug in mp_montgomery_reduce() which was introduced when I tweaked mp_rshd() in the previous release.
 | 
				
			||||||
 | 
					          Essentially the digits were not trimmed before the compare which cause a subtraction to occur all the time.
 | 
				
			||||||
 | 
					       -- Fixed up etc/tune.c a bit to stop testing new cutoffs after 16 failures [to find more optimal points]. 
 | 
				
			||||||
 | 
					          Brute force ho!
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					
 | 
				
			||||||
May 29th, 2003
 | 
					May 29th, 2003
 | 
				
			||||||
v0.18  -- Fixed a bug in s_mp_sqr which would handle carries properly just not very elegantly.
 | 
					v0.18  -- Fixed a bug in s_mp_sqr which would handle carries properly just not very elegantly.
 | 
				
			||||||
          (e.g. correct result, just bad looking code)
 | 
					          (e.g. correct result, just bad looking code)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								etc/drprimes.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								etc/drprimes.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					224-bit prime:
 | 
				
			||||||
 | 
					p == 26959946667150639794667015087019630673637144422540572481103341844143
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					532-bit prime:
 | 
				
			||||||
 | 
					p == 14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368691747
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -57,7 +57,7 @@ is_mersenne (long s, int *pp)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* if u == 0 then its prime */
 | 
					  /* if u == 0 then its prime */
 | 
				
			||||||
  if (mp_iszero (&u) == 1) {
 | 
					  if (mp_iszero (&u) == 1) {
 | 
				
			||||||
    mp_prime_is_prime(&n, 3, pp);
 | 
					    mp_prime_is_prime(&n, 8, pp);
 | 
				
			||||||
  if (*pp != 1) printf("FAILURE\n");
 | 
					  if (*pp != 1) printf("FAILURE\n");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										47
									
								
								etc/tune.c
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								etc/tune.c
									
									
									
									
									
								
							@ -5,6 +5,12 @@
 | 
				
			|||||||
#include <tommath.h>
 | 
					#include <tommath.h>
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* how many times todo each size mult.  Depends on your computer.  For slow computers
 | 
				
			||||||
 | 
					 * this can be low like 5 or 10.  For fast [re: Athlon] should be 25 - 50 or so 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define TIMES 50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef X86_TIMER
 | 
					#ifndef X86_TIMER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* generic ISO C timer */
 | 
					/* generic ISO C timer */
 | 
				
			||||||
@ -31,7 +37,7 @@ time_mult (int max)
 | 
				
			|||||||
  for (x = 32; x <= max; x += 4) {
 | 
					  for (x = 32; x <= max; x += 4) {
 | 
				
			||||||
    mp_rand (&a, x);
 | 
					    mp_rand (&a, x);
 | 
				
			||||||
    mp_rand (&b, x);
 | 
					    mp_rand (&b, x);
 | 
				
			||||||
    for (y = 0; y < 100; y++) {
 | 
					    for (y = 0; y < TIMES; y++) {
 | 
				
			||||||
      mp_mul (&a, &b, &c);
 | 
					      mp_mul (&a, &b, &c);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -53,7 +59,7 @@ time_sqr (int max)
 | 
				
			|||||||
  t_start();
 | 
					  t_start();
 | 
				
			||||||
  for (x = 32; x <= max; x += 4) {
 | 
					  for (x = 32; x <= max; x += 4) {
 | 
				
			||||||
    mp_rand (&a, x);
 | 
					    mp_rand (&a, x);
 | 
				
			||||||
    for (y = 0; y < 100; y++) {
 | 
					    for (y = 0; y < TIMES; y++) {
 | 
				
			||||||
      mp_sqr (&a, &b);
 | 
					      mp_sqr (&a, &b);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -65,7 +71,7 @@ time_sqr (int max)
 | 
				
			|||||||
int
 | 
					int
 | 
				
			||||||
main (void)
 | 
					main (void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  int     best_kmult, best_tmult, best_ksquare, best_tsquare;
 | 
					  int     best_kmult, best_tmult, best_ksquare, best_tsquare, counter;
 | 
				
			||||||
  ulong64 best, ti;
 | 
					  ulong64 best, ti;
 | 
				
			||||||
  FILE   *log;
 | 
					  FILE   *log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -77,39 +83,52 @@ main (void)
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
  log = fopen ("mult.log", "w");
 | 
					  log = fopen ("mult.log", "w");
 | 
				
			||||||
  best = -1;
 | 
					  best = -1;
 | 
				
			||||||
 | 
					  counter = 16;
 | 
				
			||||||
  for (KARATSUBA_MUL_CUTOFF = 8; KARATSUBA_MUL_CUTOFF <= 200; KARATSUBA_MUL_CUTOFF++) {
 | 
					  for (KARATSUBA_MUL_CUTOFF = 8; KARATSUBA_MUL_CUTOFF <= 200; KARATSUBA_MUL_CUTOFF++) {
 | 
				
			||||||
    ti = time_mult (300);
 | 
					    ti = time_mult (300);
 | 
				
			||||||
    printf ("%4d : %9llu            \r", KARATSUBA_MUL_CUTOFF, ti);
 | 
					    printf ("%4d : %9llu            \r", KARATSUBA_MUL_CUTOFF, ti);
 | 
				
			||||||
    fprintf (log, "%d, %llu\n", KARATSUBA_MUL_CUTOFF, ti);
 | 
					    fprintf (log, "%d, %llu\n", KARATSUBA_MUL_CUTOFF, ti);
 | 
				
			||||||
    fflush (stdout);
 | 
					    fflush (stdout);
 | 
				
			||||||
    if (ti < best) {
 | 
					    if (ti < best) {
 | 
				
			||||||
      printf ("New best: %llu, %d         \n", ti, KARATSUBA_MUL_CUTOFF);
 | 
					      printf ("New best: %llu, %d         \r", ti, KARATSUBA_MUL_CUTOFF);
 | 
				
			||||||
      best = ti;
 | 
					      best = ti;
 | 
				
			||||||
      best_kmult = KARATSUBA_MUL_CUTOFF;
 | 
					      best_kmult = KARATSUBA_MUL_CUTOFF;
 | 
				
			||||||
 | 
					      counter = 16;
 | 
				
			||||||
 | 
					    } else if (--counter == 0) {
 | 
				
			||||||
 | 
					       printf("No better found in 16 trials.\n");
 | 
				
			||||||
 | 
					       break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  fclose (log);
 | 
					  fclose (log);
 | 
				
			||||||
 | 
					  printf("Karatsuba Multiplier Cutoff (KARATSUBA_MUL_CUTOFF) == %d\n", best_kmult);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  /* tune squaring */
 | 
					  /* tune squaring */
 | 
				
			||||||
  log = fopen ("sqr.log", "w");
 | 
					  log = fopen ("sqr.log", "w");
 | 
				
			||||||
  best = -1;
 | 
					  best = -1;
 | 
				
			||||||
 | 
					  counter = 16;
 | 
				
			||||||
  for (KARATSUBA_SQR_CUTOFF = 8; KARATSUBA_SQR_CUTOFF <= 200; KARATSUBA_SQR_CUTOFF++) {
 | 
					  for (KARATSUBA_SQR_CUTOFF = 8; KARATSUBA_SQR_CUTOFF <= 200; KARATSUBA_SQR_CUTOFF++) {
 | 
				
			||||||
    ti = time_sqr (300);
 | 
					    ti = time_sqr (300);
 | 
				
			||||||
    printf ("%4d : %9llu             \r", KARATSUBA_SQR_CUTOFF, ti);
 | 
					    printf ("%4d : %9llu             \r", KARATSUBA_SQR_CUTOFF, ti);
 | 
				
			||||||
    fprintf (log, "%d, %llu\n", KARATSUBA_SQR_CUTOFF, ti);
 | 
					    fprintf (log, "%d, %llu\n", KARATSUBA_SQR_CUTOFF, ti);
 | 
				
			||||||
    fflush (stdout);
 | 
					    fflush (stdout);
 | 
				
			||||||
    if (ti < best) {
 | 
					    if (ti < best) {
 | 
				
			||||||
      printf ("New best: %llu, %d         \n", ti, KARATSUBA_SQR_CUTOFF);
 | 
					      printf ("New best: %llu, %d         \r", ti, KARATSUBA_SQR_CUTOFF);
 | 
				
			||||||
      best = ti;
 | 
					      best = ti;
 | 
				
			||||||
      best_ksquare = KARATSUBA_SQR_CUTOFF;
 | 
					      best_ksquare = KARATSUBA_SQR_CUTOFF;
 | 
				
			||||||
 | 
					      counter = 16;
 | 
				
			||||||
 | 
					    } else if (--counter == 0) {
 | 
				
			||||||
 | 
					       printf("No better found in 16 trials.\n");
 | 
				
			||||||
 | 
					       break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  fclose (log);
 | 
					  fclose (log);
 | 
				
			||||||
 | 
					  printf("Karatsuba Squaring Cutoff (KARATSUBA_SQR_CUTOFF) == %d\n", best_ksquare);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  KARATSUBA_MUL_CUTOFF = best_kmult;
 | 
					  KARATSUBA_MUL_CUTOFF = best_kmult;
 | 
				
			||||||
  KARATSUBA_SQR_CUTOFF = best_ksquare;
 | 
					  KARATSUBA_SQR_CUTOFF = best_ksquare;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  /* tune TOOM mult */
 | 
					  /* tune TOOM mult */
 | 
				
			||||||
 | 
					  counter = 16;
 | 
				
			||||||
  log = fopen ("tmult.log", "w");
 | 
					  log = fopen ("tmult.log", "w");
 | 
				
			||||||
  best = -1;
 | 
					  best = -1;
 | 
				
			||||||
  for (TOOM_MUL_CUTOFF = best_kmult*5; TOOM_MUL_CUTOFF <= 800; TOOM_MUL_CUTOFF++) {
 | 
					  for (TOOM_MUL_CUTOFF = best_kmult*5; TOOM_MUL_CUTOFF <= 800; TOOM_MUL_CUTOFF++) {
 | 
				
			||||||
@ -118,32 +137,40 @@ main (void)
 | 
				
			|||||||
    fprintf (log, "%d, %llu\n", TOOM_MUL_CUTOFF, ti);
 | 
					    fprintf (log, "%d, %llu\n", TOOM_MUL_CUTOFF, ti);
 | 
				
			||||||
    fflush (stdout);
 | 
					    fflush (stdout);
 | 
				
			||||||
    if (ti < best) {
 | 
					    if (ti < best) {
 | 
				
			||||||
      printf ("New best: %llu, %d         \n", ti, TOOM_MUL_CUTOFF);
 | 
					      printf ("New best: %llu, %d         \r", ti, TOOM_MUL_CUTOFF);
 | 
				
			||||||
      best = ti;
 | 
					      best = ti;
 | 
				
			||||||
      best_tmult = TOOM_MUL_CUTOFF;
 | 
					      best_tmult = TOOM_MUL_CUTOFF;
 | 
				
			||||||
 | 
					      counter = 16;
 | 
				
			||||||
 | 
					    } else if (--counter == 0) {
 | 
				
			||||||
 | 
					       printf("No better found in 16 trials.\n");
 | 
				
			||||||
 | 
					       break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  fclose (log);   
 | 
					  fclose (log);   
 | 
				
			||||||
 | 
					  printf("Toom-Cook Multiplier Cutoff (TOOM_MUL_CUTOFF) == %d\n", best_tmult);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  /* tune TOOM sqr */
 | 
					  /* tune TOOM sqr */
 | 
				
			||||||
  log = fopen ("tsqr.log", "w");
 | 
					  log = fopen ("tsqr.log", "w");
 | 
				
			||||||
  best = -1;
 | 
					  best = -1;
 | 
				
			||||||
 | 
					  counter = 16;
 | 
				
			||||||
  for (TOOM_SQR_CUTOFF = best_ksquare*3; TOOM_SQR_CUTOFF <= 800; TOOM_SQR_CUTOFF++) {
 | 
					  for (TOOM_SQR_CUTOFF = best_ksquare*3; TOOM_SQR_CUTOFF <= 800; TOOM_SQR_CUTOFF++) {
 | 
				
			||||||
    ti = time_sqr (1200);
 | 
					    ti = time_sqr (1200);
 | 
				
			||||||
    printf ("%4d : %9llu           \r", TOOM_SQR_CUTOFF, ti);
 | 
					    printf ("%4d : %9llu           \r", TOOM_SQR_CUTOFF, ti);
 | 
				
			||||||
    fprintf (log, "%d, %llu\n", TOOM_SQR_CUTOFF, ti);
 | 
					    fprintf (log, "%d, %llu\n", TOOM_SQR_CUTOFF, ti);
 | 
				
			||||||
    fflush (stdout);
 | 
					    fflush (stdout);
 | 
				
			||||||
    if (ti < best) {
 | 
					    if (ti < best) {
 | 
				
			||||||
      printf ("New best: %llu, %d         \n", ti, TOOM_SQR_CUTOFF);
 | 
					      printf ("New best: %llu, %d         \r", ti, TOOM_SQR_CUTOFF);
 | 
				
			||||||
      best = ti;
 | 
					      best = ti;
 | 
				
			||||||
      best_tsquare = TOOM_SQR_CUTOFF;
 | 
					      best_tsquare = TOOM_SQR_CUTOFF;
 | 
				
			||||||
 | 
					      counter = 16;
 | 
				
			||||||
 | 
					    } else if (--counter == 0) {
 | 
				
			||||||
 | 
					       printf("No better found in 16 trials.\n");
 | 
				
			||||||
 | 
					       break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  fclose (log);   
 | 
					  fclose (log);   
 | 
				
			||||||
 | 
					  printf("Toom-Cook Squaring Cutoff (TOOM_SQR_CUTOFF) == %d\n", best_tsquare);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  printf
 | 
					 | 
				
			||||||
    ("\n\n\nKaratsuba Multiplier Cutoff: %d\nKaratsuba Squaring Cutoff: %d\nToom Multiplier Cutoff: %d\nToom Squaring Cutoff: %d\n",
 | 
					 | 
				
			||||||
     best_kmult, best_ksquare, best_tmult, best_tsquare);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								makefile
									
									
									
									
									
								
							@ -1,6 +1,6 @@
 | 
				
			|||||||
CFLAGS  +=  -I./ -Wall -W -Wshadow -O3 -fomit-frame-pointer -funroll-loops
 | 
					CFLAGS  +=  -I./ -Wall -W -Wshadow -O3 -fomit-frame-pointer -funroll-loops
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VERSION=0.18
 | 
					VERSION=0.19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
default: libtommath.a
 | 
					default: libtommath.a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -32,6 +32,6 @@ TARGET = libtommath.lib
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
$(TARGET): $(OBJECTS)
 | 
					$(TARGET): $(OBJECTS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.c.objbj:
 | 
					.c.obj:
 | 
				
			||||||
	$(CC) $(CFLAGS) $<
 | 
						$(CC) $(CFLAGS) $<
 | 
				
			||||||
	$(LIB) $(TARGET) -+$@
 | 
						$(LIB) $(TARGET) -+$@
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								poster.pdf
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								poster.pdf
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										12
									
								
								poster.tex
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								poster.tex
									
									
									
									
									
								
							@ -1,14 +1,15 @@
 | 
				
			|||||||
\documentclass[landscape,11pt]{article}
 | 
					\documentclass[landscape,11pt]{article}
 | 
				
			||||||
\usepackage{amsmath, amssymb}
 | 
					\usepackage{amsmath, amssymb}
 | 
				
			||||||
 | 
					\usepackage{hyperref}
 | 
				
			||||||
\begin{document}
 | 
					\begin{document}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
\hspace*{-3in}
 | 
					\hspace*{-3in}
 | 
				
			||||||
\begin{tabular}{llllll}
 | 
					\begin{tabular}{llllll}
 | 
				
			||||||
$c = a + b$  & {\tt mp\_add(\&a, \&b, \&c)} & $b = 2a$  & {\tt mp\_mul\_2(\&a, \&b)} & Greater Than & MP\_GT \\
 | 
					$c = a + b$  & {\tt mp\_add(\&a, \&b, \&c)} & $b = 2a$  & {\tt mp\_mul\_2(\&a, \&b)} & \\
 | 
				
			||||||
$c = a - b$  & {\tt mp\_sub(\&a, \&b, \&c)} & $b = a/2$ & {\tt mp\_div\_2(\&a, \&b)} & Equal To & MP\_EQ \\
 | 
					$c = a - b$  & {\tt mp\_sub(\&a, \&b, \&c)} & $b = a/2$ & {\tt mp\_div\_2(\&a, \&b)} & \\
 | 
				
			||||||
$c = ab $   & {\tt mp\_mul(\&a, \&b, \&c)}  & $c = 2^ba$  & {\tt mp\_mul\_2d(\&a, b, \&c)} & Less Than & MP\_LT \\
 | 
					$c = ab $   & {\tt mp\_mul(\&a, \&b, \&c)}  & $c = 2^ba$  & {\tt mp\_mul\_2d(\&a, b, \&c)}  \\
 | 
				
			||||||
$b = a^2 $  & {\tt mp\_sqr(\&a, \&b)}       & $c = a/2^b, d = a \mod 2^b$ & {\tt mp\_div\_2d(\&a, b, \&c, \&d)} \\
 | 
					$b = a^2 $  & {\tt mp\_sqr(\&a, \&b)}       & $c = a/2^b, d = a \mod 2^b$ & {\tt mp\_div\_2d(\&a, b, \&c, \&d)} \\
 | 
				
			||||||
$c = \lfloor a/b \rfloor, d = a \mod b$ & {\tt mp\_div(\&a, \&b, \&c, \&d)} & $c = a \mod 2^b $  & {\tt mp\_mod\_2d(\&a, b, \&c)}  & Bits per digit & DIGIT\_BIT \\
 | 
					$c = \lfloor a/b \rfloor, d = a \mod b$ & {\tt mp\_div(\&a, \&b, \&c, \&d)} & $c = a \mod 2^b $  & {\tt mp\_mod\_2d(\&a, b, \&c)}  \\
 | 
				
			||||||
 && \\
 | 
					 && \\
 | 
				
			||||||
$a = b $  & {\tt mp\_set\_int(\&a, b)}  & $c = a \vee b$  & {\tt mp\_or(\&a, \&b, \&c)}  \\
 | 
					$a = b $  & {\tt mp\_set\_int(\&a, b)}  & $c = a \vee b$  & {\tt mp\_or(\&a, \&b, \&c)}  \\
 | 
				
			||||||
$b = a $  & {\tt mp\_copy(\&a, \&b)} & $c = a \wedge b$  & {\tt mp\_and(\&a, \&b, \&c)}  \\
 | 
					$b = a $  & {\tt mp\_copy(\&a, \&b)} & $c = a \wedge b$  & {\tt mp\_and(\&a, \&b, \&c)}  \\
 | 
				
			||||||
@ -28,5 +29,8 @@ $a \leftarrow buf[0..len-1]$          & {\tt mp\_read\_unsigned\_bin(\&a, buf, l
 | 
				
			|||||||
&\\
 | 
					&\\
 | 
				
			||||||
$b = \sqrt{a}$ & {\tt mp\_sqrt(\&a, \&b)}  & $c = \mbox{gcd}(a, b)$ & {\tt mp\_gcd(\&a, \&b, \&c)} \\
 | 
					$b = \sqrt{a}$ & {\tt mp\_sqrt(\&a, \&b)}  & $c = \mbox{gcd}(a, b)$ & {\tt mp\_gcd(\&a, \&b, \&c)} \\
 | 
				
			||||||
$c = a^{1/b}$ & {\tt mp\_n\_root(\&a, b, \&c)} & $c = \mbox{lcm}(a, b)$ & {\tt mp\_lcm(\&a, \&b, \&c)} \\
 | 
					$c = a^{1/b}$ & {\tt mp\_n\_root(\&a, b, \&c)} & $c = \mbox{lcm}(a, b)$ & {\tt mp\_lcm(\&a, \&b, \&c)} \\
 | 
				
			||||||
 | 
					&\\
 | 
				
			||||||
 | 
					Greater Than & MP\_GT & Equal To & MP\_EQ \\
 | 
				
			||||||
 | 
					Less Than & MP\_LT & Bits per digit & DIGIT\_BIT \\
 | 
				
			||||||
\end{tabular}
 | 
					\end{tabular}
 | 
				
			||||||
\end{document}
 | 
					\end{document}
 | 
				
			||||||
@ -2060,8 +2060,8 @@ mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
 | 
				
			|||||||
     dr = mp_reduce_is_2k(P) << 1;
 | 
					     dr = mp_reduce_is_2k(P) << 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
  /* if the modulus is odd use the fast method */
 | 
					  /* if the modulus is odd or dr != 0 use the fast method */
 | 
				
			||||||
  if ((mp_isodd (P) == 1 || dr !=  0) && P->used > 4) {
 | 
					  if (mp_isodd (P) == 1 || dr !=  0) {
 | 
				
			||||||
    return mp_exptmod_fast (G, X, P, Y, dr);
 | 
					    return mp_exptmod_fast (G, X, P, Y, dr);
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    return s_mp_exptmod (G, X, P, Y);
 | 
					    return s_mp_exptmod (G, X, P, Y);
 | 
				
			||||||
@ -2155,6 +2155,7 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
 | 
				
			|||||||
     if (((P->used * 2 + 1) < MP_WARRAY) &&
 | 
					     if (((P->used * 2 + 1) < MP_WARRAY) &&
 | 
				
			||||||
          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
 | 
					          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
 | 
				
			||||||
        redux = fast_mp_montgomery_reduce;
 | 
					        redux = fast_mp_montgomery_reduce;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     } else {
 | 
					     } else {
 | 
				
			||||||
        /* use slower baselien method */
 | 
					        /* use slower baselien method */
 | 
				
			||||||
        redux = mp_montgomery_reduce;
 | 
					        redux = mp_montgomery_reduce;
 | 
				
			||||||
@ -2964,6 +2965,7 @@ mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
 | 
				
			|||||||
  mp_int  x0, x1, y0, y1, t1, x0y0, x1y1;
 | 
					  mp_int  x0, x1, y0, y1, t1, x0y0, x1y1;
 | 
				
			||||||
  int     B, err;
 | 
					  int     B, err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* default the return code to an error */
 | 
				
			||||||
  err = MP_MEM;
 | 
					  err = MP_MEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* min # of digits */
 | 
					  /* min # of digits */
 | 
				
			||||||
@ -3064,6 +3066,7 @@ mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
 | 
				
			|||||||
  if (mp_add (&t1, &x1y1, c) != MP_OKAY)
 | 
					  if (mp_add (&t1, &x1y1, c) != MP_OKAY)
 | 
				
			||||||
    goto X1Y1;          /* t1 = x0y0 + t1 + x1y1 */
 | 
					    goto X1Y1;          /* t1 = x0y0 + t1 + x1y1 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Algorithm succeeded set the return code to MP_OKAY */
 | 
				
			||||||
  err = MP_OKAY;
 | 
					  err = MP_OKAY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
X1Y1:mp_clear (&x1y1);
 | 
					X1Y1:mp_clear (&x1y1);
 | 
				
			||||||
@ -3581,6 +3584,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* x = x/b**n.used */
 | 
					  /* x = x/b**n.used */
 | 
				
			||||||
 | 
					  mp_clamp(x);
 | 
				
			||||||
  mp_rshd (x, n->used);
 | 
					  mp_rshd (x, n->used);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* if A >= m then A = A - m */
 | 
					  /* if A >= m then A = A - m */
 | 
				
			||||||
@ -4969,7 +4973,8 @@ mp_reduce_is_2k(mp_int *a)
 | 
				
			|||||||
   } else if (a->used > 1) {
 | 
					   } else if (a->used > 1) {
 | 
				
			||||||
      iy = mp_count_bits(a);
 | 
					      iy = mp_count_bits(a);
 | 
				
			||||||
      for (ix = DIGIT_BIT; ix < iy; ix++) {
 | 
					      for (ix = DIGIT_BIT; ix < iy; ix++) {
 | 
				
			||||||
          if ((a->dp[ix/DIGIT_BIT] & ((mp_digit)1 << (mp_digit)(ix % DIGIT_BIT))) == 0) {
 | 
					          if ((a->dp[ix/DIGIT_BIT] & 
 | 
				
			||||||
 | 
					              ((mp_digit)1 << (mp_digit)(ix % DIGIT_BIT))) == 0) {
 | 
				
			||||||
             return 0;
 | 
					             return 0;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -5543,7 +5548,7 @@ mp_to_unsigned_bin (mp_int * a, unsigned char *b)
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
#include <tommath.h>
 | 
					#include <tommath.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* multiplication using Toom-Cook 3-way algorithm */
 | 
					/* multiplication using the Toom-Cook 3-way algorithm */
 | 
				
			||||||
int 
 | 
					int 
 | 
				
			||||||
mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
					mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -5551,14 +5556,16 @@ mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			|||||||
    int res, B;
 | 
					    int res, B;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    /* init temps */
 | 
					    /* init temps */
 | 
				
			||||||
    if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &b0, &b1, &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
 | 
					    if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, 
 | 
				
			||||||
 | 
					                             &a0, &a1, &a2, &b0, &b1, 
 | 
				
			||||||
 | 
					                             &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
 | 
				
			||||||
       return res;
 | 
					       return res;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* B */
 | 
					    /* B */
 | 
				
			||||||
    B = MIN(a->used, b->used) / 3;
 | 
					    B = MIN(a->used, b->used) / 3;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* a = a2 * B^2 + a1 * B + a0 */
 | 
					    /* a = a2 * B**2 + a1 * B + a0 */
 | 
				
			||||||
    if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
 | 
					    if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
 | 
				
			||||||
       goto ERR;
 | 
					       goto ERR;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -5574,7 +5581,7 @@ mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    mp_rshd(&a2, B*2);
 | 
					    mp_rshd(&a2, B*2);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /* b = b2 * B^2 + b1 * B + b0 */
 | 
					    /* b = b2 * B**2 + b1 * B + b0 */
 | 
				
			||||||
    if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
 | 
					    if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
 | 
				
			||||||
       goto ERR;
 | 
					       goto ERR;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -5688,7 +5695,8 @@ mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			|||||||
       16 8  4  2  1
 | 
					       16 8  4  2  1
 | 
				
			||||||
       1  0  0  0  0
 | 
					       1  0  0  0  0
 | 
				
			||||||
       
 | 
					       
 | 
				
			||||||
       using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication 
 | 
					       using 12 subtractions, 4 shifts, 
 | 
				
			||||||
 | 
					              2 small divisions and 1 small multiplication 
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
     /* r1 - r4 */
 | 
					     /* r1 - r4 */
 | 
				
			||||||
@ -5791,7 +5799,9 @@ mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
 | 
				
			|||||||
     }     
 | 
					     }     
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
ERR:
 | 
					ERR:
 | 
				
			||||||
     mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &b0, &b1, &b2, &tmp1, &tmp2, NULL);
 | 
					     mp_clear_multi(&w0, &w1, &w2, &w3, &w4, 
 | 
				
			||||||
 | 
					                    &a0, &a1, &a2, &b0, &b1, 
 | 
				
			||||||
 | 
					                    &b2, &tmp1, &tmp2, NULL);
 | 
				
			||||||
     return res;
 | 
					     return res;
 | 
				
			||||||
}     
 | 
					}     
 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
@ -6267,6 +6277,14 @@ mp_toradix (mp_int * a, char *str, int radix)
 | 
				
			|||||||
    return MP_VAL;
 | 
					    return MP_VAL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
 | 
					  /* quick out if its zero */
 | 
				
			||||||
 | 
					  if (mp_iszero(a) == 1) {
 | 
				
			||||||
 | 
					     *str++ = '0';
 | 
				
			||||||
 | 
					     *str = '\0';
 | 
				
			||||||
 | 
					     return MP_OKAY;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
 | 
					  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -6624,21 +6642,26 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  /* create M table
 | 
					  /* create M table
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   * The M table contains powers of the input base, e.g. M[x] = G**x mod P
 | 
					   * The M table contains powers of the base, 
 | 
				
			||||||
 | 
					   * e.g. M[x] = G**x mod P
 | 
				
			||||||
   *
 | 
					   *
 | 
				
			||||||
   * The first half of the table is not computed though accept for M[0] and M[1]
 | 
					   * The first half of the table is not 
 | 
				
			||||||
 | 
					   * computed though accept for M[0] and M[1]
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
 | 
					  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
 | 
				
			||||||
    goto __MU;
 | 
					    goto __MU;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
 | 
					  /* compute the value at M[1<<(winsize-1)] by squaring 
 | 
				
			||||||
 | 
					   * M[1] (winsize-1) times 
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
 | 
					  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
 | 
				
			||||||
    goto __MU;
 | 
					    goto __MU;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (x = 0; x < (winsize - 1); x++) {
 | 
					  for (x = 0; x < (winsize - 1); x++) {
 | 
				
			||||||
    if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
 | 
					    if ((err = mp_sqr (&M[1 << (winsize - 1)], 
 | 
				
			||||||
 | 
					                       &M[1 << (winsize - 1)])) != MP_OKAY) {
 | 
				
			||||||
      goto __MU;
 | 
					      goto __MU;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if ((err = mp_reduce (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
 | 
					    if ((err = mp_reduce (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
 | 
				
			||||||
@ -6966,19 +6989,19 @@ s_mp_sqr (mp_int * a, mp_int * b)
 | 
				
			|||||||
  mp_digit u, tmpx, *tmpt;
 | 
					  mp_digit u, tmpx, *tmpt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  pa = a->used;
 | 
					  pa = a->used;
 | 
				
			||||||
  if ((res = mp_init_size (&t, pa + pa + 1)) != MP_OKAY) {
 | 
					  if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  t.used = pa + pa + 1;
 | 
					  t.used = 2*pa + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (ix = 0; ix < pa; ix++) {
 | 
					  for (ix = 0; ix < pa; ix++) {
 | 
				
			||||||
    /* first calculate the digit at 2*ix */
 | 
					    /* first calculate the digit at 2*ix */
 | 
				
			||||||
    /* calculate double precision result */
 | 
					    /* calculate double precision result */
 | 
				
			||||||
    r = ((mp_word) t.dp[ix + ix]) + 
 | 
					    r = ((mp_word) t.dp[2*ix]) + 
 | 
				
			||||||
        ((mp_word) a->dp[ix]) * ((mp_word) a->dp[ix]);
 | 
					        ((mp_word) a->dp[ix]) * ((mp_word) a->dp[ix]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* store lower part in result */
 | 
					    /* store lower part in result */
 | 
				
			||||||
    t.dp[ix + ix] = (mp_digit) (r & ((mp_word) MP_MASK));
 | 
					    t.dp[2*ix] = (mp_digit) (r & ((mp_word) MP_MASK));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* get the carry */
 | 
					    /* get the carry */
 | 
				
			||||||
    u = (r >> ((mp_word) DIGIT_BIT));
 | 
					    u = (r >> ((mp_word) DIGIT_BIT));
 | 
				
			||||||
@ -6987,14 +7010,14 @@ s_mp_sqr (mp_int * a, mp_int * b)
 | 
				
			|||||||
    tmpx = a->dp[ix];
 | 
					    tmpx = a->dp[ix];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* alias for where to store the results */
 | 
					    /* alias for where to store the results */
 | 
				
			||||||
    tmpt = t.dp + (ix + ix + 1);
 | 
					    tmpt = t.dp + (2*ix + 1);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for (iy = ix + 1; iy < pa; iy++) {
 | 
					    for (iy = ix + 1; iy < pa; iy++) {
 | 
				
			||||||
      /* first calculate the product */
 | 
					      /* first calculate the product */
 | 
				
			||||||
      r = ((mp_word) tmpx) * ((mp_word) a->dp[iy]);
 | 
					      r = ((mp_word) tmpx) * ((mp_word) a->dp[iy]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /* now calculate the double precision result, note we use
 | 
					      /* now calculate the double precision result, note we use
 | 
				
			||||||
       * addition instead of *2 since its easier to optimize
 | 
					       * addition instead of *2 since it's easier to optimize
 | 
				
			||||||
       */
 | 
					       */
 | 
				
			||||||
      r = ((mp_word) * tmpt) + r + r + ((mp_word) u);
 | 
					      r = ((mp_word) * tmpt) + r + r + ((mp_word) u);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										143
									
								
								tommath.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								tommath.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,143 @@
 | 
				
			|||||||
 | 
					\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}{Multiple Precision Arithmetic}{section.1.1}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.1.1.3}{Benefits of Multiple Precision Arithmetic}{section.1.1}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.1.1.4}{Basis of Operations}{section.1.1}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.1.2}{Purpose of This Text}{chapter.1}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.1.3}{Discussion and Notation}{chapter.1}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.1.3.1}{Notation}{section.1.3}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.1.3.2}{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}{Other Initialization Routines}{chapter.3}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.3.6.1}{Initializing Variable Sized mp\137int Structures}{section.3.6}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.3.6.2}{Creating a Clone}{section.3.6}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.3.6.3}{Multiple Integer Initializations And Clearings}{section.3.6}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.3.7}{Maintenance}{chapter.3}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.3.7.1}{Augmenting Integer Precision}{section.3.7}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.3.7.2}{Clamping Excess Digits}{section.3.7}
 | 
				
			||||||
 | 
					\BOOKMARK [0][-]{chapter.4}{Basic Operations}{}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.4.1}{Copying an Integer}{chapter.4}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.4.2}{Zeroing an Integer}{chapter.4}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.4.3}{Sign Manipulation}{chapter.4}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.4.3.1}{Absolute Value}{section.4.3}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.4.3.2}{Integer Negation}{section.4.3}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.4.4}{Small Constants}{chapter.4}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.4.4.1}{Setting Small Constants}{section.4.4}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.4.4.2}{Setting Large Constants}{section.4.4}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.4.5}{Comparisons}{chapter.4}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.4.5.1}{Unsigned Comparisions}{section.4.5}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.4.5.2}{Signed Comparisons}{section.4.5}
 | 
				
			||||||
 | 
					\BOOKMARK [0][-]{chapter.5}{Basic Arithmetic}{}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.5.1}{Building Blocks}{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 [1][-]{section.9.2}{Single Digit Helpers}{chapter.9}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.2.1}{Single Digit Addition}{section.9.2}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.2.2}{Single Digit Subtraction}{section.9.2}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.2.3}{Single Digit Multiplication}{section.9.2}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.2.4}{Single Digit Division}{section.9.2}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.2.5}{Single Digit Modulo}{section.9.2}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.2.6}{Single Digit Root Extraction}{section.9.2}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.9.3}{Random Number Generation}{chapter.9}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.9.4}{Formatted Output}{chapter.9}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.4.1}{Getting The Output Size}{section.9.4}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.4.2}{Generating Radix-n Output}{section.9.4}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.4.3}{Reading Radix-n Input}{section.9.4}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.9.5}{Unformatted Output}{chapter.9}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.5.1}{Getting The Output Size}{section.9.5}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.5.2}{Generating Output}{section.9.5}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.9.5.3}{Reading Input}{section.9.5}
 | 
				
			||||||
 | 
					\BOOKMARK [0][-]{chapter.10}{Number Theoretic Algorithms}{}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.10.1}{Greatest Common Divisor}{chapter.10}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.10.2}{Least Common Multiple}{chapter.10}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.10.3}{Jacobi Symbol Computation}{chapter.10}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.10.4}{Modular Inverse}{chapter.10}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.10.4.1}{General Case}{section.10.4}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.10.4.2}{Odd Moduli}{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 [2][-]{subsection.10.5.4}{Primality Test in a Bottle}{section.10.5}
 | 
				
			||||||
 | 
					\BOOKMARK [2][-]{subsection.10.5.5}{The Next Prime}{section.10.5}
 | 
				
			||||||
 | 
					\BOOKMARK [1][-]{section.10.6}{Root Extraction}{chapter.10}
 | 
				
			||||||
 | 
					\BOOKMARK [0][-]{appendix*.16}{Appendix}{}
 | 
				
			||||||
							
								
								
									
										938
									
								
								tommath.src
									
									
									
									
									
								
							
							
						
						
									
										938
									
								
								tommath.src
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1778
									
								
								tommath.tex
									
									
									
									
									
								
							
							
						
						
									
										1778
									
								
								tommath.tex
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user