Index: generic/tclStubInit.c ================================================================== --- generic/tclStubInit.c +++ generic/tclStubInit.c @@ -446,10 +446,21 @@ # define TclGetCommandFromObj Tcl_GetCommandFromObj # define TclGetCommandFullName Tcl_GetCommandFullName # define TclpLocaltime_unix TclpLocaltime # define TclpGmtime_unix TclpGmtime # define TclOldFreeObj TclFreeObj +# define TclBN_reverse bn_reverse +# define TclBN_fast_s_mp_mul_digs fast_s_mp_mul_digs +# define TclBN_fast_s_mp_sqr fast_s_mp_sqr +# define TclBN_mp_karatsuba_mul mp_karatsuba_mul +# define TclBN_mp_karatsuba_sqr mp_karatsuba_sqr +# define TclBN_mp_toom_mul mp_toom_mul +# define TclBN_mp_toom_sqr mp_toom_sqr +# define TclBN_s_mp_add s_mp_add +# define TclBN_s_mp_mul_digs s_mp_mul_digs +# define TclBN_s_mp_sqr s_mp_sqr +# define TclBN_s_mp_sub s_mp_sub static int seekOld( Tcl_Channel chan, /* The channel on which to seek. */ int offset, /* Offset to seek to. */ Index: generic/tclTomMath.decls ================================================================== --- generic/tclTomMath.decls +++ generic/tclTomMath.decls @@ -237,14 +237,14 @@ declare 67 { int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) } # Added in libtommath 1.0.1 declare 68 { - int TclBN_mp_set_long_long(mp_int *a, Tcl_WideUInt i) + int TclBN_mp_set_long_long(mp_int *a, unsigned TCL_WIDE_INT_TYPE i) } declare 69 { - Tcl_WideUInt TclBN_mp_get_long_long(const mp_int *a) + unsigned TCL_WIDE_INT_TYPE TclBN_mp_get_long_long(const mp_int *a) } declare 70 { int TclBN_mp_set_long(mp_int *a, unsigned long i) } declare 71 { Index: generic/tclTomMath.h ================================================================== --- generic/tclTomMath.h +++ generic/tclTomMath.h @@ -5,12 +5,11 @@ * * 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. + * SPDX-License-Identifier: Unlicense */ #ifndef BN_H_ #define BN_H_ #include "tclTomMathDecls.h" @@ -23,11 +22,11 @@ #ifdef __cplusplus extern "C" { #endif /* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ -#if defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__) +#if defined(_WIN32) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__) # define MP_32BIT #endif /* detect 64-bit mode if possible */ #if defined(NEVER) @@ -108,13 +107,10 @@ #endif /* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ #ifndef DIGIT_BIT # define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */ -typedef unsigned long mp_min_u32; -#else -typedef mp_digit mp_min_u32; #endif #define MP_DIGIT_BIT DIGIT_BIT #define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) #define MP_DIGIT_MAX MP_MASK @@ -129,10 +125,11 @@ #define MP_OKAY 0 /* ok result */ #define MP_MEM -2 /* out of mem */ #define MP_VAL -3 /* invalid input */ #define MP_RANGE MP_VAL +#define MP_ITER -4 /* Max. iterations reached */ #define MP_YES 1 /* yes response */ #define MP_NO 0 /* no response */ /* Primality generation flags */ @@ -176,15 +173,10 @@ }; /* 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) - /* error code to char* string */ const char *mp_error_to_string(int code); /* ---> init and deinit bignum functions <--- */ /* init a bignum */ @@ -240,10 +232,15 @@ /* set to a digit */ /* void mp_set(mp_int *a, mp_digit b); */ + +/* set a double */ +/* +int mp_set_double(mp_int *a, double b); +*/ /* set a 32-bit const */ /* int mp_set_int(mp_int *a, unsigned long b); */ @@ -255,10 +252,15 @@ /* set a platform dependent unsigned long long value */ /* int mp_set_long_long(mp_int *a, unsigned long long b); */ + +/* get a double */ +/* +double mp_get_double(const mp_int *a); +*/ /* get a 32-bit value */ /* unsigned long mp_get_int(const mp_int *a); */ @@ -355,19 +357,24 @@ int mp_cnt_lsb(const mp_int *a); */ /* I Love Earth! */ -/* makes a pseudo-random int of a given size */ +/* makes a pseudo-random mp_int of a given size */ /* int mp_rand(mp_int *a, int digits); */ +/* makes a pseudo-random small int of a given size */ +/* +int mp_rand_digit(mp_digit *r); +*/ #ifdef MP_PRNG_ENABLE_LTM_RNG -/* as last resort we will fall back to libtomcrypt's rng_get_bytes() - * in case you don't use libtomcrypt or use it w/o rng_get_bytes() - * you have to implement it somewhere else, as it's required */ +/* A last resort to provide random data on systems without any of the other + * implemented ways to gather entropy. + * It is compatible with `rng_get_bytes()` from libtomcrypt so you could + * provide that one and then set `ltm_rng = rng_get_bytes;` */ extern unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void)); extern void (*ltm_rng_callback)(void); #endif /* ---> binary operations <--- */ @@ -383,10 +390,17 @@ /* c = a AND b */ /* int mp_and(const mp_int *a, const mp_int *b, mp_int *c); */ + +/* Checks the bit at position b and returns MP_YES + if the bit is 1, MP_NO if it is 0 and MP_VAL + in case of error */ +/* +int mp_get_bit(const mp_int *a, int b); +*/ /* c = a XOR b (two complement) */ /* int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c); */ @@ -578,10 +592,15 @@ /* computes the jacobi c = (a | n) (or Legendre if b is prime) */ /* int mp_jacobi(const mp_int *a, const mp_int *n, int *c); */ + +/* computes the Kronecker symbol c = (a | p) (like jacobi() but with {a,p} in Z */ +/* +int mp_kronecker(const mp_int *a, const mp_int *p, int *c); +*/ /* used to setup the Barrett reduction for a given modulus b */ /* int mp_reduce_setup(mp_int *a, const mp_int *b); */ @@ -700,14 +719,35 @@ */ /* 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 +/* performs one strong Lucas-Selfridge test of "a". + * Sets result to 0 if composite or 1 if probable prime + */ +/* +int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result); +*/ + +/* performs one Frobenius test of "a" as described by Paul Underwood. + * Sets result to 0 if composite or 1 if probable prime + */ +/* +int mp_prime_frobenius_underwood(const mp_int *N, int *result); +*/ + +/* performs t random rounds of Miller-Rabin on "a" additional to + * bases 2 and 3. Also performs an initial sieve of trial * division. Determines if "a" is prime with probability * of error no more than (1/4)**t. + * Both a strong Lucas-Selfridge to complete the BPSW test + * and a separate Frobenius test are available at compile time. + * With t<0 a deterministic test is run for primes up to + * 318665857834031151167461. With t<13 (abs(t)-13) additional + * tests with sequential small primes are run starting at 43. + * Is Fips 186.4 compliant if called with t as computed by + * mp_prime_rabin_miller_trials(); * * Sets result to 1 if probably prime, 0 otherwise */ /* int mp_prime_is_prime(const mp_int *a, int t, int *result); Index: generic/tclTomMathDecls.h ================================================================== --- generic/tclTomMathDecls.h +++ generic/tclTomMathDecls.h @@ -42,13 +42,10 @@ #define KARATSUBA_MUL_CUTOFF TclBNKaratsubaMulCutoff #define KARATSUBA_SQR_CUTOFF TclBNKaratsubaSqrCutoff #define TOOM_MUL_CUTOFF TclBNToomMulCutoff #define TOOM_SQR_CUTOFF TclBNToomSqrCutoff -#define bn_reverse TclBN_reverse -#define fast_s_mp_mul_digs TclBN_fast_s_mp_mul_digs -#define fast_s_mp_sqr TclBN_fast_s_mp_sqr #define mp_add TclBN_mp_add #define mp_add_d TclBN_mp_add_d #define mp_and TclBN_mp_and #define mp_clamp TclBN_mp_clamp #define mp_clear TclBN_mp_clear @@ -76,12 +73,10 @@ #define mp_init_copy TclBN_mp_init_copy #define mp_init_multi TclBN_mp_init_multi #define mp_init_set TclBN_mp_init_set #define mp_init_set_int TclBN_mp_init_set_int #define mp_init_size TclBN_mp_init_size -#define mp_karatsuba_mul TclBN_mp_karatsuba_mul -#define mp_karatsuba_sqr TclBN_mp_karatsuba_sqr #define mp_lshd TclBN_mp_lshd #define mp_mod TclBN_mp_mod #define mp_mod_2d TclBN_mp_mod_2d #define mp_mul TclBN_mp_mul #define mp_mul_2 TclBN_mp_mul_2 @@ -105,20 +100,26 @@ #define mp_tc_div_2d TclBN_mp_tc_div_2d #define mp_tc_or TclBN_mp_tc_or #define mp_tc_xor TclBN_mp_tc_xor #define mp_to_unsigned_bin TclBN_mp_to_unsigned_bin #define mp_to_unsigned_bin_n TclBN_mp_to_unsigned_bin_n -#define mp_toom_mul TclBN_mp_toom_mul -#define mp_toom_sqr TclBN_mp_toom_sqr #define mp_toradix_n TclBN_mp_toradix_n #define mp_unsigned_bin_size TclBN_mp_unsigned_bin_size #define mp_xor TclBN_mp_xor #define mp_zero TclBN_mp_zero -#define s_mp_add TclBN_s_mp_add -#define s_mp_mul_digs TclBN_s_mp_mul_digs -#define s_mp_sqr TclBN_s_mp_sqr -#define s_mp_sub TclBN_s_mp_sub + +MODULE_SCOPE void bn_reverse(unsigned char *s, int len); +MODULE_SCOPE int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs); +MODULE_SCOPE int fast_s_mp_sqr(const mp_int *a, mp_int *b); +MODULE_SCOPE int mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c); +MODULE_SCOPE int mp_karatsuba_sqr(const mp_int *a, mp_int *b); +MODULE_SCOPE int mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c); +MODULE_SCOPE int mp_toom_sqr(const mp_int *a, mp_int *b); +MODULE_SCOPE int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c); +MODULE_SCOPE int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs); +MODULE_SCOPE int s_mp_sqr(const mp_int *a, mp_int *b); +MODULE_SCOPE int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c); #undef TCL_STORAGE_CLASS #ifdef BUILD_tcl # define TCL_STORAGE_CLASS DLLEXPORT #else @@ -605,7 +606,18 @@ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT + +#undef TclBNInitBignumFromLong +#define TclBNInitBignumFromLong(value) TclBNInitBignumFromWideInt((long) value) +#ifdef USE_TCL_STUBS +# undef TclBN_mp_set_long +# ifdef TCL_WIDE_INT_IS_LONG +# define TclBN_mp_set_long(a, b) TclBN_mp_set_long_long(a, (unsigned long)b) +# else +# define TclBN_mp_set_long(a, b) TclBN_mp_set_int(a, b) +# endif +#endif #endif /* _TCLINTDECLS */ Index: generic/tclTomMathInterface.c ================================================================== --- generic/tclTomMathInterface.c +++ generic/tclTomMathInterface.c @@ -11,11 +11,11 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" -#include "tommath.h" +#include "tommath_private.h" MODULE_SCOPE const TclTomMathStubs tclTomMathStubs; /* *---------------------------------------------------------------------- @@ -104,23 +104,28 @@ * The 'bignum' is constructed. * *---------------------------------------------------------------------- */ + +#ifdef TCL_WIDE_INT_IS_LONG +# define TclBN_mp_set_long_long TclBN_mp_set_long +#endif + void TclInitBignumFromWideInt( mp_int *a, /* Bignum to initialize */ Tcl_WideInt v) /* Initial value */ { if (mp_init_size(a, (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) != MP_OKAY) { Tcl_Panic("initialization failure in TclInitBignumFromWideInt"); } if (v < 0) { - mp_set_long_long(a, (Tcl_WideUInt)(-v)); + TclBN_mp_set_long_long(a, (Tcl_WideUInt)(-v)); mp_neg(a, a); } else { - mp_set_long_long(a, (Tcl_WideUInt)v); + TclBN_mp_set_long_long(a, (Tcl_WideUInt)v); } } /* *---------------------------------------------------------------------- @@ -144,15 +149,15 @@ Tcl_WideUInt v) /* Initial value */ { if (mp_init_size(a, (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) != MP_OKAY) { Tcl_Panic("initialization failure in TclInitBignumFromWideUInt"); } - mp_set_long_long(a, v); + TclBN_mp_set_long_long(a, v); } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ Index: libtommath/bn_fast_s_mp_sqr.c ================================================================== --- libtommath/bn_fast_s_mp_sqr.c +++ libtommath/bn_fast_s_mp_sqr.c @@ -77,11 +77,11 @@ if (((unsigned)ix & 1u) == 0u) { _W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1]; } /* store it */ - W[ix] = _W & MP_MASK; + W[ix] = (mp_digit)_W & MP_MASK; /* make next carry */ W1 = _W >> (mp_word)DIGIT_BIT; } Index: libtommath/bn_mp_get_bit.c ================================================================== --- libtommath/bn_mp_get_bit.c +++ libtommath/bn_mp_get_bit.c @@ -25,22 +25,12 @@ return MP_VAL; } limb = b / DIGIT_BIT; - /* - * Zero is a special value with the member "used" set to zero. - * Needs to be tested before the check for the upper boundary - * otherwise (limb >= a->used) would be true for a = 0 - */ - - if (mp_iszero(a) != MP_NO) { - return MP_NO; - } - if (limb >= a->used) { - return MP_VAL; + return MP_NO; } bit = (mp_digit)(1) << (b % DIGIT_BIT); isset = a->dp[limb] & bit; Index: libtommath/bn_mp_get_double.c ================================================================== --- libtommath/bn_mp_get_double.c +++ libtommath/bn_mp_get_double.c @@ -17,12 +17,12 @@ int i; double d = 0.0, fac = 1.0; for (i = 0; i < DIGIT_BIT; ++i) { fac *= 2.0; } - for (i = USED(a); i --> 0;) { - d = (d * fac) + (double)DIGIT(a, i); + for (i = a->used; i --> 0;) { + d = (d * fac) + (double)a->dp[i]; } return (mp_isneg(a) != MP_NO) ? -d : d; } #endif Index: libtommath/bn_mp_get_int.c ================================================================== --- libtommath/bn_mp_get_int.c +++ libtommath/bn_mp_get_int.c @@ -13,29 +13,12 @@ */ /* get the lower 32-bits of an mp_int */ unsigned long mp_get_int(const mp_int *a) { - int i; - mp_min_u32 res; - - if (a->used == 0) { - return 0; - } - - /* get number of digits of the lsb we have to read */ - i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; - - /* get most significant digit of result */ - res = DIGIT(a, i); - - while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a, i); - } - /* force result to 32-bits always so it is consistent on non 32-bit platforms */ - return res & 0xFFFFFFFFUL; + return mp_get_long(a) & 0xFFFFFFFFUL; } #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ Index: libtommath/bn_mp_get_long.c ================================================================== --- libtommath/bn_mp_get_long.c +++ libtommath/bn_mp_get_long.c @@ -24,15 +24,15 @@ /* get number of digits of the lsb we have to read */ i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; /* get most significant digit of result */ - res = DIGIT(a, i); + res = (unsigned long)a->dp[i]; -#if (ULONG_MAX != 0xffffffffuL) || (DIGIT_BIT < 32) +#if (ULONG_MAX != 0xFFFFFFFFUL) || (DIGIT_BIT < 32) while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a, i); + res = (res << DIGIT_BIT) | (unsigned long)a->dp[i]; } #endif return res; } #endif Index: libtommath/bn_mp_get_long_long.c ================================================================== --- libtommath/bn_mp_get_long_long.c +++ libtommath/bn_mp_get_long_long.c @@ -11,28 +11,28 @@ * * SPDX-License-Identifier: Unlicense */ /* get the lower unsigned long long of an mp_int, platform dependent */ -Tcl_WideUInt mp_get_long_long(const mp_int *a) +unsigned TCL_WIDE_INT_TYPE mp_get_long_long(const mp_int *a) { int i; - Tcl_WideUInt res; + unsigned TCL_WIDE_INT_TYPE res; if (a->used == 0) { return 0; } /* get number of digits of the lsb we have to read */ - i = MIN(a->used, ((((int)sizeof(Tcl_WideUInt) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; + i = MIN(a->used, ((((int)sizeof(unsigned TCL_WIDE_INT_TYPE) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; /* get most significant digit of result */ - res = DIGIT(a, i); + res = (unsigned TCL_WIDE_INT_TYPE)a->dp[i]; #if DIGIT_BIT < 64 while (--i >= 0) { - res = (res << DIGIT_BIT) | DIGIT(a, i); + res = (res << DIGIT_BIT) | (unsigned TCL_WIDE_INT_TYPE)a->dp[i]; } #endif return res; } #endif Index: libtommath/bn_mp_is_square.c ================================================================== --- libtommath/bn_mp_is_square.c +++ libtommath/bn_mp_is_square.c @@ -53,11 +53,11 @@ if (arg->used == 0) { return MP_OKAY; } /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ - if (rem_128[127u & DIGIT(arg, 0)] == (char)1) { + if (rem_128[127u & arg->dp[0]] == (char)1) { return MP_OKAY; } /* Next check mod 105 (3*5*7) */ if ((res = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) { Index: libtommath/bn_mp_rand.c ================================================================== --- libtommath/bn_mp_rand.c +++ libtommath/bn_mp_rand.c @@ -16,11 +16,11 @@ * - *BSD * - Windows */ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) #define MP_ARC4RANDOM -#define MP_GEN_RANDOM_MAX 0xffffffffu +#define MP_GEN_RANDOM_MAX 0xFFFFFFFFU #define MP_GEN_RANDOM_SHIFT 32 static int s_read_arc4random(mp_digit *p) { mp_digit d = 0, msk = 0; Index: libtommath/bn_mp_set_double.c ================================================================== --- libtommath/bn_mp_set_double.c +++ libtommath/bn_mp_set_double.c @@ -40,11 +40,11 @@ if (res != MP_OKAY) { return res; } if (((cast.bits >> 63) != 0ULL) && (mp_iszero(a) == MP_NO)) { - SIGN(a) = MP_NEG; + a->sign = MP_NEG; } return MP_OKAY; } #else Index: libtommath/bn_mp_set_int.c ================================================================== --- libtommath/bn_mp_set_int.c +++ libtommath/bn_mp_set_int.c @@ -13,32 +13,11 @@ */ /* set a 32-bit const */ int mp_set_int(mp_int *a, unsigned long b) { - int x, res; - - mp_zero(a); - - /* set four bits at a time */ - for (x = 0; x < 8; x++) { - /* shift the number up four bits */ - if ((res = mp_mul_2d(a, 4, a)) != MP_OKAY) { - return res; - } - - /* OR in the top four bits of the source */ - a->dp[0] |= (mp_digit)(b >> 28) & 15uL; - - /* shift the source up to the next four bits */ - b <<= 4; - - /* ensure that digits are not clamped off */ - a->used += 1; - } - mp_clamp(a); - return MP_OKAY; + return mp_set_long(a, b & 0xFFFFFFFFUL); } #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ Index: libtommath/bn_mp_set_long_long.c ================================================================== --- libtommath/bn_mp_set_long_long.c +++ libtommath/bn_mp_set_long_long.c @@ -11,11 +11,11 @@ * * SPDX-License-Identifier: Unlicense */ /* set a platform dependent unsigned long long int */ -MP_SET_XLONG(mp_set_long_long, Tcl_WideUInt) +MP_SET_XLONG(mp_set_long_long, unsigned TCL_WIDE_INT_TYPE) #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ /* commit time: $Format:%ai$ */ Index: libtommath/tommath.h ================================================================== --- libtommath/tommath.h +++ libtommath/tommath.h @@ -21,11 +21,11 @@ #ifdef __cplusplus extern "C" { #endif /* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ -#if defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__) +#if defined(_WIN32) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__) # define MP_32BIT #endif /* detect 64-bit mode if possible */ #if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \ @@ -43,12 +43,10 @@ # define MP_32BIT # endif # endif #endif -typedef unsigned long long Tcl_WideUInt; - /* some default configurations. * * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits * @@ -63,10 +61,11 @@ # error You must not define DIGIT_BIT when using MP_8BIT # endif #elif defined(MP_16BIT) typedef unsigned short mp_digit; typedef unsigned int mp_word; +#endif # define MP_SIZEOF_MP_DIGIT 2 # ifdef DIGIT_BIT # error You must not define DIGIT_BIT when using MP_16BIT # endif #elif defined(MP_64BIT) @@ -77,11 +76,16 @@ #else /* this is the default case, 28-bit digits */ /* this is to make porting into LibTomCrypt easier :-) */ typedef unsigned int mp_digit; +#ifdef _WIN32 +typedef unsigned __int64 mp_word; +#else typedef unsigned long long mp_word; +#endif +#endif # ifdef MP_31BIT /* this is an extension that uses 31-bit digits */ # define DIGIT_BIT 31 # else @@ -147,14 +151,18 @@ /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ #define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) /* the infamous mp_int structure */ -typedef struct { +#ifndef MP_INT_DECLARED +#define MP_INT_DECLARED +typedef struct mp_int mp_int; +#endif +struct mp_int { 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); @@ -210,11 +218,15 @@ /* set a platform dependent unsigned long value */ int mp_set_long(mp_int *a, unsigned long b); /* set a platform dependent unsigned long long value */ +#ifdef _WIN32 +int mp_set_long_long(mp_int *a, unsigned __int64 b); +#else int mp_set_long_long(mp_int *a, unsigned long long b); +#endif /* get a double */ double mp_get_double(const mp_int *a); /* get a 32-bit value */ @@ -222,11 +234,15 @@ /* get a platform dependent unsigned long value */ unsigned long mp_get_long(const mp_int *a); /* get a platform dependent unsigned long long value */ +#ifdef _WIN32 +unsigned __int64 mp_get_long_long(const mp_int *a); +#else unsigned long long mp_get_long_long(const mp_int *a); +#endif /* initialize and set a digit */ int mp_init_set(mp_int *a, mp_digit b); /* initialize and set 32-bit value */ Index: libtommath/tommath_private.h ================================================================== --- libtommath/tommath_private.h +++ libtommath/tommath_private.h @@ -83,33 +83,20 @@ * b is the original value that should be set in the MPI. */ #define MP_SET_XLONG(func_name, type) \ int func_name (mp_int * a, type b) \ { \ - unsigned int x; \ - int res; \ - \ - mp_zero (a); \ - \ - /* set four bits at a time */ \ - for (x = 0; x < (sizeof(type) * 2u); x++) { \ - /* shift the number up four bits */ \ - if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { \ - return res; \ - } \ - \ - /* OR in the top four bits of the source */ \ - a->dp[0] |= (mp_digit)(b >> ((sizeof(type) * 8u) - 4u)) & 15uL;\ - \ - /* shift the source up to the next four bits */ \ - b <<= 4; \ - \ - /* ensure that digits are not clamped off */ \ - a->used += 1; \ - } \ - mp_clamp (a); \ - return MP_OKAY; \ + unsigned int x = 0; \ + int res = mp_grow(a, (CHAR_BIT * sizeof(type) + DIGIT_BIT - 1) / DIGIT_BIT); \ + if (res == MP_OKAY) { \ + while (b) { \ + a->dp[x++] = ((mp_digit)b & MP_MASK); \ + b >>= DIGIT_BIT; \ + } \ + a->used = x; \ + } \ + return res; \ } #ifdef __cplusplus } #endif