Permalink
Browse files

added libtommath-0.23

  • Loading branch information...
1 parent 4c1d3f0 commit eed6765fe99a3e239152ae58fb7435be6221cc15 Tom St Denis committed with sjaeckel Jul 12, 2003
View
Binary file not shown.
View
@@ -1,7 +1,7 @@
\documentclass[]{article}
\begin{document}
-\title{LibTomMath v0.22 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
+\title{LibTomMath v0.23 \\ A Free Multiple Precision Integer Library \\ http://math.libtomcrypt.org }
\author{Tom St Denis \\ tomstdenis@iahu.ca}
\maketitle
\newpage
@@ -64,7 +64,7 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
* that W[ix-1] have the carry cleared (see after the inner loop)
*/
register mp_digit mu;
- mu = (((mp_digit) (W[ix] & MP_MASK)) * rho) & MP_MASK;
+ mu = ((W[ix] & MP_MASK) * rho) & MP_MASK;
/* a = a + mu * m * b**i
*
@@ -93,15 +93,14 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
/* inner loop */
for (iy = 0; iy < n->used; iy++) {
- *_W++ += ((mp_word) mu) * ((mp_word) * tmpn++);
+ *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
}
}
/* now fix carry for next digit, W[ix+1] */
W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
}
-
{
register mp_digit *tmpx;
register mp_word *_W, *_W1;
@@ -81,7 +81,7 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
pb = MIN (b->used, digs - ix);
for (iy = 0; iy < pb; iy++) {
- *_W++ += ((mp_word) tmpx) * ((mp_word) * tmpy++);
+ *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++);
}
}
@@ -104,20 +104,27 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
* from N*(N+N*c)==N**2 + c*N**2 to N**2 + N*c where c is the
* cost of the shifting. On very small numbers this is slower
* but on most cryptographic size numbers it is faster.
+ *
+ * In this particular implementation we feed the carries from
+ * behind which means when the loop terminates we still have one
+ * last digit to copy
*/
tmpc = c->dp;
for (ix = 1; ix < digs; ix++) {
+ /* forward the carry from the previous temp */
W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT));
+
+ /* now extract the previous digit [below the carry] */
*tmpc++ = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK));
}
+ /* fetch the last digit */
*tmpc++ = (mp_digit) (W[digs - 1] & ((mp_word) MP_MASK));
- /* clear unused */
+ /* clear unused digits [that existed in the old copy of c] */
for (; ix < olduse; ix++) {
*tmpc++ = 0;
}
}
-
mp_clamp (c);
return MP_OKAY;
}
@@ -71,7 +71,7 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
/* compute column products for digits above the minimum */
for (; iy < pb; iy++) {
- *_W++ += ((mp_word) tmpx) * ((mp_word) * tmpy++);
+ *_W++ += ((mp_word) tmpx) * ((mp_word)*tmpy++);
}
}
}
@@ -80,12 +80,15 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
oldused = c->used;
c->used = newused;
- /* now convert the array W downto what we need */
+ /* now convert the array W downto what we need
+ *
+ * See comments in bn_fast_s_mp_mul_digs.c
+ */
for (ix = digs + 1; ix < newused; ix++) {
W[ix] += (W[ix - 1] >> ((mp_word) DIGIT_BIT));
c->dp[ix - 1] = (mp_digit) (W[ix - 1] & ((mp_word) MP_MASK));
}
- c->dp[(pa + pb + 1) - 1] = (mp_digit) (W[(pa + pb + 1) - 1] & ((mp_word) MP_MASK));
+ c->dp[newused - 1] = (mp_digit) (W[newused - 1] & ((mp_word) MP_MASK));
for (; ix < oldused; ix++) {
c->dp[ix] = 0;
View
@@ -68,7 +68,7 @@ fast_s_mp_sqr (mp_int * a, mp_int * b)
* for a particular column only once which means that
* there is no need todo a double precision addition
*/
- W2[ix + ix] = ((mp_word) a->dp[ix]) * ((mp_word) a->dp[ix]);
+ W2[ix + ix] = ((mp_word)a->dp[ix]) * ((mp_word)a->dp[ix]);
{
register mp_digit tmpx, *tmpy;
@@ -86,7 +86,7 @@ fast_s_mp_sqr (mp_int * a, mp_int * b)
/* inner products */
for (iy = ix + 1; iy < pa; iy++) {
- *_W++ += ((mp_word) tmpx) * ((mp_word) * tmpy++);
+ *_W++ += ((mp_word)tmpx) * ((mp_word)*tmpy++);
}
}
}
View
@@ -19,15 +19,14 @@ void
mp_clear (mp_int * a)
{
if (a->dp != NULL) {
-
/* first zero the digits */
memset (a->dp, 0, sizeof (mp_digit) * a->used);
/* free ram */
free (a->dp);
/* reset members to make debugging easier */
- a->dp = NULL;
+ a->dp = NULL;
a->alloc = a->used = 0;
}
}
View
@@ -14,6 +14,19 @@
*/
#include <tommath.h>
+static int s_is_power_of_two(mp_digit b, int *p)
+{
+ int x;
+
+ for (x = 1; x < DIGIT_BIT; x++) {
+ if (b == (((mp_digit)1)<<x)) {
+ *p = x;
+ return 1;
+ }
+ }
+ return 0;
+}
+
/* single digit division (based on routine from MPI) */
int
mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
@@ -22,15 +35,40 @@ mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
mp_word w;
mp_digit t;
int res, ix;
-
+
+ /* cannot divide by zero */
if (b == 0) {
return MP_VAL;
}
-
+
+ /* quick outs */
+ if (b == 1 || mp_iszero(a) == 1) {
+ if (d != NULL) {
+ *d = 0;
+ }
+ if (c != NULL) {
+ return mp_copy(a, c);
+ }
+ return MP_OKAY;
+ }
+
+ /* power of two ? */
+ if (s_is_power_of_two(b, &ix) == 1) {
+ if (d != NULL) {
+ *d = a->dp[0] & ((1<<ix) - 1);
+ }
+ if (c != NULL) {
+ return mp_div_2d(a, ix, c, NULL);
+ }
+ return MP_OKAY;
+ }
+
+ /* three? */
if (b == 3) {
return mp_div_3(a, c, d);
}
-
+
+ /* no easy answer [c'est la vie]. Just division */
if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
return res;
}
@@ -82,7 +82,6 @@ mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
}
}
-
/* determine and setup reduction code */
if (redmode == 0) {
/* now setup montgomery */
@@ -44,7 +44,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
for (ix = 0; ix < n->used; ix++) {
/* mu = ai * m' mod b */
- mu = (x->dp[ix] * rho) & MP_MASK;
+ mu = ((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK;
/* a = a + mu * m * b**i */
{
@@ -61,7 +61,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
/* Multiply and add in place */
for (iy = 0; iy < n->used; iy++) {
- r = ((mp_word) mu) * ((mp_word) * tmpn++) +
+ r = ((mp_word)mu) * ((mp_word)*tmpn++) +
((mp_word) u) + ((mp_word) * tmpx);
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
*tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
View
@@ -50,7 +50,7 @@ mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
u = 0;
for (ix = 0; ix < pa; ix++) {
/* compute product and carry sum for this term */
- r = ((mp_word) u) + ((mp_word) * tmpa++) * ((mp_word) b);
+ r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
/* mask off higher bits to get a single digit */
*tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
@@ -31,6 +31,11 @@ mp_prime_fermat (mp_int * a, mp_int * b, int *result)
/* default to fail */
*result = 0;
+ /* ensure b > 1 */
+ if (mp_cmp_d(b, 1) != MP_GT) {
+ return MP_VAL;
+ }
+
/* init t */
if ((err = mp_init (&t)) != MP_OKAY) {
return err;
@@ -17,7 +17,7 @@
/* performs a variable number of rounds of Miller-Rabin
*
* Probability of error after t rounds is no more than
- * (1/4)^t when 1 <= t <= 256
+ * (1/4)^t when 1 <= t <= PRIME_SIZE
*
* Sets result to 1 if probably prime, 0 otherwise
*/
@@ -31,7 +31,7 @@ mp_prime_is_prime (mp_int * a, int t, int *result)
*result = 0;
/* valid value of t? */
- if (t < 1 || t > PRIME_SIZE) {
+ if (t <= 0 || t > PRIME_SIZE) {
return MP_VAL;
}
@@ -47,6 +47,8 @@ mp_prime_is_prime (mp_int * a, int t, int *result)
if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
return err;
}
+
+ /* return if it was trivially divisible */
if (res == 1) {
return MP_OKAY;
}
@@ -30,6 +30,11 @@ mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
/* default */
*result = 0;
+ /* ensure b > 1 */
+ if (mp_cmp_d(b, 1) != MP_GT) {
+ return MP_VAL;
+ }
+
/* get n1 = a - 1 */
if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
return err;
@@ -42,8 +47,13 @@ mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
goto __N1;
}
-
+
+ /* count the number of least significant bits
+ * which are zero
+ */
s = mp_cnt_lsb(&r);
+
+ /* now divide n - 1 by 2^s */
if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
goto __R;
}
Oops, something went wrong.

0 comments on commit eed6765

Please sign in to comment.