added libtommath-0.28
This commit is contained in:
parent
c343371bb2
commit
455bb4db20
6
bn.ilg
Normal file
6
bn.ilg
Normal file
@ -0,0 +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).
|
||||
Output written in bn.ind.
|
||||
Transcript written in bn.ilg.
|
56
bn.ind
Normal file
56
bn.ind
Normal file
@ -0,0 +1,56 @@
|
||||
\begin{theindex}
|
||||
|
||||
\item mp\_add, \hyperpage{23}
|
||||
\item mp\_and, \hyperpage{23}
|
||||
\item mp\_clear, \hyperpage{7}
|
||||
\item mp\_clear\_multi, \hyperpage{8}
|
||||
\item mp\_cmp, \hyperpage{18}
|
||||
\item mp\_cmp\_d, \hyperpage{20}
|
||||
\item mp\_cmp\_mag, \hyperpage{17}
|
||||
\item mp\_div, \hyperpage{29}
|
||||
\item mp\_div\_2, \hyperpage{21}
|
||||
\item mp\_div\_2d, \hyperpage{22}
|
||||
\item MP\_EQ, \hyperpage{17}
|
||||
\item mp\_error\_to\_string, \hyperpage{6}
|
||||
\item mp\_expt\_d, \hyperpage{31}
|
||||
\item mp\_exptmod, \hyperpage{31}
|
||||
\item mp\_gcd, \hyperpage{39}
|
||||
\item mp\_grow, \hyperpage{12}
|
||||
\item MP\_GT, \hyperpage{17}
|
||||
\item mp\_init, \hyperpage{7}
|
||||
\item mp\_init\_copy, \hyperpage{9}
|
||||
\item mp\_init\_multi, \hyperpage{8}
|
||||
\item mp\_init\_size, \hyperpage{10}
|
||||
\item mp\_int, \hyperpage{6}
|
||||
\item mp\_invmod, \hyperpage{40}
|
||||
\item mp\_jacobi, \hyperpage{39}
|
||||
\item mp\_lcm, \hyperpage{39}
|
||||
\item mp\_lshd, \hyperpage{23}
|
||||
\item MP\_LT, \hyperpage{17}
|
||||
\item MP\_MEM, \hyperpage{5}
|
||||
\item mp\_mul, \hyperpage{25}
|
||||
\item mp\_mul\_2, \hyperpage{21}
|
||||
\item mp\_mul\_2d, \hyperpage{22}
|
||||
\item mp\_n\_root, \hyperpage{31}
|
||||
\item mp\_neg, \hyperpage{24}
|
||||
\item MP\_NO, \hyperpage{5}
|
||||
\item MP\_OKAY, \hyperpage{5}
|
||||
\item mp\_or, \hyperpage{23}
|
||||
\item mp\_prime\_fermat, \hyperpage{33}
|
||||
\item mp\_prime\_is\_divisible, \hyperpage{33}
|
||||
\item mp\_prime\_is\_prime, \hyperpage{34}
|
||||
\item mp\_prime\_miller\_rabin, \hyperpage{33}
|
||||
\item mp\_prime\_next\_prime, \hyperpage{34}
|
||||
\item mp\_prime\_rabin\_miller\_trials, \hyperpage{34}
|
||||
\item mp\_prime\_random, \hyperpage{35}
|
||||
\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\_VAL, \hyperpage{5}
|
||||
\item mp\_xor, \hyperpage{23}
|
||||
\item MP\_YES, \hyperpage{5}
|
||||
|
||||
\end{theindex}
|
@ -26,11 +26,8 @@ fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
||||
mp_int x, y, u, v, B, D;
|
||||
int res, neg;
|
||||
|
||||
/* 2. [modified] if a,b are both even then return an error!
|
||||
*
|
||||
* That is if gcd(a,b) = 2**k * q then obviously there is no inverse.
|
||||
*/
|
||||
if (mp_iseven (a) == 1 && mp_iseven (b) == 1) {
|
||||
/* 2. [modified] b must be odd */
|
||||
if (mp_iseven (b) == 1) {
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
|
@ -14,11 +14,11 @@
|
||||
*/
|
||||
#include <tommath.h>
|
||||
|
||||
/* computes xR**-1 == x (mod N) via Montgomery Reduction
|
||||
*
|
||||
* This is an optimized implementation of mp_montgomery_reduce
|
||||
/* computes xR**-1 == x (mod N) via Montgomery Reduction
|
||||
*
|
||||
* This is an optimized implementation of mp_montgomery_reduce
|
||||
* which uses the comba method to quickly calculate the columns of the
|
||||
* reduction.
|
||||
* reduction.
|
||||
*
|
||||
* Based on Algorithm 14.32 on pp.601 of HAC.
|
||||
*/
|
||||
@ -69,11 +69,11 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
/* mu = ai * m' mod b
|
||||
*
|
||||
* We avoid a double precision multiplication (which isn't required)
|
||||
* by casting the value down to a mp_digit. Note this requires
|
||||
* by casting the value down to a mp_digit. Note this requires
|
||||
* that W[ix-1] have the carry cleared (see after the inner loop)
|
||||
*/
|
||||
register mp_digit mu;
|
||||
mu = ((W[ix] & MP_MASK) * rho) & MP_MASK;
|
||||
mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
|
||||
|
||||
/* a = a + mu * m * b**i
|
||||
*
|
||||
@ -81,12 +81,12 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
* by b**i is handled by offseting which columns the results
|
||||
* are added to.
|
||||
*
|
||||
* Note the comba method normally doesn't handle carries in the
|
||||
* inner loop In this case we fix the carry from the previous
|
||||
* column since the Montgomery reduction requires digits of the
|
||||
* Note the comba method normally doesn't handle carries in the
|
||||
* inner loop In this case we fix the carry from the previous
|
||||
* column since the Montgomery reduction requires digits of the
|
||||
* result (so far) [see above] to work. This is
|
||||
* handled by fixing up one carry after the inner loop. The
|
||||
* carry fixups are done in order so after these loops the
|
||||
* handled by fixing up one carry after the inner loop. The
|
||||
* carry fixups are done in order so after these loops the
|
||||
* first m->used words of W[] have the carries fixed
|
||||
*/
|
||||
{
|
||||
@ -132,8 +132,8 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
|
||||
/* copy out, A = A/b**n
|
||||
*
|
||||
* The result is A/b**n but instead of converting from an
|
||||
* array of mp_word to mp_digit than calling mp_rshd
|
||||
* The result is A/b**n but instead of converting from an
|
||||
* array of mp_word to mp_digit than calling mp_rshd
|
||||
* we just copy them in the right order
|
||||
*/
|
||||
|
||||
|
@ -16,16 +16,16 @@
|
||||
|
||||
/* fast squaring
|
||||
*
|
||||
* This is the comba method where the columns of the product
|
||||
* are computed first then the carries are computed. This
|
||||
* has the effect of making a very simple inner loop that
|
||||
* This is the comba method where the columns of the product
|
||||
* are computed first then the carries are computed. This
|
||||
* has the effect of making a very simple inner loop that
|
||||
* is executed the most
|
||||
*
|
||||
* W2 represents the outer products and W the inner.
|
||||
*
|
||||
* A further optimizations is made because the inner
|
||||
* products are of the form "A * B * 2". The *2 part does
|
||||
* not need to be computed until the end which is good
|
||||
* A further optimizations is made because the inner
|
||||
* products are of the form "A * B * 2". The *2 part does
|
||||
* not need to be computed until the end which is good
|
||||
* because 64-bit shifts are slow!
|
||||
*
|
||||
* Based on Algorithm 14.16 on pp.597 of HAC.
|
||||
@ -105,8 +105,8 @@ fast_s_mp_sqr (mp_int * a, mp_int * b)
|
||||
{
|
||||
register mp_digit *tmpb;
|
||||
|
||||
/* double first value, since the inner products are
|
||||
* half of what they should be
|
||||
/* double first value, since the inner products are
|
||||
* half of what they should be
|
||||
*/
|
||||
W[0] += W[0] + W2[0];
|
||||
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* high level addition (handles signs) */
|
||||
int
|
||||
mp_add (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_add (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
int sa, sb, res;
|
||||
|
||||
|
@ -24,7 +24,7 @@ mp_clear (mp_int * a)
|
||||
memset (a->dp, 0, sizeof (mp_digit) * a->used);
|
||||
|
||||
/* free ram */
|
||||
free (a->dp);
|
||||
XFREE(a->dp);
|
||||
|
||||
/* reset members to make debugging easier */
|
||||
a->dp = NULL;
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* compare a digit */
|
||||
int
|
||||
mp_cmp_d (mp_int * a, mp_digit b)
|
||||
int mp_cmp_d(mp_int * a, mp_digit b)
|
||||
{
|
||||
/* compare based on sign */
|
||||
if (a->sign == MP_NEG) {
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* compare maginitude of two ints (unsigned) */
|
||||
int
|
||||
mp_cmp_mag (mp_int * a, mp_int * b)
|
||||
int mp_cmp_mag (mp_int * a, mp_int * b)
|
||||
{
|
||||
int n;
|
||||
mp_digit *tmpa, *tmpb;
|
||||
|
@ -27,8 +27,7 @@
|
||||
* The overall algorithm is as described as
|
||||
* 14.20 from HAC but fixed to treat these cases.
|
||||
*/
|
||||
int
|
||||
mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
||||
int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
||||
{
|
||||
mp_int q, x, y, t1, t2;
|
||||
int res, n, t, i, norm, neg;
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* b = a/2 */
|
||||
int
|
||||
mp_div_2 (mp_int * a, mp_int * b)
|
||||
int mp_div_2(mp_int * a, mp_int * b)
|
||||
{
|
||||
int x, res, oldused;
|
||||
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* shift right by a certain bit count (store quotient in c, optional remainder in d) */
|
||||
int
|
||||
mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
|
||||
int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
|
||||
{
|
||||
mp_digit D, r, rr;
|
||||
int x, res;
|
||||
|
@ -81,7 +81,7 @@ mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
||||
|
||||
if (w >= b) {
|
||||
t = (mp_digit)(w / b);
|
||||
w = w % b;
|
||||
w -= ((mp_word)t) * ((mp_word)b);
|
||||
} else {
|
||||
t = 0;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* swap the elements of two integers, for cases where you can't simply swap the
|
||||
* mp_int pointers around
|
||||
* mp_int pointers around
|
||||
*/
|
||||
void
|
||||
mp_exch (mp_int * a, mp_int * b)
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* calculate c = a**b using a square-multiply algorithm */
|
||||
int
|
||||
mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
|
||||
int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
|
||||
{
|
||||
int res, x;
|
||||
mp_int g;
|
||||
|
@ -20,8 +20,7 @@
|
||||
* embedded in the normal function but that wasted alot of stack space
|
||||
* for nothing (since 99% of the time the Montgomery code would be called)
|
||||
*/
|
||||
int
|
||||
mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
{
|
||||
int dr;
|
||||
|
||||
|
@ -24,24 +24,24 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream)
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
buf = malloc(len);
|
||||
buf = XMALLOC (len);
|
||||
if (buf == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
|
||||
if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
|
||||
free(buf);
|
||||
XFREE (buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (x = 0; x < len; x++) {
|
||||
if (fputc(buf[x], stream) == EOF) {
|
||||
free(buf);
|
||||
XFREE (buf);
|
||||
return MP_VAL;
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
XFREE (buf);
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* Greatest Common Divisor using the binary method */
|
||||
int
|
||||
mp_gcd (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
mp_int u, v;
|
||||
int k, u_lsb, v_lsb, res;
|
||||
|
@ -15,13 +15,11 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* grow as required */
|
||||
int
|
||||
mp_grow (mp_int * a, int size)
|
||||
int mp_grow (mp_int * a, int size)
|
||||
{
|
||||
int i;
|
||||
mp_digit *tmp;
|
||||
|
||||
|
||||
/* if the alloc size is smaller alloc more ram */
|
||||
if (a->alloc < size) {
|
||||
/* ensure there are always at least MP_PREC digits extra on top */
|
||||
@ -33,7 +31,7 @@ mp_grow (mp_int * a, int size)
|
||||
* in case the operation failed we don't want
|
||||
* to overwrite the dp member of a.
|
||||
*/
|
||||
tmp = OPT_CAST realloc (a->dp, sizeof (mp_digit) * size);
|
||||
tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * size);
|
||||
if (tmp == NULL) {
|
||||
/* reallocation failed but "a" is still valid [can be freed] */
|
||||
return MP_MEM;
|
||||
|
@ -15,11 +15,10 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* init a new bigint */
|
||||
int
|
||||
mp_init (mp_int * a)
|
||||
int mp_init (mp_int * a)
|
||||
{
|
||||
/* allocate memory required and clear it */
|
||||
a->dp = OPT_CAST calloc (sizeof (mp_digit), MP_PREC);
|
||||
a->dp = OPT_CAST XCALLOC (sizeof (mp_digit), MP_PREC);
|
||||
if (a->dp == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* creates "a" then copies b into it */
|
||||
int
|
||||
mp_init_copy (mp_int * a, mp_int * b)
|
||||
int mp_init_copy (mp_int * a, mp_int * b)
|
||||
{
|
||||
int res;
|
||||
|
||||
|
@ -15,14 +15,13 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* init an mp_init for a given size */
|
||||
int
|
||||
mp_init_size (mp_int * a, int size)
|
||||
int mp_init_size (mp_int * a, int size)
|
||||
{
|
||||
/* pad size so there are always extra digits */
|
||||
size += (MP_PREC * 2) - (size % MP_PREC);
|
||||
|
||||
/* alloc mem */
|
||||
a->dp = OPT_CAST calloc (sizeof (mp_digit), size);
|
||||
a->dp = OPT_CAST XCALLOC (sizeof (mp_digit), size);
|
||||
if (a->dp == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* hac 14.61, pp608 */
|
||||
int
|
||||
mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
mp_int x, y, u, v, A, B, C, D;
|
||||
int res;
|
||||
|
@ -17,8 +17,7 @@
|
||||
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
|
||||
* HAC pp. 73 Algorithm 2.149
|
||||
*/
|
||||
int
|
||||
mp_jacobi (mp_int * a, mp_int * p, int *c)
|
||||
int mp_jacobi (mp_int * a, mp_int * p, int *c)
|
||||
{
|
||||
mp_int a1, p1;
|
||||
int k, s, r, res;
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* computes least common multiple as |a*b|/(a, b) */
|
||||
int
|
||||
mp_lcm (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
int res;
|
||||
mp_int t1, t2;
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* shift left a certain amount of digits */
|
||||
int
|
||||
mp_lshd (mp_int * a, int b)
|
||||
int mp_lshd (mp_int * a, int b)
|
||||
{
|
||||
int x, res;
|
||||
|
||||
|
@ -28,8 +28,8 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
* are fixed up in the inner loop.
|
||||
*/
|
||||
digs = n->used * 2 + 1;
|
||||
if ((digs < MP_WARRAY) &&
|
||||
n->used <
|
||||
if ((digs < MP_WARRAY) &&
|
||||
n->used <
|
||||
(1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
|
||||
return fast_mp_montgomery_reduce (x, n, rho);
|
||||
}
|
||||
@ -51,7 +51,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
* following inner loop to reduce the
|
||||
* input one digit at a time
|
||||
*/
|
||||
mu = ((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK;
|
||||
mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
|
||||
|
||||
/* a = a + mu * m * b**i */
|
||||
{
|
||||
@ -67,7 +67,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
|
||||
/* set the carry to zero */
|
||||
u = 0;
|
||||
|
||||
|
||||
/* Multiply and add in place */
|
||||
for (iy = 0; iy < n->used; iy++) {
|
||||
/* compute product and sum */
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* high level multiplication (handles sign) */
|
||||
int
|
||||
mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
int res, neg;
|
||||
neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* b = a*2 */
|
||||
int
|
||||
mp_mul_2 (mp_int * a, mp_int * b)
|
||||
int mp_mul_2(mp_int * a, mp_int * b)
|
||||
{
|
||||
int x, res, oldused;
|
||||
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* shift left by a certain bit count */
|
||||
int
|
||||
mp_mul_2d (mp_int * a, int b, mp_int * c)
|
||||
int mp_mul_2d (mp_int * a, int b, mp_int * c)
|
||||
{
|
||||
mp_digit d;
|
||||
int res;
|
||||
|
@ -21,7 +21,6 @@ mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
||||
int res;
|
||||
mp_int t;
|
||||
|
||||
|
||||
if ((res = mp_init (&t)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
|
@ -24,8 +24,7 @@
|
||||
* each step involves a fair bit. This is not meant to
|
||||
* find huge roots [square and cube, etc].
|
||||
*/
|
||||
int
|
||||
mp_n_root (mp_int * a, mp_digit b, mp_int * c)
|
||||
int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
|
||||
{
|
||||
mp_int t1, t2, t3;
|
||||
int res, neg;
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* b = -a */
|
||||
int
|
||||
mp_neg (mp_int * a, mp_int * b)
|
||||
int mp_neg (mp_int * a, mp_int * b)
|
||||
{
|
||||
int res;
|
||||
if ((res = mp_copy (a, b)) != MP_OKAY) {
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* OR two ints together */
|
||||
int
|
||||
mp_or (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_or (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
int res, ix, px;
|
||||
mp_int t, *x;
|
||||
|
@ -22,14 +22,13 @@
|
||||
*
|
||||
* Sets result to 1 if the congruence holds, or zero otherwise.
|
||||
*/
|
||||
int
|
||||
mp_prime_fermat (mp_int * a, mp_int * b, int *result)
|
||||
int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
|
||||
{
|
||||
mp_int t;
|
||||
int err;
|
||||
|
||||
/* default to composite */
|
||||
*result = 0;
|
||||
*result = MP_NO;
|
||||
|
||||
/* ensure b > 1 */
|
||||
if (mp_cmp_d(b, 1) != MP_GT) {
|
||||
@ -48,7 +47,7 @@ mp_prime_fermat (mp_int * a, mp_int * b, int *result)
|
||||
|
||||
/* is it equal to b? */
|
||||
if (mp_cmp (&t, b) == MP_EQ) {
|
||||
*result = 1;
|
||||
*result = MP_YES;
|
||||
}
|
||||
|
||||
err = MP_OKAY;
|
||||
|
@ -19,14 +19,13 @@
|
||||
*
|
||||
* sets result to 0 if not, 1 if yes
|
||||
*/
|
||||
int
|
||||
mp_prime_is_divisible (mp_int * a, int *result)
|
||||
int mp_prime_is_divisible (mp_int * a, int *result)
|
||||
{
|
||||
int err, ix;
|
||||
mp_digit res;
|
||||
|
||||
/* default to not */
|
||||
*result = 0;
|
||||
*result = MP_NO;
|
||||
|
||||
for (ix = 0; ix < PRIME_SIZE; ix++) {
|
||||
/* what is a mod __prime_tab[ix] */
|
||||
@ -36,7 +35,7 @@ mp_prime_is_divisible (mp_int * a, int *result)
|
||||
|
||||
/* is the residue zero? */
|
||||
if (res == 0) {
|
||||
*result = 1;
|
||||
*result = MP_YES;
|
||||
return MP_OKAY;
|
||||
}
|
||||
}
|
||||
|
@ -21,14 +21,13 @@
|
||||
*
|
||||
* Sets result to 1 if probably prime, 0 otherwise
|
||||
*/
|
||||
int
|
||||
mp_prime_is_prime (mp_int * a, int t, int *result)
|
||||
int mp_prime_is_prime (mp_int * a, int t, int *result)
|
||||
{
|
||||
mp_int b;
|
||||
int ix, err, res;
|
||||
|
||||
/* default to no */
|
||||
*result = 0;
|
||||
*result = MP_NO;
|
||||
|
||||
/* valid value of t? */
|
||||
if (t <= 0 || t > PRIME_SIZE) {
|
||||
@ -49,7 +48,7 @@ mp_prime_is_prime (mp_int * a, int t, int *result)
|
||||
}
|
||||
|
||||
/* return if it was trivially divisible */
|
||||
if (res == 1) {
|
||||
if (res == MP_YES) {
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
@ -66,13 +65,13 @@ mp_prime_is_prime (mp_int * a, int t, int *result)
|
||||
goto __B;
|
||||
}
|
||||
|
||||
if (res == 0) {
|
||||
if (res == MP_NO) {
|
||||
goto __B;
|
||||
}
|
||||
}
|
||||
|
||||
/* passed the test */
|
||||
*result = 1;
|
||||
*result = MP_YES;
|
||||
__B:mp_clear (&b);
|
||||
return err;
|
||||
}
|
||||
|
@ -21,14 +21,13 @@
|
||||
* Randomly the chance of error is no more than 1/4 and often
|
||||
* very much lower.
|
||||
*/
|
||||
int
|
||||
mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
|
||||
int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
|
||||
{
|
||||
mp_int n1, y, r;
|
||||
int s, j, err;
|
||||
|
||||
/* default */
|
||||
*result = 0;
|
||||
*result = MP_NO;
|
||||
|
||||
/* ensure b > 1 */
|
||||
if (mp_cmp_d(b, 1) != MP_GT) {
|
||||
@ -90,7 +89,7 @@ mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
|
||||
}
|
||||
|
||||
/* probably prime now */
|
||||
*result = 1;
|
||||
*result = MP_YES;
|
||||
__Y:mp_clear (&y);
|
||||
__R:mp_clear (&r);
|
||||
__N1:mp_clear (&n1);
|
||||
|
@ -146,12 +146,12 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
|
||||
if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
|
||||
goto __ERR;
|
||||
}
|
||||
if (res == 0) {
|
||||
if (res == MP_NO) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res == 1) {
|
||||
if (res == MP_YES) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
74
bn_mp_prime_random.c
Normal file
74
bn_mp_prime_random.c
Normal file
@ -0,0 +1,74 @@
|
||||
/* 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>
|
||||
|
||||
/* makes a truly random prime of a given size (bytes),
|
||||
* call with bbs = 1 if you want it to be congruent to 3 mod 4
|
||||
*
|
||||
* You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
|
||||
* have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
|
||||
* so it can be NULL
|
||||
*
|
||||
* The prime generated will be larger than 2^(8*size).
|
||||
*/
|
||||
|
||||
/* this sole function may hold the key to enslaving all mankind! */
|
||||
int mp_prime_random(mp_int *a, int t, int size, int bbs, ltm_prime_callback cb, void *dat)
|
||||
{
|
||||
unsigned char *tmp;
|
||||
int res, err;
|
||||
|
||||
/* sanity check the input */
|
||||
if (size <= 0) {
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
/* we need a buffer of size+1 bytes */
|
||||
tmp = XMALLOC(size+1);
|
||||
if (tmp == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
|
||||
/* fix MSB */
|
||||
tmp[0] = 1;
|
||||
|
||||
do {
|
||||
/* read the bytes */
|
||||
if (cb(tmp+1, size, dat) != size) {
|
||||
err = MP_VAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* fix the LSB */
|
||||
tmp[size] |= (bbs ? 3 : 1);
|
||||
|
||||
/* read it in */
|
||||
if ((err = mp_read_unsigned_bin(a, tmp, size+1)) != MP_OKAY) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* is it prime? */
|
||||
if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) {
|
||||
goto error;
|
||||
}
|
||||
} while (res == MP_NO);
|
||||
|
||||
err = MP_OKAY;
|
||||
error:
|
||||
XFREE(tmp);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -27,28 +27,36 @@ mp_radix_size (mp_int * a, int radix)
|
||||
return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
|
||||
}
|
||||
|
||||
/* make sure the radix is in range */
|
||||
if (radix < 2 || radix > 64) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* init a copy of the input */
|
||||
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* digs is the digit count */
|
||||
digs = 0;
|
||||
|
||||
/* if it's negative add one for the sign */
|
||||
if (t.sign == MP_NEG) {
|
||||
++digs;
|
||||
t.sign = MP_ZPOS;
|
||||
}
|
||||
|
||||
/* fetch out all of the digits */
|
||||
while (mp_iszero (&t) == 0) {
|
||||
if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
|
||||
mp_clear (&t);
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
++digs;
|
||||
}
|
||||
mp_clear (&t);
|
||||
|
||||
/* return digs + 1, the 1 is for the NULL byte that would be required. */
|
||||
return digs + 1;
|
||||
}
|
||||
|
||||
|
@ -15,10 +15,9 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* determines if mp_reduce_2k can be used */
|
||||
int
|
||||
mp_reduce_is_2k(mp_int *a)
|
||||
int mp_reduce_is_2k(mp_int *a)
|
||||
{
|
||||
int ix, iy;
|
||||
int ix, iy, iz, iw;
|
||||
|
||||
if (a->used == 0) {
|
||||
return 0;
|
||||
@ -26,11 +25,19 @@ mp_reduce_is_2k(mp_int *a)
|
||||
return 1;
|
||||
} else if (a->used > 1) {
|
||||
iy = mp_count_bits(a);
|
||||
iz = 1;
|
||||
iw = 1;
|
||||
|
||||
/* Test every bit from the second digit up, must be 1 */
|
||||
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[iw] & iz) == 0) {
|
||||
return 0;
|
||||
}
|
||||
iz <<= 1;
|
||||
if (iz > (int)MP_MASK) {
|
||||
++iw;
|
||||
iz = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* shift right a certain amount of digits */
|
||||
void
|
||||
mp_rshd (mp_int * a, int b)
|
||||
void mp_rshd (mp_int * a, int b)
|
||||
{
|
||||
int x;
|
||||
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* set to a digit */
|
||||
void
|
||||
mp_set (mp_int * a, mp_digit b)
|
||||
void mp_set (mp_int * a, mp_digit b)
|
||||
{
|
||||
mp_zero (a);
|
||||
a->dp[0] = b & MP_MASK;
|
||||
|
@ -15,8 +15,7 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* set a 32-bit const */
|
||||
int
|
||||
mp_set_int (mp_int * a, unsigned int b)
|
||||
int mp_set_int (mp_int * a, unsigned long b)
|
||||
{
|
||||
int x, res;
|
||||
|
||||
|
@ -15,13 +15,14 @@
|
||||
#include <tommath.h>
|
||||
|
||||
/* shrink a bignum */
|
||||
int
|
||||
mp_shrink (mp_int * a)
|
||||
int mp_shrink (mp_int * a)
|
||||
{
|
||||
mp_digit *tmp;
|
||||
if (a->alloc != a->used) {
|
||||
if ((a->dp = OPT_CAST realloc (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
|
||||
if ((tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
a->dp = tmp;
|
||||
a->alloc = a->used;
|
||||
}
|
||||
return MP_OKAY;
|
||||
|
@ -23,17 +23,18 @@ mp_toradix (mp_int * a, char *str, int radix)
|
||||
mp_digit d;
|
||||
char *_s = str;
|
||||
|
||||
/* check range of the radix */
|
||||
if (radix < 2 || radix > 64) {
|
||||
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) {
|
||||
return res;
|
||||
}
|
||||
@ -59,11 +60,10 @@ mp_toradix (mp_int * a, char *str, int radix)
|
||||
* to the first digit [exluding the sign] of the number]
|
||||
*/
|
||||
bn_reverse ((unsigned char *)_s, digs);
|
||||
|
||||
|
||||
/* append a NULL so the string is properly terminated */
|
||||
*str++ = '\0';
|
||||
|
||||
|
||||
*str = '\0';
|
||||
|
||||
mp_clear (&t);
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
69
bn_prime_sizes_tab.c
Normal file
69
bn_prime_sizes_tab.c
Normal file
@ -0,0 +1,69 @@
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
* LibTomMath is a library that provides multiple-precision
|
||||
* integer arithmetic as well as number theoretic functionality.
|
||||
*
|
||||
* The library was designed directly after the MPI library by
|
||||
* Michael Fromberger but has been written from scratch with
|
||||
* additional optimizations in place.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
|
||||
*/
|
||||
#include <tommath.h>
|
||||
|
||||
/* this table gives the # of rabin miller trials for a prob of failure lower than 2^-96 */
|
||||
static const struct {
|
||||
int k, t;
|
||||
} sizes[] = {
|
||||
{ 128, 28 },
|
||||
{ 256, 16 },
|
||||
{ 384, 10 },
|
||||
{ 512, 7 },
|
||||
{ 640, 6 },
|
||||
{ 768, 5 },
|
||||
{ 896, 4 },
|
||||
{ 1024, 4 },
|
||||
{ 1152, 3 },
|
||||
{ 1280, 3 },
|
||||
{ 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 } };
|
||||
|
||||
/* returns # of RM trials required for a given bit size */
|
||||
int mp_prime_rabin_miller_trials(int size)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
|
||||
if (sizes[x].k == size) {
|
||||
return sizes[x].t;
|
||||
} else if (sizes[x].k > size) {
|
||||
return (x == 0) ? sizes[0].t : sizes[x - 1].t;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,9 @@ s_mp_sqr (mp_int * a, mp_int * b)
|
||||
pa = a->used;
|
||||
if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* default used is maximum possible size */
|
||||
t.used = 2*pa + 1;
|
||||
|
||||
for (ix = 0; ix < pa; ix++) {
|
||||
@ -36,20 +38,20 @@ s_mp_sqr (mp_int * a, mp_int * b)
|
||||
((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
|
||||
|
||||
/* store lower part in result */
|
||||
t.dp[2*ix] = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||
t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||
|
||||
/* get the carry */
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
|
||||
/* left hand side of A[ix] * A[iy] */
|
||||
tmpx = a->dp[ix];
|
||||
tmpx = a->dp[ix];
|
||||
|
||||
/* alias for where to store the results */
|
||||
tmpt = t.dp + (2*ix + 1);
|
||||
tmpt = t.dp + (2*ix + 1);
|
||||
|
||||
for (iy = ix + 1; iy < pa; iy++) {
|
||||
/* 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
|
||||
* addition instead of *2 since it's easier to optimize
|
||||
|
21
changes.txt
21
changes.txt
@ -1,3 +1,24 @@
|
||||
Dec 24th, 2003
|
||||
v0.28 -- Henrik 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().
|
||||
-- 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)
|
||||
-- Picked up a second wind. I'm filled with Gooo. Mission Gooo!
|
||||
-- Removed divisions from mp_reduce_is_2k()
|
||||
-- Sped up mp_div_d() [general case] to use only one division per digit instead of two.
|
||||
-- Added the heap macros from LTC to LTM. Now you can easily [by editing four lines of tommath.h]
|
||||
change the name of the heap functions used in LTM [also compatible with LTC via MPI mode]
|
||||
-- Added bn_prime_rabin_miller_trials() which gives the number of Rabin-Miller trials to achieve
|
||||
a failure rate of less than 2^-96
|
||||
-- fixed bug in fast_mp_invmod(). The initial testing logic was wrong. An invalid input is not when
|
||||
"a" and "b" are even it's when "b" is even [the algo is for odd moduli only].
|
||||
-- Started a new manual [finally]. It is incomplete and will be finished as time goes on. I had to stop
|
||||
adding full demos around half way in chapter three so I could at least get a good portion of the
|
||||
manual done. If you really need help using the library you can always email me!
|
||||
-- My Textbook is now included as part of the package [all Public Domain]
|
||||
|
||||
Sept 19th, 2003
|
||||
v0.27 -- Removed changes.txt~ which was made by accident since "kate" decided it was
|
||||
a good time to re-enable backups... [kde is fun!]
|
||||
|
39
demo/demo.c
39
demo/demo.c
@ -111,10 +111,10 @@ int main(void)
|
||||
|
||||
/* test mp_reduce_2k */
|
||||
#if 0
|
||||
for (cnt = 3; cnt <= 256; ++cnt) {
|
||||
for (cnt = 3; cnt <= 384; ++cnt) {
|
||||
mp_digit tmp;
|
||||
mp_2expt(&a, cnt);
|
||||
mp_sub_d(&a, 1, &a); /* a = 2**cnt - 1 */
|
||||
mp_sub_d(&a, 2, &a); /* a = 2**cnt - 2 */
|
||||
|
||||
|
||||
printf("\nTesting %4d bits", cnt);
|
||||
@ -138,11 +138,11 @@ int main(void)
|
||||
|
||||
/* test mp_div_3 */
|
||||
#if 0
|
||||
for (cnt = 0; cnt < 10000; ) {
|
||||
for (cnt = 0; cnt < 1000000; ) {
|
||||
mp_digit r1, r2;
|
||||
|
||||
if (!(++cnt & 127)) printf("%9d\r", cnt);
|
||||
mp_rand(&a, abs(rand()) % 32 + 1);
|
||||
mp_rand(&a, abs(rand()) % 128 + 1);
|
||||
mp_div_d(&a, 3, &b, &r1);
|
||||
mp_div_3(&a, &c, &r2);
|
||||
|
||||
@ -155,7 +155,7 @@ int main(void)
|
||||
|
||||
/* test the DR reduction */
|
||||
#if 0
|
||||
for (cnt = 2; cnt < 32; cnt++) {
|
||||
for (cnt = 2; cnt < 128; cnt++) {
|
||||
printf("%d digit modulus\n", cnt);
|
||||
mp_grow(&a, cnt);
|
||||
mp_zero(&a);
|
||||
@ -181,7 +181,7 @@ int main(void)
|
||||
printf("Failed on trial %lu\n", rr); exit(-1);
|
||||
|
||||
}
|
||||
} while (++rr < 10000);
|
||||
} while (++rr < 100000);
|
||||
printf("Passed DR test for %d digits\n", cnt);
|
||||
}
|
||||
#endif
|
||||
@ -203,8 +203,8 @@ int main(void)
|
||||
rr += 16;
|
||||
} while (rdtsc() < (CLOCKS_PER_SEC * 2));
|
||||
tt = rdtsc();
|
||||
printf("Adding\t\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt);
|
||||
printf("Adding\t\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((ulong64)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((ulong64)rr)*CLOCKS_PER_SEC)/tt);
|
||||
}
|
||||
fclose(log);
|
||||
|
||||
@ -220,12 +220,13 @@ int main(void)
|
||||
rr += 16;
|
||||
} while (rdtsc() < (CLOCKS_PER_SEC * 2));
|
||||
tt = rdtsc();
|
||||
printf("Subtracting\t\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt);
|
||||
printf("Subtracting\t\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((ulong64)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((ulong64)rr)*CLOCKS_PER_SEC)/tt);
|
||||
}
|
||||
fclose(log);
|
||||
|
||||
/* do mult/square twice, first without karatsuba and second with */
|
||||
mult_test:
|
||||
old_kara_m = KARATSUBA_MUL_CUTOFF;
|
||||
old_kara_s = KARATSUBA_SQR_CUTOFF;
|
||||
for (ix = 0; ix < 2; ix++) {
|
||||
@ -246,8 +247,8 @@ int main(void)
|
||||
rr += 16;
|
||||
} while (rdtsc() < (CLOCKS_PER_SEC * 2));
|
||||
tt = rdtsc();
|
||||
printf("Multiplying\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt);
|
||||
printf("Multiplying\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((ulong64)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", mp_count_bits(&a), (((ulong64)rr)*CLOCKS_PER_SEC)/tt);
|
||||
}
|
||||
fclose(log);
|
||||
|
||||
@ -262,8 +263,8 @@ int main(void)
|
||||
rr += 16;
|
||||
} while (rdtsc() < (CLOCKS_PER_SEC * 2));
|
||||
tt = rdtsc();
|
||||
printf("Squaring\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt);
|
||||
printf("Squaring\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((ulong64)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", mp_count_bits(&a), (((ulong64)rr)*CLOCKS_PER_SEC)/tt);
|
||||
}
|
||||
fclose(log);
|
||||
|
||||
@ -297,12 +298,14 @@ int main(void)
|
||||
"1214855636816562637502584060163403830270705000634713483015101384881871978446801224798536155406895823305035467591632531067547890948695117172076954220727075688048751022421198712032848890056357845974246560748347918630050853933697792254955890439720297560693579400297062396904306270145886830719309296352765295712183040773146419022875165382778007040109957609739589875590885701126197906063620133954893216612678838507540777138437797705602453719559017633986486649523611975865005712371194067612263330335590526176087004421363598470302731349138773205901447704682181517904064735636518462452242791676541725292378925568296858010151852326316777511935037531017413910506921922450666933202278489024521263798482237150056835746454842662048692127173834433089016107854491097456725016327709663199738238442164843147132789153725513257167915555162094970853584447993125488607696008169807374736711297007473812256272245489405898470297178738029484459690836250560495461579533254473316340608217876781986188705928270735695752830825527963838355419762516246028680280988020401914551825487349990306976304093109384451438813251211051597392127491464898797406789175453067960072008590614886532333015881171367104445044718144312416815712216611576221546455968770801413440778423979",
|
||||
NULL
|
||||
};
|
||||
expt_test:
|
||||
log = fopen("logs/expt.log", "w");
|
||||
logb = fopen("logs/expt_dr.log", "w");
|
||||
logc = fopen("logs/expt_2k.log", "w");
|
||||
for (n = 0; primes[n]; n++) {
|
||||
SLEEP;
|
||||
mp_read_radix(&a, primes[n], 10);
|
||||
printf("Different (%d)!!!\n", mp_count_bits(&a));
|
||||
mp_zero(&b);
|
||||
for (rr = 0; rr < mp_count_bits(&a); rr++) {
|
||||
mp_mul_2(&b, &b);
|
||||
@ -328,8 +331,8 @@ int main(void)
|
||||
draw(&d);
|
||||
exit(0);
|
||||
}
|
||||
printf("Exponentiating\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf((n < 6) ? logc : (n < 13) ? logb : log, "%d %9llu\n", mp_count_bits(&a), (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt);
|
||||
printf("Exponentiating\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((ulong64)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf((n < 6) ? logc : (n < 13) ? logb : log, "%d %9llu\n", mp_count_bits(&a), (((ulong64)rr)*CLOCKS_PER_SEC)/tt);
|
||||
}
|
||||
}
|
||||
fclose(log);
|
||||
@ -359,8 +362,8 @@ int main(void)
|
||||
printf("Failed to invert\n");
|
||||
return 0;
|
||||
}
|
||||
printf("Inverting mod\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((unsigned long long)rr)*CLOCKS_PER_SEC)/tt);
|
||||
printf("Inverting mod\t%4d-bit => %9llu/sec, %9llu ticks\n", mp_count_bits(&a), (((ulong64)rr)*CLOCKS_PER_SEC)/tt, tt);
|
||||
fprintf(log, "%d %9llu\n", cnt*DIGIT_BIT, (((ulong64)rr)*CLOCKS_PER_SEC)/tt);
|
||||
}
|
||||
fclose(log);
|
||||
|
||||
|
@ -0,0 +1,2 @@
|
||||
256-bits (k = 36113) = 115792089237316195423570985008687907853269984665640564039457584007913129603823
|
||||
512-bits (k = 38117) = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006045979
|
@ -1,3 +1,6 @@
|
||||
280-bit prime:
|
||||
p == 1942668892225729070919461906823518906642406839052139521251812409738904285204940164839
|
||||
|
||||
280-bit prime:
|
||||
p == 1942668892225729070919461906823518906642406839052139521251812409738904285204940164839
|
||||
|
||||
532-bit prime:
|
||||
p == 14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368691747
|
||||
|
||||
|
@ -19,6 +19,11 @@ tune86: tune.c
|
||||
nasm -f coff timer.asm
|
||||
$(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86
|
||||
|
||||
# for cygwin
|
||||
tune86c: tune.c
|
||||
nasm -f gnuwin32 timer.asm
|
||||
$(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86
|
||||
|
||||
#make tune86 for linux or any ELF format
|
||||
tune86l: tune.c
|
||||
nasm -f elf -DUSE_ELF timer.asm
|
||||
|
32
logs/add.log
32
logs/add.log
@ -1,16 +1,16 @@
|
||||
224 12849536
|
||||
448 9956080
|
||||
672 8372000
|
||||
896 7065464
|
||||
1120 5824864
|
||||
1344 5141728
|
||||
1568 4511808
|
||||
1792 4170480
|
||||
2016 3802536
|
||||
2240 3500936
|
||||
2464 3193352
|
||||
2688 2991976
|
||||
2912 2818672
|
||||
3136 2661448
|
||||
3360 2506560
|
||||
3584 2343304
|
||||
224 8622881
|
||||
448 7241417
|
||||
672 5844712
|
||||
896 4938016
|
||||
1120 4256543
|
||||
1344 3728000
|
||||
1568 3328263
|
||||
1792 3012161
|
||||
2016 2743688
|
||||
2240 2512095
|
||||
2464 2234464
|
||||
2688 1960139
|
||||
2912 2013395
|
||||
3136 1879636
|
||||
3360 1756301
|
||||
3584 1680982
|
||||
|
@ -1,7 +0,0 @@
|
||||
513 600
|
||||
769 221
|
||||
1025 103
|
||||
2049 15
|
||||
2561 8
|
||||
3073 4
|
||||
4097 2
|
@ -1,6 +0,0 @@
|
||||
521 728
|
||||
607 549
|
||||
1279 100
|
||||
2203 29
|
||||
3217 11
|
||||
4253 5
|
@ -1,7 +0,0 @@
|
||||
532 1032
|
||||
784 424
|
||||
1036 214
|
||||
1540 81
|
||||
2072 38
|
||||
3080 13
|
||||
4116 5
|
@ -1,17 +1,17 @@
|
||||
896 301008
|
||||
1344 141872
|
||||
1792 84424
|
||||
2240 55864
|
||||
2688 39784
|
||||
3136 29624
|
||||
3584 22952
|
||||
4032 18304
|
||||
4480 14944
|
||||
4928 12432
|
||||
5376 10496
|
||||
5824 8976
|
||||
6272 7776
|
||||
6720 6792
|
||||
7168 1656
|
||||
7616 1472
|
||||
8064 1312
|
||||
896 348504
|
||||
1344 165040
|
||||
1792 98696
|
||||
2240 65400
|
||||
2688 46672
|
||||
3136 34968
|
||||
3584 27144
|
||||
4032 21648
|
||||
4480 17672
|
||||
4928 14768
|
||||
5376 12416
|
||||
5824 10696
|
||||
6272 9184
|
||||
6720 8064
|
||||
7168 1896
|
||||
7616 1680
|
||||
8064 1504
|
||||
|
34
logs/sqr.log
34
logs/sqr.log
@ -1,17 +1,17 @@
|
||||
896 371856
|
||||
1344 196352
|
||||
1792 122312
|
||||
2240 83144
|
||||
2688 60304
|
||||
3136 45832
|
||||
3584 12760
|
||||
4032 10160
|
||||
4480 8352
|
||||
4928 6944
|
||||
5376 5824
|
||||
5824 5008
|
||||
6272 4336
|
||||
6720 3768
|
||||
7168 3280
|
||||
7616 2952
|
||||
8064 2640
|
||||
911 167013
|
||||
1359 83796
|
||||
1807 50308
|
||||
2254 33637
|
||||
2703 24067
|
||||
3151 17997
|
||||
3599 5751
|
||||
4047 4561
|
||||
4490 3714
|
||||
4943 3067
|
||||
5391 2597
|
||||
5839 2204
|
||||
6286 1909
|
||||
6735 1637
|
||||
7183 1461
|
||||
7631 1302
|
||||
8078 1158
|
||||
|
17
logs/sqr.old
Normal file
17
logs/sqr.old
Normal file
@ -0,0 +1,17 @@
|
||||
896 382617
|
||||
1344 207161
|
||||
1792 131522
|
||||
2240 90775
|
||||
2688 66652
|
||||
3136 50955
|
||||
3584 11678
|
||||
4032 9342
|
||||
4480 7684
|
||||
4928 6382
|
||||
5376 5399
|
||||
5824 4545
|
||||
6272 3994
|
||||
6720 3490
|
||||
7168 3075
|
||||
7616 2733
|
||||
8064 2428
|
@ -1,17 +1,17 @@
|
||||
896 372256
|
||||
1344 196368
|
||||
1792 122272
|
||||
2240 82976
|
||||
2688 60480
|
||||
3136 45808
|
||||
3584 33296
|
||||
4032 27888
|
||||
4480 23608
|
||||
4928 20296
|
||||
5376 17576
|
||||
5824 15416
|
||||
6272 13600
|
||||
6720 12104
|
||||
7168 10080
|
||||
7616 9232
|
||||
8064 8008
|
||||
910 165312
|
||||
1358 84355
|
||||
1806 50316
|
||||
2255 33661
|
||||
2702 24027
|
||||
3151 18068
|
||||
3599 14721
|
||||
4046 12101
|
||||
4493 10112
|
||||
4942 8591
|
||||
5390 7364
|
||||
5839 6398
|
||||
6285 5607
|
||||
6735 4952
|
||||
7182 4625
|
||||
7631 4193
|
||||
8079 3810
|
||||
|
32
logs/sub.log
32
logs/sub.log
@ -1,16 +1,16 @@
|
||||
224 9325944
|
||||
448 8075808
|
||||
672 7054912
|
||||
896 5757992
|
||||
1120 5081768
|
||||
1344 4669384
|
||||
1568 4422384
|
||||
1792 3900416
|
||||
2016 3548872
|
||||
2240 3428912
|
||||
2464 3216968
|
||||
2688 2905280
|
||||
2912 2782664
|
||||
3136 2591440
|
||||
3360 2475728
|
||||
3584 2282216
|
||||
224 10295756
|
||||
448 7577910
|
||||
672 6279588
|
||||
896 5345182
|
||||
1120 4646989
|
||||
1344 4101759
|
||||
1568 3685447
|
||||
1792 3337497
|
||||
2016 3051095
|
||||
2240 2811900
|
||||
2464 2605371
|
||||
2688 2420561
|
||||
2912 2273174
|
||||
3136 2134662
|
||||
3360 2014354
|
||||
3584 1901723
|
||||
|
38
makefile
38
makefile
@ -4,9 +4,9 @@
|
||||
CFLAGS += -I./ -Wall -W -Wshadow -O3 -funroll-loops
|
||||
|
||||
#x86 optimizations [should be valid for any GCC install though]
|
||||
CFLAGS += -fomit-frame-pointer
|
||||
CFLAGS += -fomit-frame-pointer
|
||||
|
||||
VERSION=0.27
|
||||
VERSION=0.28
|
||||
|
||||
default: libtommath.a
|
||||
|
||||
@ -44,7 +44,7 @@ bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \
|
||||
bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
|
||||
bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
|
||||
bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
|
||||
bn_mp_init_multi.o bn_mp_clear_multi.o
|
||||
bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_prime_random.o bn_prime_sizes_tab.o
|
||||
|
||||
libtommath.a: $(OBJECTS)
|
||||
$(AR) $(ARFLAGS) libtommath.a $(OBJECTS)
|
||||
@ -81,29 +81,35 @@ poster: poster.tex
|
||||
docs:
|
||||
cd pics ; make pdfes
|
||||
echo "hello" > tommath.ind
|
||||
perl booker.pl PDF
|
||||
perl booker.pl PDF
|
||||
latex tommath > /dev/null
|
||||
makeindex tommath
|
||||
latex tommath > /dev/null
|
||||
pdflatex tommath
|
||||
rm -f tommath.log tommath.aux tommath.dvi tommath.idx tommath.toc tommath.lof tommath.ind tommath.ilg
|
||||
cd pics ; make clean
|
||||
|
||||
#the old manual being phased out
|
||||
manual:
|
||||
latex bn
|
||||
pdflatex bn
|
||||
rm -f bn.aux bn.dvi bn.log
|
||||
#LTM user manual
|
||||
mandvi: bn.tex
|
||||
echo "hello" > bn.ind
|
||||
latex bn > /dev/null
|
||||
makeindex bn
|
||||
latex bn > /dev/null
|
||||
|
||||
#LTM user manual [pdf]
|
||||
manual: mandvi
|
||||
pdflatex bn >/dev/null
|
||||
rm -f bn.aux bn.dvi bn.log bn.idx bn.lof bn.out bn.toc
|
||||
|
||||
clean:
|
||||
rm -f *.bat *.pdf *.o *.a *.obj *.lib *.exe etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \
|
||||
tommath.idx tommath.toc tommath.log tommath.aux tommath.dvi tommath.lof tommath.ind tommath.ilg *.ps *.pdf *.log *.s mpi.c \
|
||||
poster.aux poster.dvi poster.log
|
||||
rm -f *.bat *.pdf *.o *.a *.obj *.lib *.exe *.dll etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \
|
||||
*.idx *.toc *.log *.aux *.dvi *.lof *.ind *.ilg *.ps *.log *.s mpi.c
|
||||
cd etc ; make clean
|
||||
cd pics ; make clean
|
||||
|
||||
zipup: clean manual poster
|
||||
zipup: clean manual poster docs
|
||||
perl gen.pl ; mv mpi.c pre_gen/ ; \
|
||||
cd .. ; rm -rf ltm* libtommath-$(VERSION) ; mkdir libtommath-$(VERSION) ; \
|
||||
cp -R ./libtommath/* ./libtommath-$(VERSION)/ ; cd ./libtommath-$(VERSION) ; rm -f tommath.src tommath.tex tommath.out ; cd pics ; rm -f *.tif *.ps *.pdf ; cd .. ; cd .. ; ls ; \
|
||||
tar -c libtommath-$(VERSION)/* > ltm-$(VERSION).tar ; \
|
||||
bzip2 -9vv ltm-$(VERSION).tar ; zip -9 -r ltm-$(VERSION).zip libtommath-$(VERSION)/*
|
||||
cp -R ./libtommath/* ./libtommath-$(VERSION)/ ; \
|
||||
tar -c libtommath-$(VERSION)/* | bzip2 -9vvc > ltm-$(VERSION).tar.bz2 ; \
|
||||
zip -9 -r ltm-$(VERSION).zip libtommath-$(VERSION)/*
|
||||
|
@ -29,7 +29,7 @@ bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \
|
||||
bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \
|
||||
bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \
|
||||
bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \
|
||||
bn_mp_init_multi.obj bn_mp_clear_multi.obj
|
||||
bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_prime_random.obj bn_prime_sizes_tab.obj
|
||||
|
||||
TARGET = libtommath.lib
|
||||
|
||||
|
47
makefile.cygwin_dll
Normal file
47
makefile.cygwin_dll
Normal file
@ -0,0 +1,47 @@
|
||||
#Makefile for Cygwin-GCC
|
||||
#
|
||||
#This makefile will build a Windows DLL [doesn't require cygwin to run] in the file
|
||||
#libtommath.dll. The import library is in libtommath.dll.a. Remember to add
|
||||
#"-Wl,--enable-auto-import" to your client build to avoid the auto-import warnings
|
||||
#
|
||||
#Tom St Denis
|
||||
CFLAGS += -I./ -Wall -W -Wshadow -O3 -funroll-loops -mno-cygwin
|
||||
|
||||
#x86 optimizations [should be valid for any GCC install though]
|
||||
CFLAGS += -fomit-frame-pointer
|
||||
|
||||
default: windll
|
||||
|
||||
OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \
|
||||
bn_mp_clamp.o bn_mp_zero.o bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \
|
||||
bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \
|
||||
bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \
|
||||
bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \
|
||||
bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \
|
||||
bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \
|
||||
bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \
|
||||
bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \
|
||||
bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \
|
||||
bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \
|
||||
bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \
|
||||
bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \
|
||||
bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o \
|
||||
bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \
|
||||
bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \
|
||||
bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \
|
||||
bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \
|
||||
bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \
|
||||
bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
|
||||
bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
|
||||
bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
|
||||
bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_prime_random.o bn_prime_sizes_tab.o
|
||||
|
||||
# make a Windows DLL via Cygwin
|
||||
windll: $(OBJECTS)
|
||||
gcc -mno-cygwin -mdll -o libtommath.dll -Wl,--out-implib=libtommath.dll.a -Wl,--export-all-symbols *.o
|
||||
ranlib libtommath.dll.a
|
||||
|
||||
# build the test program using the windows DLL
|
||||
test: $(OBJECTS) windll
|
||||
gcc $(CFLAGS) demo/demo.c libtommath.dll.a -Wl,--enable-auto-import -o test -s
|
||||
cd mtest ; $(CC) -O3 -fomit-frame-pointer -funroll-loops mtest.c -o mtest -s
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
#Tom St Denis
|
||||
|
||||
CFLAGS = /I. /Ox /DWIN32 /W3
|
||||
CFLAGS = /I. /Ox /DWIN32 /W4
|
||||
|
||||
default: library
|
||||
|
||||
@ -28,7 +28,7 @@ bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \
|
||||
bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \
|
||||
bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \
|
||||
bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \
|
||||
bn_mp_init_multi.obj bn_mp_clear_multi.obj
|
||||
bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_prime_random.obj bn_prime_sizes_tab.obj
|
||||
|
||||
library: $(OBJECTS)
|
||||
lib /out:tommath.lib $(OBJECTS)
|
||||
|
@ -1,23 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include "mpi.c"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mp_int a, b;
|
||||
int ix;
|
||||
char buf[1024];
|
||||
|
||||
mp_init(&a);
|
||||
mp_init(&b);
|
||||
|
||||
mp_set(&a, 0x1B);
|
||||
mp_neg(&a, &a);
|
||||
ix = 0;
|
||||
mp_add_d(&a, ix, &b);
|
||||
|
||||
mp_toradix(&b, buf, 64);
|
||||
printf("b == %s\n", buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
BIN
pics/design_process.tif
Normal file
BIN
pics/design_process.tif
Normal file
Binary file not shown.
BIN
pics/expt_state.tif
Normal file
BIN
pics/expt_state.tif
Normal file
Binary file not shown.
BIN
pics/primality.tif
Normal file
BIN
pics/primality.tif
Normal file
Binary file not shown.
BIN
pics/radix.sxd
Normal file
BIN
pics/radix.sxd
Normal file
Binary file not shown.
BIN
pics/sliding_window.tif
Normal file
BIN
pics/sliding_window.tif
Normal file
Binary file not shown.
BIN
poster.pdf
BIN
poster.pdf
Binary file not shown.
@ -2,7 +2,6 @@
|
||||
\usepackage{amsmath, amssymb}
|
||||
\usepackage{hyperref}
|
||||
\begin{document}
|
||||
|
||||
\hspace*{-3in}
|
||||
\begin{tabular}{llllll}
|
||||
$c = a + b$ & {\tt mp\_add(\&a, \&b, \&c)} & $b = 2a$ & {\tt mp\_mul\_2(\&a, \&b)} & \\
|
||||
|
404
pre_gen/mpi.c
404
pre_gen/mpi.c
@ -72,11 +72,8 @@ fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
||||
mp_int x, y, u, v, B, D;
|
||||
int res, neg;
|
||||
|
||||
/* 2. [modified] if a,b are both even then return an error!
|
||||
*
|
||||
* That is if gcd(a,b) = 2**k * q then obviously there is no inverse.
|
||||
*/
|
||||
if (mp_iseven (a) == 1 && mp_iseven (b) == 1) {
|
||||
/* 2. [modified] b must be odd */
|
||||
if (mp_iseven (b) == 1) {
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
@ -210,11 +207,11 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
|
||||
*/
|
||||
#include <tommath.h>
|
||||
|
||||
/* computes xR**-1 == x (mod N) via Montgomery Reduction
|
||||
*
|
||||
* This is an optimized implementation of mp_montgomery_reduce
|
||||
/* computes xR**-1 == x (mod N) via Montgomery Reduction
|
||||
*
|
||||
* This is an optimized implementation of mp_montgomery_reduce
|
||||
* which uses the comba method to quickly calculate the columns of the
|
||||
* reduction.
|
||||
* reduction.
|
||||
*
|
||||
* Based on Algorithm 14.32 on pp.601 of HAC.
|
||||
*/
|
||||
@ -265,11 +262,11 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
/* mu = ai * m' mod b
|
||||
*
|
||||
* We avoid a double precision multiplication (which isn't required)
|
||||
* by casting the value down to a mp_digit. Note this requires
|
||||
* by casting the value down to a mp_digit. Note this requires
|
||||
* that W[ix-1] have the carry cleared (see after the inner loop)
|
||||
*/
|
||||
register mp_digit mu;
|
||||
mu = ((W[ix] & MP_MASK) * rho) & MP_MASK;
|
||||
mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
|
||||
|
||||
/* a = a + mu * m * b**i
|
||||
*
|
||||
@ -277,12 +274,12 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
* by b**i is handled by offseting which columns the results
|
||||
* are added to.
|
||||
*
|
||||
* Note the comba method normally doesn't handle carries in the
|
||||
* inner loop In this case we fix the carry from the previous
|
||||
* column since the Montgomery reduction requires digits of the
|
||||
* Note the comba method normally doesn't handle carries in the
|
||||
* inner loop In this case we fix the carry from the previous
|
||||
* column since the Montgomery reduction requires digits of the
|
||||
* result (so far) [see above] to work. This is
|
||||
* handled by fixing up one carry after the inner loop. The
|
||||
* carry fixups are done in order so after these loops the
|
||||
* handled by fixing up one carry after the inner loop. The
|
||||
* carry fixups are done in order so after these loops the
|
||||
* first m->used words of W[] have the carries fixed
|
||||
*/
|
||||
{
|
||||
@ -328,8 +325,8 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
|
||||
/* copy out, A = A/b**n
|
||||
*
|
||||
* The result is A/b**n but instead of converting from an
|
||||
* array of mp_word to mp_digit than calling mp_rshd
|
||||
* The result is A/b**n but instead of converting from an
|
||||
* array of mp_word to mp_digit than calling mp_rshd
|
||||
* we just copy them in the right order
|
||||
*/
|
||||
|
||||
@ -619,16 +616,16 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
|
||||
|
||||
/* fast squaring
|
||||
*
|
||||
* This is the comba method where the columns of the product
|
||||
* are computed first then the carries are computed. This
|
||||
* has the effect of making a very simple inner loop that
|
||||
* This is the comba method where the columns of the product
|
||||
* are computed first then the carries are computed. This
|
||||
* has the effect of making a very simple inner loop that
|
||||
* is executed the most
|
||||
*
|
||||
* W2 represents the outer products and W the inner.
|
||||
*
|
||||
* A further optimizations is made because the inner
|
||||
* products are of the form "A * B * 2". The *2 part does
|
||||
* not need to be computed until the end which is good
|
||||
* A further optimizations is made because the inner
|
||||
* products are of the form "A * B * 2". The *2 part does
|
||||
* not need to be computed until the end which is good
|
||||
* because 64-bit shifts are slow!
|
||||
*
|
||||
* Based on Algorithm 14.16 on pp.597 of HAC.
|
||||
@ -708,8 +705,8 @@ fast_s_mp_sqr (mp_int * a, mp_int * b)
|
||||
{
|
||||
register mp_digit *tmpb;
|
||||
|
||||
/* double first value, since the inner products are
|
||||
* half of what they should be
|
||||
/* double first value, since the inner products are
|
||||
* half of what they should be
|
||||
*/
|
||||
W[0] += W[0] + W2[0];
|
||||
|
||||
@ -849,8 +846,7 @@ mp_abs (mp_int * a, mp_int * b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* high level addition (handles signs) */
|
||||
int
|
||||
mp_add (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_add (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
int sa, sb, res;
|
||||
|
||||
@ -1153,7 +1149,7 @@ mp_clear (mp_int * a)
|
||||
memset (a->dp, 0, sizeof (mp_digit) * a->used);
|
||||
|
||||
/* free ram */
|
||||
free (a->dp);
|
||||
XFREE(a->dp);
|
||||
|
||||
/* reset members to make debugging easier */
|
||||
a->dp = NULL;
|
||||
@ -1255,8 +1251,7 @@ mp_cmp (mp_int * a, mp_int * b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* compare a digit */
|
||||
int
|
||||
mp_cmp_d (mp_int * a, mp_digit b)
|
||||
int mp_cmp_d(mp_int * a, mp_digit b)
|
||||
{
|
||||
/* compare based on sign */
|
||||
if (a->sign == MP_NEG) {
|
||||
@ -1298,8 +1293,7 @@ mp_cmp_d (mp_int * a, mp_digit b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* compare maginitude of two ints (unsigned) */
|
||||
int
|
||||
mp_cmp_mag (mp_int * a, mp_int * b)
|
||||
int mp_cmp_mag (mp_int * a, mp_int * b)
|
||||
{
|
||||
int n;
|
||||
mp_digit *tmpa, *tmpb;
|
||||
@ -1518,8 +1512,7 @@ mp_count_bits (mp_int * a)
|
||||
* The overall algorithm is as described as
|
||||
* 14.20 from HAC but fixed to treat these cases.
|
||||
*/
|
||||
int
|
||||
mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
||||
int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
||||
{
|
||||
mp_int q, x, y, t1, t2;
|
||||
int res, n, t, i, norm, neg;
|
||||
@ -1722,8 +1715,7 @@ __Q:mp_clear (&q);
|
||||
#include <tommath.h>
|
||||
|
||||
/* b = a/2 */
|
||||
int
|
||||
mp_div_2 (mp_int * a, mp_int * b)
|
||||
int mp_div_2(mp_int * a, mp_int * b)
|
||||
{
|
||||
int x, res, oldused;
|
||||
|
||||
@ -1789,8 +1781,7 @@ mp_div_2 (mp_int * a, mp_int * b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* shift right by a certain bit count (store quotient in c, optional remainder in d) */
|
||||
int
|
||||
mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
|
||||
int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
|
||||
{
|
||||
mp_digit D, r, rr;
|
||||
int x, res;
|
||||
@ -2028,7 +2019,7 @@ mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
|
||||
|
||||
if (w >= b) {
|
||||
t = (mp_digit)(w / b);
|
||||
w = w % b;
|
||||
w -= ((mp_word)t) * ((mp_word)b);
|
||||
} else {
|
||||
t = 0;
|
||||
}
|
||||
@ -2232,7 +2223,7 @@ void mp_dr_setup(mp_int *a, mp_digit *d)
|
||||
#include <tommath.h>
|
||||
|
||||
/* swap the elements of two integers, for cases where you can't simply swap the
|
||||
* mp_int pointers around
|
||||
* mp_int pointers around
|
||||
*/
|
||||
void
|
||||
mp_exch (mp_int * a, mp_int * b)
|
||||
@ -2264,8 +2255,7 @@ mp_exch (mp_int * a, mp_int * b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* calculate c = a**b using a square-multiply algorithm */
|
||||
int
|
||||
mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
|
||||
int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
|
||||
{
|
||||
int res, x;
|
||||
mp_int g;
|
||||
@ -2325,8 +2315,7 @@ mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
|
||||
* embedded in the normal function but that wasted alot of stack space
|
||||
* for nothing (since 99% of the time the Montgomery code would be called)
|
||||
*/
|
||||
int
|
||||
mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
|
||||
{
|
||||
int dr;
|
||||
|
||||
@ -2768,24 +2757,24 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream)
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
buf = malloc(len);
|
||||
buf = XMALLOC (len);
|
||||
if (buf == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
|
||||
if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
|
||||
free(buf);
|
||||
XFREE (buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (x = 0; x < len; x++) {
|
||||
if (fputc(buf[x], stream) == EOF) {
|
||||
free(buf);
|
||||
XFREE (buf);
|
||||
return MP_VAL;
|
||||
}
|
||||
}
|
||||
|
||||
free(buf);
|
||||
XFREE (buf);
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
@ -2810,8 +2799,7 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream)
|
||||
#include <tommath.h>
|
||||
|
||||
/* Greatest Common Divisor using the binary method */
|
||||
int
|
||||
mp_gcd (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
mp_int u, v;
|
||||
int k, u_lsb, v_lsb, res;
|
||||
@ -2922,13 +2910,11 @@ __U:mp_clear (&v);
|
||||
#include <tommath.h>
|
||||
|
||||
/* grow as required */
|
||||
int
|
||||
mp_grow (mp_int * a, int size)
|
||||
int mp_grow (mp_int * a, int size)
|
||||
{
|
||||
int i;
|
||||
mp_digit *tmp;
|
||||
|
||||
|
||||
/* if the alloc size is smaller alloc more ram */
|
||||
if (a->alloc < size) {
|
||||
/* ensure there are always at least MP_PREC digits extra on top */
|
||||
@ -2940,7 +2926,7 @@ mp_grow (mp_int * a, int size)
|
||||
* in case the operation failed we don't want
|
||||
* to overwrite the dp member of a.
|
||||
*/
|
||||
tmp = OPT_CAST realloc (a->dp, sizeof (mp_digit) * size);
|
||||
tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * size);
|
||||
if (tmp == NULL) {
|
||||
/* reallocation failed but "a" is still valid [can be freed] */
|
||||
return MP_MEM;
|
||||
@ -2979,11 +2965,10 @@ mp_grow (mp_int * a, int size)
|
||||
#include <tommath.h>
|
||||
|
||||
/* init a new bigint */
|
||||
int
|
||||
mp_init (mp_int * a)
|
||||
int mp_init (mp_int * a)
|
||||
{
|
||||
/* allocate memory required and clear it */
|
||||
a->dp = OPT_CAST calloc (sizeof (mp_digit), MP_PREC);
|
||||
a->dp = OPT_CAST XCALLOC (sizeof (mp_digit), MP_PREC);
|
||||
if (a->dp == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
@ -3017,8 +3002,7 @@ mp_init (mp_int * a)
|
||||
#include <tommath.h>
|
||||
|
||||
/* creates "a" then copies b into it */
|
||||
int
|
||||
mp_init_copy (mp_int * a, mp_int * b)
|
||||
int mp_init_copy (mp_int * a, mp_int * b)
|
||||
{
|
||||
int res;
|
||||
|
||||
@ -3105,14 +3089,13 @@ int mp_init_multi(mp_int *mp, ...)
|
||||
#include <tommath.h>
|
||||
|
||||
/* init an mp_init for a given size */
|
||||
int
|
||||
mp_init_size (mp_int * a, int size)
|
||||
int mp_init_size (mp_int * a, int size)
|
||||
{
|
||||
/* pad size so there are always extra digits */
|
||||
size += (MP_PREC * 2) - (size % MP_PREC);
|
||||
|
||||
/* alloc mem */
|
||||
a->dp = OPT_CAST calloc (sizeof (mp_digit), size);
|
||||
a->dp = OPT_CAST XCALLOC (sizeof (mp_digit), size);
|
||||
if (a->dp == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
@ -3143,8 +3126,7 @@ mp_init_size (mp_int * a, int size)
|
||||
#include <tommath.h>
|
||||
|
||||
/* hac 14.61, pp608 */
|
||||
int
|
||||
mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
mp_int x, y, u, v, A, B, C, D;
|
||||
int res;
|
||||
@ -3324,8 +3306,7 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
|
||||
/* computes the jacobi c = (a | n) (or Legendre if n is prime)
|
||||
* HAC pp. 73 Algorithm 2.149
|
||||
*/
|
||||
int
|
||||
mp_jacobi (mp_int * a, mp_int * p, int *c)
|
||||
int mp_jacobi (mp_int * a, mp_int * p, int *c)
|
||||
{
|
||||
mp_int a1, p1;
|
||||
int k, s, r, res;
|
||||
@ -3715,8 +3696,7 @@ ERR:
|
||||
#include <tommath.h>
|
||||
|
||||
/* computes least common multiple as |a*b|/(a, b) */
|
||||
int
|
||||
mp_lcm (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
int res;
|
||||
mp_int t1, t2;
|
||||
@ -3774,8 +3754,7 @@ __T:
|
||||
#include <tommath.h>
|
||||
|
||||
/* shift left a certain amount of digits */
|
||||
int
|
||||
mp_lshd (mp_int * a, int b)
|
||||
int mp_lshd (mp_int * a, int b)
|
||||
{
|
||||
int x, res;
|
||||
|
||||
@ -4035,8 +4014,8 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
* are fixed up in the inner loop.
|
||||
*/
|
||||
digs = n->used * 2 + 1;
|
||||
if ((digs < MP_WARRAY) &&
|
||||
n->used <
|
||||
if ((digs < MP_WARRAY) &&
|
||||
n->used <
|
||||
(1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
|
||||
return fast_mp_montgomery_reduce (x, n, rho);
|
||||
}
|
||||
@ -4058,7 +4037,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
* following inner loop to reduce the
|
||||
* input one digit at a time
|
||||
*/
|
||||
mu = ((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK;
|
||||
mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
|
||||
|
||||
/* a = a + mu * m * b**i */
|
||||
{
|
||||
@ -4074,7 +4053,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
|
||||
|
||||
/* set the carry to zero */
|
||||
u = 0;
|
||||
|
||||
|
||||
/* Multiply and add in place */
|
||||
for (iy = 0; iy < n->used; iy++) {
|
||||
/* compute product and sum */
|
||||
@ -4195,8 +4174,7 @@ mp_montgomery_setup (mp_int * n, mp_digit * rho)
|
||||
#include <tommath.h>
|
||||
|
||||
/* high level multiplication (handles sign) */
|
||||
int
|
||||
mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
int res, neg;
|
||||
neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
|
||||
@ -4249,8 +4227,7 @@ mp_mul (mp_int * a, mp_int * b, mp_int * c)
|
||||
#include <tommath.h>
|
||||
|
||||
/* b = a*2 */
|
||||
int
|
||||
mp_mul_2 (mp_int * a, mp_int * b)
|
||||
int mp_mul_2(mp_int * a, mp_int * b)
|
||||
{
|
||||
int x, res, oldused;
|
||||
|
||||
@ -4330,8 +4307,7 @@ mp_mul_2 (mp_int * a, mp_int * b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* shift left by a certain bit count */
|
||||
int
|
||||
mp_mul_2d (mp_int * a, int b, mp_int * c)
|
||||
int mp_mul_2d (mp_int * a, int b, mp_int * c)
|
||||
{
|
||||
mp_digit d;
|
||||
int res;
|
||||
@ -4496,7 +4472,6 @@ mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
||||
int res;
|
||||
mp_int t;
|
||||
|
||||
|
||||
if ((res = mp_init (&t)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
@ -4539,8 +4514,7 @@ mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
|
||||
* each step involves a fair bit. This is not meant to
|
||||
* find huge roots [square and cube, etc].
|
||||
*/
|
||||
int
|
||||
mp_n_root (mp_int * a, mp_digit b, mp_int * c)
|
||||
int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
|
||||
{
|
||||
mp_int t1, t2, t3;
|
||||
int res, neg;
|
||||
@ -4661,8 +4635,7 @@ __T1:mp_clear (&t1);
|
||||
#include <tommath.h>
|
||||
|
||||
/* b = -a */
|
||||
int
|
||||
mp_neg (mp_int * a, mp_int * b)
|
||||
int mp_neg (mp_int * a, mp_int * b)
|
||||
{
|
||||
int res;
|
||||
if ((res = mp_copy (a, b)) != MP_OKAY) {
|
||||
@ -4694,8 +4667,7 @@ mp_neg (mp_int * a, mp_int * b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* OR two ints together */
|
||||
int
|
||||
mp_or (mp_int * a, mp_int * b, mp_int * c)
|
||||
int mp_or (mp_int * a, mp_int * b, mp_int * c)
|
||||
{
|
||||
int res, ix, px;
|
||||
mp_int t, *x;
|
||||
@ -4750,14 +4722,13 @@ mp_or (mp_int * a, mp_int * b, mp_int * c)
|
||||
*
|
||||
* Sets result to 1 if the congruence holds, or zero otherwise.
|
||||
*/
|
||||
int
|
||||
mp_prime_fermat (mp_int * a, mp_int * b, int *result)
|
||||
int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
|
||||
{
|
||||
mp_int t;
|
||||
int err;
|
||||
|
||||
/* default to composite */
|
||||
*result = 0;
|
||||
*result = MP_NO;
|
||||
|
||||
/* ensure b > 1 */
|
||||
if (mp_cmp_d(b, 1) != MP_GT) {
|
||||
@ -4776,7 +4747,7 @@ mp_prime_fermat (mp_int * a, mp_int * b, int *result)
|
||||
|
||||
/* is it equal to b? */
|
||||
if (mp_cmp (&t, b) == MP_EQ) {
|
||||
*result = 1;
|
||||
*result = MP_YES;
|
||||
}
|
||||
|
||||
err = MP_OKAY;
|
||||
@ -4808,14 +4779,13 @@ __T:mp_clear (&t);
|
||||
*
|
||||
* sets result to 0 if not, 1 if yes
|
||||
*/
|
||||
int
|
||||
mp_prime_is_divisible (mp_int * a, int *result)
|
||||
int mp_prime_is_divisible (mp_int * a, int *result)
|
||||
{
|
||||
int err, ix;
|
||||
mp_digit res;
|
||||
|
||||
/* default to not */
|
||||
*result = 0;
|
||||
*result = MP_NO;
|
||||
|
||||
for (ix = 0; ix < PRIME_SIZE; ix++) {
|
||||
/* what is a mod __prime_tab[ix] */
|
||||
@ -4825,7 +4795,7 @@ mp_prime_is_divisible (mp_int * a, int *result)
|
||||
|
||||
/* is the residue zero? */
|
||||
if (res == 0) {
|
||||
*result = 1;
|
||||
*result = MP_YES;
|
||||
return MP_OKAY;
|
||||
}
|
||||
}
|
||||
@ -4859,14 +4829,13 @@ mp_prime_is_divisible (mp_int * a, int *result)
|
||||
*
|
||||
* Sets result to 1 if probably prime, 0 otherwise
|
||||
*/
|
||||
int
|
||||
mp_prime_is_prime (mp_int * a, int t, int *result)
|
||||
int mp_prime_is_prime (mp_int * a, int t, int *result)
|
||||
{
|
||||
mp_int b;
|
||||
int ix, err, res;
|
||||
|
||||
/* default to no */
|
||||
*result = 0;
|
||||
*result = MP_NO;
|
||||
|
||||
/* valid value of t? */
|
||||
if (t <= 0 || t > PRIME_SIZE) {
|
||||
@ -4887,7 +4856,7 @@ mp_prime_is_prime (mp_int * a, int t, int *result)
|
||||
}
|
||||
|
||||
/* return if it was trivially divisible */
|
||||
if (res == 1) {
|
||||
if (res == MP_YES) {
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
@ -4904,13 +4873,13 @@ mp_prime_is_prime (mp_int * a, int t, int *result)
|
||||
goto __B;
|
||||
}
|
||||
|
||||
if (res == 0) {
|
||||
if (res == MP_NO) {
|
||||
goto __B;
|
||||
}
|
||||
}
|
||||
|
||||
/* passed the test */
|
||||
*result = 1;
|
||||
*result = MP_YES;
|
||||
__B:mp_clear (&b);
|
||||
return err;
|
||||
}
|
||||
@ -4941,14 +4910,13 @@ __B:mp_clear (&b);
|
||||
* Randomly the chance of error is no more than 1/4 and often
|
||||
* very much lower.
|
||||
*/
|
||||
int
|
||||
mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
|
||||
int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
|
||||
{
|
||||
mp_int n1, y, r;
|
||||
int s, j, err;
|
||||
|
||||
/* default */
|
||||
*result = 0;
|
||||
*result = MP_NO;
|
||||
|
||||
/* ensure b > 1 */
|
||||
if (mp_cmp_d(b, 1) != MP_GT) {
|
||||
@ -5010,7 +4978,7 @@ mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
|
||||
}
|
||||
|
||||
/* probably prime now */
|
||||
*result = 1;
|
||||
*result = MP_YES;
|
||||
__Y:mp_clear (&y);
|
||||
__R:mp_clear (&r);
|
||||
__N1:mp_clear (&n1);
|
||||
@ -5168,12 +5136,12 @@ int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
|
||||
if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
|
||||
goto __ERR;
|
||||
}
|
||||
if (res == 0) {
|
||||
if (res == MP_NO) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (res == 1) {
|
||||
if (res == MP_YES) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -5187,6 +5155,84 @@ __ERR:
|
||||
|
||||
/* End: bn_mp_prime_next_prime.c */
|
||||
|
||||
/* Start: bn_mp_prime_random.c */
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
* LibTomMath is a library that provides multiple-precision
|
||||
* integer arithmetic as well as number theoretic functionality.
|
||||
*
|
||||
* The library was designed directly after the MPI library by
|
||||
* Michael Fromberger but has been written from scratch with
|
||||
* additional optimizations in place.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
|
||||
*/
|
||||
#include <tommath.h>
|
||||
|
||||
/* makes a truly random prime of a given size (bytes),
|
||||
* call with bbs = 1 if you want it to be congruent to 3 mod 4
|
||||
*
|
||||
* You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
|
||||
* have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
|
||||
* so it can be NULL
|
||||
*
|
||||
* The prime generated will be larger than 2^(8*size).
|
||||
*/
|
||||
|
||||
/* this sole function may hold the key to enslaving all mankind! */
|
||||
int mp_prime_random(mp_int *a, int t, int size, int bbs, ltm_prime_callback cb, void *dat)
|
||||
{
|
||||
unsigned char *tmp;
|
||||
int res, err;
|
||||
|
||||
/* sanity check the input */
|
||||
if (size <= 0) {
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
/* we need a buffer of size+1 bytes */
|
||||
tmp = XMALLOC(size+1);
|
||||
if (tmp == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
|
||||
/* fix MSB */
|
||||
tmp[0] = 1;
|
||||
|
||||
do {
|
||||
/* read the bytes */
|
||||
if (cb(tmp+1, size, dat) != size) {
|
||||
err = MP_VAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* fix the LSB */
|
||||
tmp[size] |= (bbs ? 3 : 1);
|
||||
|
||||
/* read it in */
|
||||
if ((err = mp_read_unsigned_bin(a, tmp, size+1)) != MP_OKAY) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* is it prime? */
|
||||
if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY) {
|
||||
goto error;
|
||||
}
|
||||
} while (res == MP_NO);
|
||||
|
||||
err = MP_OKAY;
|
||||
error:
|
||||
XFREE(tmp);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* End: bn_mp_prime_random.c */
|
||||
|
||||
/* Start: bn_mp_radix_size.c */
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
@ -5217,28 +5263,36 @@ mp_radix_size (mp_int * a, int radix)
|
||||
return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
|
||||
}
|
||||
|
||||
/* make sure the radix is in range */
|
||||
if (radix < 2 || radix > 64) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* init a copy of the input */
|
||||
if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* digs is the digit count */
|
||||
digs = 0;
|
||||
|
||||
/* if it's negative add one for the sign */
|
||||
if (t.sign == MP_NEG) {
|
||||
++digs;
|
||||
t.sign = MP_ZPOS;
|
||||
}
|
||||
|
||||
/* fetch out all of the digits */
|
||||
while (mp_iszero (&t) == 0) {
|
||||
if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
|
||||
mp_clear (&t);
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
++digs;
|
||||
}
|
||||
mp_clear (&t);
|
||||
|
||||
/* return digs + 1, the 1 is for the NULL byte that would be required. */
|
||||
return digs + 1;
|
||||
}
|
||||
|
||||
@ -5707,10 +5761,9 @@ mp_reduce_2k_setup(mp_int *a, mp_digit *d)
|
||||
#include <tommath.h>
|
||||
|
||||
/* determines if mp_reduce_2k can be used */
|
||||
int
|
||||
mp_reduce_is_2k(mp_int *a)
|
||||
int mp_reduce_is_2k(mp_int *a)
|
||||
{
|
||||
int ix, iy;
|
||||
int ix, iy, iz, iw;
|
||||
|
||||
if (a->used == 0) {
|
||||
return 0;
|
||||
@ -5718,11 +5771,19 @@ mp_reduce_is_2k(mp_int *a)
|
||||
return 1;
|
||||
} else if (a->used > 1) {
|
||||
iy = mp_count_bits(a);
|
||||
iz = 1;
|
||||
iw = 1;
|
||||
|
||||
/* Test every bit from the second digit up, must be 1 */
|
||||
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[iw] & iz) == 0) {
|
||||
return 0;
|
||||
}
|
||||
iz <<= 1;
|
||||
if (iz > (int)MP_MASK) {
|
||||
++iw;
|
||||
iz = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -5782,8 +5843,7 @@ mp_reduce_setup (mp_int * a, mp_int * b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* shift right a certain amount of digits */
|
||||
void
|
||||
mp_rshd (mp_int * a, int b)
|
||||
void mp_rshd (mp_int * a, int b)
|
||||
{
|
||||
int x;
|
||||
|
||||
@ -5853,8 +5913,7 @@ mp_rshd (mp_int * a, int b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* set to a digit */
|
||||
void
|
||||
mp_set (mp_int * a, mp_digit b)
|
||||
void mp_set (mp_int * a, mp_digit b)
|
||||
{
|
||||
mp_zero (a);
|
||||
a->dp[0] = b & MP_MASK;
|
||||
@ -5881,8 +5940,7 @@ mp_set (mp_int * a, mp_digit b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* set a 32-bit const */
|
||||
int
|
||||
mp_set_int (mp_int * a, unsigned int b)
|
||||
int mp_set_int (mp_int * a, unsigned long b)
|
||||
{
|
||||
int x, res;
|
||||
|
||||
@ -5928,13 +5986,14 @@ mp_set_int (mp_int * a, unsigned int b)
|
||||
#include <tommath.h>
|
||||
|
||||
/* shrink a bignum */
|
||||
int
|
||||
mp_shrink (mp_int * a)
|
||||
int mp_shrink (mp_int * a)
|
||||
{
|
||||
mp_digit *tmp;
|
||||
if (a->alloc != a->used) {
|
||||
if ((a->dp = OPT_CAST realloc (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
|
||||
if ((tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
|
||||
return MP_MEM;
|
||||
}
|
||||
a->dp = tmp;
|
||||
a->alloc = a->used;
|
||||
}
|
||||
return MP_OKAY;
|
||||
@ -6841,17 +6900,18 @@ mp_toradix (mp_int * a, char *str, int radix)
|
||||
mp_digit d;
|
||||
char *_s = str;
|
||||
|
||||
/* check range of the radix */
|
||||
if (radix < 2 || radix > 64) {
|
||||
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) {
|
||||
return res;
|
||||
}
|
||||
@ -6877,11 +6937,10 @@ mp_toradix (mp_int * a, char *str, int radix)
|
||||
* to the first digit [exluding the sign] of the number]
|
||||
*/
|
||||
bn_reverse ((unsigned char *)_s, digs);
|
||||
|
||||
|
||||
/* append a NULL so the string is properly terminated */
|
||||
*str++ = '\0';
|
||||
|
||||
|
||||
*str = '\0';
|
||||
|
||||
mp_clear (&t);
|
||||
return MP_OKAY;
|
||||
}
|
||||
@ -6993,6 +7052,79 @@ mp_zero (mp_int * a)
|
||||
|
||||
/* End: bn_mp_zero.c */
|
||||
|
||||
/* Start: bn_prime_sizes_tab.c */
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
* LibTomMath is a library that provides multiple-precision
|
||||
* integer arithmetic as well as number theoretic functionality.
|
||||
*
|
||||
* The library was designed directly after the MPI library by
|
||||
* Michael Fromberger but has been written from scratch with
|
||||
* additional optimizations in place.
|
||||
*
|
||||
* The library is free for all purposes without any express
|
||||
* guarantee it works.
|
||||
*
|
||||
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
|
||||
*/
|
||||
#include <tommath.h>
|
||||
|
||||
/* this table gives the # of rabin miller trials for a prob of failure lower than 2^-96 */
|
||||
static const struct {
|
||||
int k, t;
|
||||
} sizes[] = {
|
||||
{ 128, 28 },
|
||||
{ 256, 16 },
|
||||
{ 384, 10 },
|
||||
{ 512, 7 },
|
||||
{ 640, 6 },
|
||||
{ 768, 5 },
|
||||
{ 896, 4 },
|
||||
{ 1024, 4 },
|
||||
{ 1152, 3 },
|
||||
{ 1280, 3 },
|
||||
{ 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 } };
|
||||
|
||||
/* returns # of RM trials required for a given bit size */
|
||||
int mp_prime_rabin_miller_trials(int size)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
|
||||
if (sizes[x].k == size) {
|
||||
return sizes[x].t;
|
||||
} else if (sizes[x].k > size) {
|
||||
return (x == 0) ? sizes[0].t : sizes[x - 1].t;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* End: bn_prime_sizes_tab.c */
|
||||
|
||||
/* Start: bn_prime_tab.c */
|
||||
/* LibTomMath, multiple-precision integer library -- Tom St Denis
|
||||
*
|
||||
@ -7630,7 +7762,9 @@ s_mp_sqr (mp_int * a, mp_int * b)
|
||||
pa = a->used;
|
||||
if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/* default used is maximum possible size */
|
||||
t.used = 2*pa + 1;
|
||||
|
||||
for (ix = 0; ix < pa; ix++) {
|
||||
@ -7640,20 +7774,20 @@ s_mp_sqr (mp_int * a, mp_int * b)
|
||||
((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
|
||||
|
||||
/* store lower part in result */
|
||||
t.dp[2*ix] = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||
t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
|
||||
|
||||
/* get the carry */
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
|
||||
|
||||
/* left hand side of A[ix] * A[iy] */
|
||||
tmpx = a->dp[ix];
|
||||
tmpx = a->dp[ix];
|
||||
|
||||
/* alias for where to store the results */
|
||||
tmpt = t.dp + (2*ix + 1);
|
||||
tmpt = t.dp + (2*ix + 1);
|
||||
|
||||
for (iy = ix + 1; iy < pa; iy++) {
|
||||
/* 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
|
||||
* addition instead of *2 since it's easier to optimize
|
||||
|
53
tommath.h
53
tommath.h
@ -91,6 +91,24 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* define heap macros */
|
||||
#ifndef CRYPT
|
||||
/* default to libc stuff */
|
||||
#ifndef XMALLOC
|
||||
#define XMALLOC malloc
|
||||
#define XFREE free
|
||||
#define XREALLOC realloc
|
||||
#define XCALLOC calloc
|
||||
#endif
|
||||
|
||||
/* prototypes for our heap functions */
|
||||
extern void *XMALLOC(size_t n);
|
||||
extern void *REALLOC(void *p, size_t n);
|
||||
extern void *XCALLOC(size_t n, size_t s);
|
||||
extern void XFREE(void *p);
|
||||
#endif
|
||||
|
||||
|
||||
/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
|
||||
#ifndef DIGIT_BIT
|
||||
#define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */
|
||||
@ -113,6 +131,9 @@ extern "C" {
|
||||
#define MP_VAL -3 /* invalid input */
|
||||
#define MP_RANGE MP_VAL
|
||||
|
||||
#define MP_YES 1 /* yes response */
|
||||
#define MP_NO 0 /* no response */
|
||||
|
||||
typedef int mp_err;
|
||||
|
||||
/* you'll have to tune these... */
|
||||
@ -130,11 +151,16 @@ extern int KARATSUBA_MUL_CUTOFF,
|
||||
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
|
||||
#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
|
||||
|
||||
/* the infamous mp_int structure */
|
||||
typedef struct {
|
||||
int used, alloc, sign;
|
||||
mp_digit *dp;
|
||||
} mp_int;
|
||||
|
||||
/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
|
||||
typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
|
||||
|
||||
|
||||
#define USED(m) ((m)->used)
|
||||
#define DIGIT(m,k) ((m)->dp[(k)])
|
||||
#define SIGN(m) ((m)->sign)
|
||||
@ -168,9 +194,9 @@ int mp_grow(mp_int *a, int size);
|
||||
int mp_init_size(mp_int *a, int size);
|
||||
|
||||
/* ---> Basic Manipulations <--- */
|
||||
#define mp_iszero(a) (((a)->used == 0) ? 1 : 0)
|
||||
#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? 1 : 0)
|
||||
#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? 1 : 0)
|
||||
#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
|
||||
#define mp_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
|
||||
#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
|
||||
|
||||
/* set to zero */
|
||||
void mp_zero(mp_int *a);
|
||||
@ -179,7 +205,7 @@ void mp_zero(mp_int *a);
|
||||
void mp_set(mp_int *a, mp_digit b);
|
||||
|
||||
/* set a 32-bit const */
|
||||
int mp_set_int(mp_int *a, unsigned int b);
|
||||
int mp_set_int(mp_int *a, unsigned long b);
|
||||
|
||||
/* copy, b = a */
|
||||
int mp_copy(mp_int *a, mp_int *b);
|
||||
@ -219,6 +245,8 @@ int mp_2expt(mp_int *a, int b);
|
||||
/* Counts the number of lsbs which are zero before the first zero bit */
|
||||
int mp_cnt_lsb(mp_int *a);
|
||||
|
||||
/* I Love Earth! */
|
||||
|
||||
/* makes a pseudo-random int of a given size */
|
||||
int mp_rand(mp_int *a, int digits);
|
||||
|
||||
@ -392,6 +420,11 @@ int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
|
||||
*/
|
||||
int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
|
||||
|
||||
/* This gives [for a given bit size] the number of trials required
|
||||
* such that Miller-Rabin gives a prob of failure lower than 2^-96
|
||||
*/
|
||||
int mp_prime_rabin_miller_trials(int size);
|
||||
|
||||
/* performs t rounds of Miller-Rabin on "a" using the first
|
||||
* t prime bases. Also performs an initial sieve of trial
|
||||
* division. Determines if "a" is prime with probability
|
||||
@ -408,6 +441,18 @@ int mp_prime_is_prime(mp_int *a, int t, int *result);
|
||||
*/
|
||||
int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
|
||||
|
||||
/* makes a truly random prime of a given size (bytes),
|
||||
* call with bbs = 1 if you want it to be congruent to 3 mod 4
|
||||
*
|
||||
* You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
|
||||
* have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
|
||||
* so it can be NULL
|
||||
*
|
||||
* The prime generated will be larger than 2^(8*size).
|
||||
*/
|
||||
int mp_prime_random(mp_int *a, int t, int size, int bbs, ltm_prime_callback cb, void *dat);
|
||||
|
||||
|
||||
/* ---> radix conversion <--- */
|
||||
int mp_count_bits(mp_int *a);
|
||||
|
||||
|
139
tommath.out
Normal file
139
tommath.out
Normal file
@ -0,0 +1,139 @@
|
||||
\BOOKMARK [0][-]{chapter.1}{Introduction}{}
|
||||
\BOOKMARK [1][-]{section.1.1}{Multiple Precision Arithmetic}{chapter.1}
|
||||
\BOOKMARK [2][-]{subsection.1.1.1}{The Need for Multiple Precision Arithmetic}{section.1.1}
|
||||
\BOOKMARK [2][-]{subsection.1.1.2}{What is Multiple Precision Arithmetic?}{section.1.1}
|
||||
\BOOKMARK [2][-]{subsection.1.1.3}{Benefits of Multiple Precision Arithmetic}{section.1.1}
|
||||
\BOOKMARK [1][-]{section.1.2}{Purpose of This Text}{chapter.1}
|
||||
\BOOKMARK [1][-]{section.1.3}{Discussion and Notation}{chapter.1}
|
||||
\BOOKMARK [2][-]{subsection.1.3.1}{Notation}{section.1.3}
|
||||
\BOOKMARK [2][-]{subsection.1.3.2}{Precision Notation}{section.1.3}
|
||||
\BOOKMARK [2][-]{subsection.1.3.3}{Algorithm Inputs and Outputs}{section.1.3}
|
||||
\BOOKMARK [2][-]{subsection.1.3.4}{Mathematical Expressions}{section.1.3}
|
||||
\BOOKMARK [2][-]{subsection.1.3.5}{Work Effort}{section.1.3}
|
||||
\BOOKMARK [1][-]{section.1.4}{Exercises}{chapter.1}
|
||||
\BOOKMARK [0][-]{chapter.2}{Introduction to LibTomMath}{}
|
||||
\BOOKMARK [1][-]{section.2.1}{What is LibTomMath?}{chapter.2}
|
||||
\BOOKMARK [1][-]{section.2.2}{Goals of LibTomMath}{chapter.2}
|
||||
\BOOKMARK [1][-]{section.2.3}{Choice of LibTomMath}{chapter.2}
|
||||
\BOOKMARK [2][-]{subsection.2.3.1}{Code Base}{section.2.3}
|
||||
\BOOKMARK [2][-]{subsection.2.3.2}{API Simplicity}{section.2.3}
|
||||
\BOOKMARK [2][-]{subsection.2.3.3}{Optimizations}{section.2.3}
|
||||
\BOOKMARK [2][-]{subsection.2.3.4}{Portability and Stability}{section.2.3}
|
||||
\BOOKMARK [2][-]{subsection.2.3.5}{Choice}{section.2.3}
|
||||
\BOOKMARK [0][-]{chapter.3}{Getting Started}{}
|
||||
\BOOKMARK [1][-]{section.3.1}{Library Basics}{chapter.3}
|
||||
\BOOKMARK [1][-]{section.3.2}{What is a Multiple Precision Integer?}{chapter.3}
|
||||
\BOOKMARK [2][-]{subsection.3.2.1}{The mp\137int Structure}{section.3.2}
|
||||
\BOOKMARK [1][-]{section.3.3}{Argument Passing}{chapter.3}
|
||||
\BOOKMARK [1][-]{section.3.4}{Return Values}{chapter.3}
|
||||
\BOOKMARK [1][-]{section.3.5}{Initialization and Clearing}{chapter.3}
|
||||
\BOOKMARK [2][-]{subsection.3.5.1}{Initializing an mp\137int}{section.3.5}
|
||||
\BOOKMARK [2][-]{subsection.3.5.2}{Clearing an mp\137int}{section.3.5}
|
||||
\BOOKMARK [1][-]{section.3.6}{Maintenance Algorithms}{chapter.3}
|
||||
\BOOKMARK [2][-]{subsection.3.6.1}{Augmenting an mp\137int's Precision}{section.3.6}
|
||||
\BOOKMARK [2][-]{subsection.3.6.2}{Initializing Variable Precision mp\137ints}{section.3.6}
|
||||
\BOOKMARK [2][-]{subsection.3.6.3}{Multiple Integer Initializations and Clearings}{section.3.6}
|
||||
\BOOKMARK [2][-]{subsection.3.6.4}{Clamping Excess Digits}{section.3.6}
|
||||
\BOOKMARK [0][-]{chapter.4}{Basic Operations}{}
|
||||
\BOOKMARK [1][-]{section.4.1}{Introduction}{chapter.4}
|
||||
\BOOKMARK [1][-]{section.4.2}{Assigning Values to mp\137int Structures}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.2.1}{Copying an mp\137int}{section.4.2}
|
||||
\BOOKMARK [2][-]{subsection.4.2.2}{Creating a Clone}{section.4.2}
|
||||
\BOOKMARK [1][-]{section.4.3}{Zeroing an Integer}{chapter.4}
|
||||
\BOOKMARK [1][-]{section.4.4}{Sign Manipulation}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.4.1}{Absolute Value}{section.4.4}
|
||||
\BOOKMARK [2][-]{subsection.4.4.2}{Integer Negation}{section.4.4}
|
||||
\BOOKMARK [1][-]{section.4.5}{Small Constants}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.5.1}{Setting Small Constants}{section.4.5}
|
||||
\BOOKMARK [2][-]{subsection.4.5.2}{Setting Large Constants}{section.4.5}
|
||||
\BOOKMARK [1][-]{section.4.6}{Comparisons}{chapter.4}
|
||||
\BOOKMARK [2][-]{subsection.4.6.1}{Unsigned Comparisions}{section.4.6}
|
||||
\BOOKMARK [2][-]{subsection.4.6.2}{Signed Comparisons}{section.4.6}
|
||||
\BOOKMARK [0][-]{chapter.5}{Basic Arithmetic}{}
|
||||
\BOOKMARK [1][-]{section.5.1}{Introduction}{chapter.5}
|
||||
\BOOKMARK [1][-]{section.5.2}{Addition and Subtraction}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.2.1}{Low Level Addition}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.2}{Low Level Subtraction}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.3}{High Level Addition}{section.5.2}
|
||||
\BOOKMARK [2][-]{subsection.5.2.4}{High Level Subtraction}{section.5.2}
|
||||
\BOOKMARK [1][-]{section.5.3}{Bit and Digit Shifting}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.3.1}{Multiplication by Two}{section.5.3}
|
||||
\BOOKMARK [2][-]{subsection.5.3.2}{Division by Two}{section.5.3}
|
||||
\BOOKMARK [1][-]{section.5.4}{Polynomial Basis Operations}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.4.1}{Multiplication by x}{section.5.4}
|
||||
\BOOKMARK [2][-]{subsection.5.4.2}{Division by x}{section.5.4}
|
||||
\BOOKMARK [1][-]{section.5.5}{Powers of Two}{chapter.5}
|
||||
\BOOKMARK [2][-]{subsection.5.5.1}{Multiplication by Power of Two}{section.5.5}
|
||||
\BOOKMARK [2][-]{subsection.5.5.2}{Division by Power of Two}{section.5.5}
|
||||
\BOOKMARK [2][-]{subsection.5.5.3}{Remainder of Division by Power of Two}{section.5.5}
|
||||
\BOOKMARK [0][-]{chapter.6}{Multiplication and Squaring}{}
|
||||
\BOOKMARK [1][-]{section.6.1}{The Multipliers}{chapter.6}
|
||||
\BOOKMARK [1][-]{section.6.2}{Multiplication}{chapter.6}
|
||||
\BOOKMARK [2][-]{subsection.6.2.1}{The Baseline Multiplication}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.2}{Faster Multiplication by the ``Comba'' Method}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.3}{Polynomial Basis Multiplication}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.4}{Karatsuba Multiplication}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.5}{Toom-Cook 3-Way Multiplication}{section.6.2}
|
||||
\BOOKMARK [2][-]{subsection.6.2.6}{Signed Multiplication}{section.6.2}
|
||||
\BOOKMARK [1][-]{section.6.3}{Squaring}{chapter.6}
|
||||
\BOOKMARK [2][-]{subsection.6.3.1}{The Baseline Squaring Algorithm}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.2}{Faster Squaring by the ``Comba'' Method}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.3}{Polynomial Basis Squaring}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.4}{Karatsuba Squaring}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.5}{Toom-Cook Squaring}{section.6.3}
|
||||
\BOOKMARK [2][-]{subsection.6.3.6}{High Level Squaring}{section.6.3}
|
||||
\BOOKMARK [0][-]{chapter.7}{Modular Reduction}{}
|
||||
\BOOKMARK [1][-]{section.7.1}{Basics of Modular Reduction}{chapter.7}
|
||||
\BOOKMARK [1][-]{section.7.2}{The Barrett Reduction}{chapter.7}
|
||||
\BOOKMARK [2][-]{subsection.7.2.1}{Fixed Point Arithmetic}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.2}{Choosing a Radix Point}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.3}{Trimming the Quotient}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.4}{Trimming the Residue}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.5}{The Barrett Algorithm}{section.7.2}
|
||||
\BOOKMARK [2][-]{subsection.7.2.6}{The Barrett Setup Algorithm}{section.7.2}
|
||||
\BOOKMARK [1][-]{section.7.3}{The Montgomery Reduction}{chapter.7}
|
||||
\BOOKMARK [2][-]{subsection.7.3.1}{Digit Based Montgomery Reduction}{section.7.3}
|
||||
\BOOKMARK [2][-]{subsection.7.3.2}{Baseline Montgomery Reduction}{section.7.3}
|
||||
\BOOKMARK [2][-]{subsection.7.3.3}{Faster ``Comba'' Montgomery Reduction}{section.7.3}
|
||||
\BOOKMARK [2][-]{subsection.7.3.4}{Montgomery Setup}{section.7.3}
|
||||
\BOOKMARK [1][-]{section.7.4}{The Diminished Radix Algorithm}{chapter.7}
|
||||
\BOOKMARK [2][-]{subsection.7.4.1}{Choice of Moduli}{section.7.4}
|
||||
\BOOKMARK [2][-]{subsection.7.4.2}{Choice of k}{section.7.4}
|
||||
\BOOKMARK [2][-]{subsection.7.4.3}{Restricted Diminished Radix Reduction}{section.7.4}
|
||||
\BOOKMARK [2][-]{subsection.7.4.4}{Unrestricted Diminished Radix Reduction}{section.7.4}
|
||||
\BOOKMARK [1][-]{section.7.5}{Algorithm Comparison}{chapter.7}
|
||||
\BOOKMARK [0][-]{chapter.8}{Exponentiation}{}
|
||||
\BOOKMARK [1][-]{section.8.1}{Exponentiation Basics}{chapter.8}
|
||||
\BOOKMARK [2][-]{subsection.8.1.1}{Single Digit Exponentiation}{section.8.1}
|
||||
\BOOKMARK [1][-]{section.8.2}{k-ary Exponentiation}{chapter.8}
|
||||
\BOOKMARK [2][-]{subsection.8.2.1}{Optimal Values of k}{section.8.2}
|
||||
\BOOKMARK [2][-]{subsection.8.2.2}{Sliding-Window Exponentiation}{section.8.2}
|
||||
\BOOKMARK [1][-]{section.8.3}{Modular Exponentiation}{chapter.8}
|
||||
\BOOKMARK [2][-]{subsection.8.3.1}{Barrett Modular Exponentiation}{section.8.3}
|
||||
\BOOKMARK [1][-]{section.8.4}{Quick Power of Two}{chapter.8}
|
||||
\BOOKMARK [0][-]{chapter.9}{Higher Level Algorithms}{}
|
||||
\BOOKMARK [1][-]{section.9.1}{Integer Division with Remainder}{chapter.9}
|
||||
\BOOKMARK [2][-]{subsection.9.1.1}{Quotient Estimation}{section.9.1}
|
||||
\BOOKMARK [2][-]{subsection.9.1.2}{Normalized Integers}{section.9.1}
|
||||
\BOOKMARK [2][-]{subsection.9.1.3}{Radix- Division with Remainder}{section.9.1}
|
||||
\BOOKMARK [1][-]{section.9.2}{Single Digit Helpers}{chapter.9}
|
||||
\BOOKMARK [2][-]{subsection.9.2.1}{Single Digit Addition and Subtraction}{section.9.2}
|
||||
\BOOKMARK [2][-]{subsection.9.2.2}{Single Digit Multiplication}{section.9.2}
|
||||
\BOOKMARK [2][-]{subsection.9.2.3}{Single Digit Division}{section.9.2}
|
||||
\BOOKMARK [2][-]{subsection.9.2.4}{Single Digit Root Extraction}{section.9.2}
|
||||
\BOOKMARK [1][-]{section.9.3}{Random Number Generation}{chapter.9}
|
||||
\BOOKMARK [1][-]{section.9.4}{Formatted Representations}{chapter.9}
|
||||
\BOOKMARK [2][-]{subsection.9.4.1}{Reading Radix-n Input}{section.9.4}
|
||||
\BOOKMARK [2][-]{subsection.9.4.2}{Generating Radix-n Output}{section.9.4}
|
||||
\BOOKMARK [0][-]{chapter.10}{Number Theoretic Algorithms}{}
|
||||
\BOOKMARK [1][-]{section.10.1}{Greatest Common Divisor}{chapter.10}
|
||||
\BOOKMARK [2][-]{subsection.10.1.1}{Complete Greatest Common Divisor}{section.10.1}
|
||||
\BOOKMARK [1][-]{section.10.2}{Least Common Multiple}{chapter.10}
|
||||
\BOOKMARK [1][-]{section.10.3}{Jacobi Symbol Computation}{chapter.10}
|
||||
\BOOKMARK [2][-]{subsection.10.3.1}{Jacobi Symbol}{section.10.3}
|
||||
\BOOKMARK [1][-]{section.10.4}{Modular Inverse}{chapter.10}
|
||||
\BOOKMARK [2][-]{subsection.10.4.1}{General Case}{section.10.4}
|
||||
\BOOKMARK [1][-]{section.10.5}{Primality Tests}{chapter.10}
|
||||
\BOOKMARK [2][-]{subsection.10.5.1}{Trial Division}{section.10.5}
|
||||
\BOOKMARK [2][-]{subsection.10.5.2}{The Fermat Test}{section.10.5}
|
||||
\BOOKMARK [2][-]{subsection.10.5.3}{The Miller-Rabin Test}{section.10.5}
|
21175
tommath.pdf
Normal file
21175
tommath.pdf
Normal file
File diff suppressed because one or more lines are too long
6268
tommath.src
Normal file
6268
tommath.src
Normal file
File diff suppressed because it is too large
Load Diff
10683
tommath.tex
Normal file
10683
tommath.tex
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user