From 997d47f0cb4f59f61420b05bc2fe95ac4534a589 Mon Sep 17 00:00:00 2001 From: czurnieden Date: Fri, 6 Sep 2019 18:06:27 +0200 Subject: [PATCH 1/7] Addition of mp_radix_size_overestimate (behaviour like the function mpz_sizeinbase in GMP); changed mp_radix_size to use mp_ilogb --- bn_mp_fwrite.c | 1 + bn_mp_radix_size.c | 60 +++++--- bn_mp_radix_size_overestimate.c | 258 ++++++++++++++++++++++++++++++++ demo/test.c | 91 +++++++++++ doc/bn.tex | 12 +- libtommath_VS2008.vcproj | 4 + makefile | 26 ++-- makefile.mingw | 26 ++-- makefile.msvc | 26 ++-- makefile.shared | 26 ++-- makefile.unix | 26 ++-- tommath.def | 1 + tommath.h | 8 +- tommath_class.h | 17 ++- 14 files changed, 488 insertions(+), 94 deletions(-) create mode 100644 bn_mp_radix_size_overestimate.c diff --git a/bn_mp_fwrite.c b/bn_mp_fwrite.c index abe2e6717..2471d8948 100644 --- a/bn_mp_fwrite.c +++ b/bn_mp_fwrite.c @@ -33,6 +33,7 @@ mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) err = MP_ERR; goto LBL_ERR; } + err = MP_OKAY; diff --git a/bn_mp_radix_size.c b/bn_mp_radix_size.c index b96f4874c..6e78efffb 100644 --- a/bn_mp_radix_size.c +++ b/bn_mp_radix_size.c @@ -6,10 +6,12 @@ /* returns size of ASCII representation */ mp_err mp_radix_size(const mp_int *a, int radix, int *size) { - mp_err err; + + mp_err err; int digs; mp_int t; mp_digit d; + mp_int a_, b; *size = 0; @@ -23,42 +25,52 @@ mp_err mp_radix_size(const mp_int *a, int radix, int *size) return MP_OKAY; } - /* special case for binary */ - if (radix == 2) { - *size = (mp_count_bits(a) + ((a->sign == MP_NEG) ? 1 : 0) + 1); + /* A small shortcut for powers of two. */ + if (!(radix&(radix-1))) { + unsigned int x = (unsigned int)radix; + int y, bit_count, rem; + for (y=0; (y < 7) && !(x & 1u); y++) { + x >>= 1; + } + bit_count = mp_count_bits(a); + *size = bit_count/y; + rem = bit_count - ((*size) * y); + /* Add 1 for the remainder if any and 1 for "\0". */ + *size += (rem == 0) ? 1 : 2; + /* And one extra character for the minus sign */ + if (a->sign == MP_NEG) { + (*size)++; + } return MP_OKAY; } - /* digs is the digit count */ - digs = 0; - /* if it's negative add one for the sign */ - if (a->sign == MP_NEG) { - ++digs; + + if ((err = mp_init(&b)) != MP_OKAY) { + goto LBL_ERR; } - /* init a copy of the input */ - if ((err = mp_init_copy(&t, a)) != MP_OKAY) { - return err; + a_ = *a; + a_.sign = MP_ZPOS; + if ((err = mp_ilogb(&a_, (uint32_t)radix, &b)) != MP_OKAY) { + goto LBL_ERR; } - /* force temp to positive */ - t.sign = MP_ZPOS; + *size = (int)mp_get_l(&b); - /* fetch out all of the digits */ - while (!MP_IS_ZERO(&t)) { - if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) { - goto LBL_ERR; - } - ++digs; + /* mp_ilogb truncates to zero, hence we need one extra put on top. */ + (*size)++; + + /* The sign needs to have a place to live, too*/ + if (a->sign == MP_NEG) { + (*size)++; } - /* return digs + 1, the 1 is for the NULL byte that would be required. */ - *size = digs + 1; - err = MP_OKAY; + /* return digs + 1, the 1 is for the NUL byte that would be required. */ + (*size)++; LBL_ERR: - mp_clear(&t); + mp_clear(&b); return err; } diff --git a/bn_mp_radix_size_overestimate.c b/bn_mp_radix_size_overestimate.c new file mode 100644 index 000000000..86cae8acd --- /dev/null +++ b/bn_mp_radix_size_overestimate.c @@ -0,0 +1,258 @@ +#include "tommath_private.h" +#ifdef BN_MP_RADIX_SIZE_OVERESTIMATE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + + + +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* returns size of ASCII representation */ + +/* + + Behaves like the function mp(n|z)_sizeinbase of GMP for all digit-sizes except MP_8BIT + and MP_16BIT (if the "int" for MP_16BIT has more than 16 bits) where it can overshoot by two. + The results for bases that are powers-of-two are exact. +*/ + +/* + Tables of {0, log_2([1..64])} times 2^p where p is the scale + factor defined in LTM_RADIX_SIZE_SCALE. + + The tables have been computed with GP/PARI 2.9.4 with the + x86-64/GMP-5.1.3 kernel and (unnecessary) 100 decimal digits + precision. The fractional parts of the results after the + multiplication by 2^p have been discarded (floor(x)). + + The number that measures the number of the digits of the bignum is + of type "int" which is at least 16 bits large and is 32 bit on the + architectures common at the time of writing. If you have hard- or + software that has a different size, please feel free to contact the + author, adding another table can be done quite quickly! + */ + +/* *INDENT-OFF* */ +#ifdef MP_8BIT +#define LTM_RADIX_SIZE_SCALE 29 +#define LTM_RADIX_SIZE_HALF_TABLE_SCALE 16 +static const mp_word logbases_high[65] = { + 0u, 0u, 8192u, 12984u, 16384u, + 19021u, 21176u, 22997u, 24576u, 25968u, + 27213u, 28339u, 29368u, 30314u, 31189u, + 32005u, 32768u, 33484u, 34160u, 34799u, + 35405u, 35981u, 36531u, 37057u, 37560u, + 38042u, 38506u, 38952u, 39381u, 39796u, + 40197u, 40584u, 40960u, 41323u, 41676u, + 42019u, 42352u, 42675u, 42991u, 43298u, + 43597u, 43889u, 44173u, 44451u, 44723u, + 44989u, 45249u, 45503u, 45752u, 45995u, + 46234u, 46468u, 46698u, 46923u, 47144u, + 47360u, 47573u, 47783u, 47988u, 48190u, + 48389u, 48584u, 48776u, 48965u, 49152u +}; +static const mp_word logbases_low[65] = { + 0u, 0u, 0u, 839u, 0u, + 15397u, 839u, 55805u, 0u, 1678u, + 15397u, 43504u, 839u, 142u, 55805u, + 16237u, 0u, 32479u, 1678u, 1454u, + 15397u, 56644u, 43504u, 1280u, 839u, + 30795u, 142u, 2517u, 55805u, 38031u, + 16237u, 50867u, 0u, 44343u, 32479u, + 5667u, 1678u, 55179u, 1454u, 981u, + 15397u, 4326u, 56644u, 62971u, 43504u, + 17076u, 1280u, 12574u, 839u, 46074u, + 30795u, 33318u, 142u, 8150u, 2517u, + 58902u, 55805u, 2293u, 38031u, 40098u, + 16237u, 39339u, 50867u, 57483u, 0u +}; +#elif (defined MP_16BIT) +#define LTM_RADIX_SIZE_SCALE 61 +#define LTM_RADIX_SIZE_HALF_TABLE_SCALE 32 +static const mp_word logbases_high[65] = { + 0ul, 0ul, 536870912ul, 850920263ul, 1073741824ul, + 1246575653ul, 1387791175ul, 1507187197ul, 1610612736ul, 1701840526ul, + 1783446565ul, 1857268208ul, 1924662087ul, 1986658446ul, 2044058109ul, + 2097495917ul, 2147483648ul, 2194439903ul, 2238711438ul, 2280588718ul, + 2320317477ul, 2358107460ul, 2394139120ul, 2428568832ul, 2461532999ul, + 2493151307ul, 2523529358ul, 2552760789ul, 2580929021ul, 2608108687ul, + 2634366829ul, 2659763891ul, 2684354560ul, 2708188471ul, 2731310815ul, + 2753762851ul, 2775582350ul, 2796803979ul, 2817459630ul, 2837578709ul, + 2857188389ul, 2876313830ul, 2894978372ul, 2913203707ul, 2931010032ul, + 2948416180ul, 2965439744ul, 2982097182ul, 2998403911ul, 3014374394ul, + 3030022219ul, 3045360166ul, 3060400270ul, 3075153878ul, 3089631701ul, + 3103843862ul, 3117799933ul, 3131508981ul, 3144979599ul, 3158219938ul, + 3171237741ul, 3184040363ul, 3196634803ul, 3209027723ul, 3221225472ul +}; +static const mp_word logbases_low[65] = { + 0ul, 0ul, 0ul, 1065013491ul, 0ul, + 3868050815ul, 1065013491ul, 1343271782ul, 0ul, 2130026983ul, + 3868050815ul, 427100031ul, 1065013491ul, 1200147405ul, 1343271782ul, + 638097011ul, 0ul, 1495425743ul, 2130026983ul, 1083835016ul, + 3868050815ul, 2408285274ul, 427100031ul, 3594167896ul, 1065013491ul, + 3441134334ul, 1200147405ul, 3195040475ul, 1343271782ul, 1429396043ul, + 638097011ul, 1651143338ul, 0ul, 1492113523ul, 1495425743ul, + 916355301ul, 2130026983ul, 1832592635ul, 1083835016ul, 2265160897ul, + 3868050815ul, 3464916779ul, 2408285274ul, 2621526098ul, 427100031ul, + 1703110503ul, 3594167896ul, 2513440227ul, 1065013491ul, 2686543564ul, + 3441134334ul, 2560439235ul, 1200147405ul, 1309103046ul, 3195040475ul, + 183550ul, 1343271782ul, 2148848508ul, 1429396043ul, 3785381171ul, + 638097011ul, 1073048670ul, 1651143338ul, 3473298766ul, 0ul +}; + +/* TODO: This assumes the type "long long" exists. If it doesn't: use the tables for MP_16BIT */ +#elif ( (defined MP_28BIT) || (defined MP_31BIT) || (defined MP_32BIT) || (defined MP_64BIT) ) +#define LTM_RADIX_SIZE_SCALE 61 +#ifdef MP_64BIT +static const mp_digit logbases[65] = { +#else +static const mp_word logbases[65] = { +#endif + 0ull, 0ull, 2305843009213693952ull, + 3654674702153732339ull, 4611686018427387904ull, 5354001665492895103ull, + 5960517711367426291ull, 6473319721408181094ull, 6917529027641081856ull, + 7309349404307464679ull, 7659844674706589055ull, 7976906213687625599ull, + 8266360720581120243ull, 8532633055092329421ull, 8779162730621875046ull, + 9008676367646627443ull, 9223372036854775808ull, 9425047617917838031ull, + 9615192413521158631ull, 9795053960520401544ull, 9965687683920283007ull, + 10127994423561913434ull, 10282749222901319551ull, 10430623713119086168ull, + 10572203729794814195ull, 10708003330985790206ull, 10838476064306023373ull, + 10964024106461197019ull, 11085005739835568998ull, 11201741516507896395ull, + 11314519376860321395ull, 11423598928577852074ull, 11529215046068469760ull, + 11631580915841357939ull, 11730890627131531983ull, 11827321386901076197ull, + 11921035422734852583ull, 12012181624960263419ull, 12100896969734095496ull, + 12187307757246061761ull, 12271530693133976959ull, 12353673836347420459ull, + 12433837432775607386ull, 12512114650772492370ull, 12588592232115013503ull, + 12663351069800359783ull, 12736466722332780120ull, 12808009872697200099ull, + 12878046739008508147ull, 12946639442816362188ull, 13013846340199484158ull, + 13079722320071570371ull, 13144319073519717325ull, 13207685337486676934ull, + 13269867115674890971ull, 13330907879180520702ull, 13390848749049262950ull, + 13449728662674133884ull, 13507584525721590347ull, 13564451351070528819ull, + 13620362386074015347ull, 13675349229302017118ull, 13729441937791546026ull, + 13782669125715645774ull, 13835058055282163712ull +}; +#else +# ifdef _MSC_VER +# pragma message("mp_radix_size_overestimate: unknown or undefined MP_xBIT type") +# else +# warning "mp_radix_size_overestimate: unknown or undefined MP_xBIT type" +# endif +#endif +/* *INDENT-ON* */ + +mp_err mp_radix_size_overestimate(const mp_int *a, const int base, int *size) +{ + mp_int bi_bit_count, bi_k; +#if ( (defined MP_8BIT) || (defined MP_16BIT) ) + mp_int bi_k_bis; +#endif + int rem, bit_count; + mp_err e = MP_OKAY; + + if ((base < 2) || (base > 64)) { + *size = 0; + return MP_VAL; + } + /* floor( log_2(a) ) + 1 */ + bit_count = mp_count_bits(a); + + if (bit_count == 0) { + *size = 2; + return MP_OKAY; + } + if (base == 2) { + *size = bit_count + 2; + return MP_OKAY; + } + + /* A small shortcut for powers of two. */ + if (!(base&(base-1))) { + unsigned int x = (unsigned int)base; + int y; + for (y=0; (y < 7) && !(x & 1u); y++) { + x >>= 1; + } + *size = bit_count/y; + rem = bit_count - ((*size) * y); + /* Add 1 for the remainder if any and 1 for "\0". */ + *size += (rem == 0) ? 1 : 2; + /* And one extra character for the minus sign */ + if (a->sign == MP_NEG) { + (*size)++; + } + return MP_OKAY; + } + + /* d(bitcount,base) = floor( (bitcount * 2^p) / k(base) ) + 1 */ + + if ((e = mp_init_multi(&bi_bit_count, &bi_k, NULL)) != MP_OKAY) { + *size = 0; + return e; + } +#if ( (defined MP_8BIT) || (defined MP_16BIT) ) + if ((e = mp_init(&bi_k_bis)) != MP_OKAY) { + /* No "goto" to avoid cluttering this code with even more preprocessor branches */ + mp_clear_multi(&bi_bit_count, &bi_k, NULL); + *size = 0; + return e; + } +#endif + /* "long" is at least as large as "int" according to even the oldest C standards */ + mp_set_l(&bi_bit_count, bit_count); +#if ( (defined MP_8BIT) || (defined MP_16BIT) ) + /* There is no mp_set_u16 for MP_8BIT */ + mp_set_u32(&bi_k, logbases_high[base]); + if ((e = mp_mul_2d(&bi_k, LTM_RADIX_SIZE_HALF_TABLE_SCALE, &bi_k)) != MP_OKAY) { + *size = 0; + goto LTM_E1; + } + mp_set_u32(&bi_k_bis, logbases_low[base]); + if ((e = mp_add(&bi_k_bis, &bi_k, &bi_k)) != MP_OKAY) { + *size = 0; + goto LTM_E1; + } +#else + mp_set_u64(&bi_k, logbases[base]); +#endif + if ((e = mp_mul_2d(&bi_bit_count, LTM_RADIX_SIZE_SCALE, &bi_bit_count)) != MP_OKAY) { + *size = 0; + goto LTM_E1; + } + if ((e = mp_div(&bi_bit_count, &bi_k, &bi_bit_count, NULL)) != MP_OKAY) { + *size = 0; + goto LTM_E1; + } + /* + The first addition of one is done because of the truncating last division, + and the second addition of one is done to make room for NIL ('\0'). + + Casting from "long" to "int" can be done because "bi_bit_count" fits into an "int" + by definition. + */ + *size = (int)mp_get_l(&bi_bit_count) + 1 + 1 ; + +#if ( (defined MP_8BIT) && (INT_MAX > 0xFFFF)) + /* TODO: Add a third table? But how likely is it that "int" is 32-bit in + an 8-bit environment? */ + /* diff. is 3 bits, hence add 2 (two) */ + *size += 2; +#endif + + /* And before we forget it: one extra character for the minus sign */ + if (a->sign == MP_NEG) { + (*size)++; + } + +LTM_E1: + mp_clear_multi(&bi_bit_count, &bi_k, NULL); +#if ( (defined MP_8BIT) || (defined MP_16BIT) ) + mp_clear(&bi_k_bis); +#endif + return e; +} + + + + +#endif diff --git a/demo/test.c b/demo/test.c index 81f5afee5..130146eed 100644 --- a/demo/test.c +++ b/demo/test.c @@ -2296,6 +2296,94 @@ static int test_s_mp_toom_sqr(void) mp_clear_multi(&a, &b, &c, NULL); return EXIT_FAILURE; } +static int test_mp_radix_size(void) +{ + mp_err err; + mp_int a; + int radix, size; +/* *INDENT-OFF* */ + int results[65] = { + 0, 0, 1627, 1027, 814, 702, 630, 581, 543, + 514, 491, 471, 455, 441, 428, 418, 408, 399, + 391, 384, 378, 372, 366, 361, 356, 352, 347, + 343, 340, 336, 333, 330, 327, 324, 321, 318, + 316, 314, 311, 309, 307, 305, 303, 301, 299, + 298, 296, 294, 293, 291, 290, 288, 287, 285, + 284, 283, 281, 280, 279, 278, 277, 276, 275, + 273, 272 + }; +/* *INDENT-ON* */ + + mp_init(&a); + + /* number to result in a different size for every base: 67^(4 * 67) */ + mp_set(&a, 67); + if ((err = mp_expt_u32(&a, 268u, &a)) != MP_OKAY) { + goto LTM_ERR; + } + + for (radix = 2; radix < 65; radix++) { + if ((err = mp_radix_size(&a, radix, &size)) != MP_OKAY) { + goto LTM_ERR; + } + if (size != results[radix]) { + fprintf(stderr, "mp_radix_size: result for base %d was %d instead of %d\n", + radix, size, results[radix]); + goto LTM_ERR; + } + } + + mp_clear(&a); + return EXIT_SUCCESS; +LTM_ERR: + mp_clear(&a); + return EXIT_FAILURE; +} + +static int test_mp_radix_size_overestimate(void) +{ + + mp_err err; + mp_int a; + int radix, size; +/* *INDENT-OFF* */ + int results[65] = { + 0, 0, 1627, 1027, 814, 702, 630, 581, 543, + 514, 491, 471, 455, 441, 428, 418, 408, 399, + 391, 384, 378, 372, 366, 361, 356, 352, 347, + 343, 340, 336, 333, 330, 327, 324, 321, 318, + 316, 314, 311, 309, 307, 305, 303, 301, 299, + 298, 296, 294, 293, 291, 290, 288, 287, 285, + 284, 283, 281, 280, 279, 278, 277, 276, 275, + 273, 272 + }; +/* *INDENT-ON* */ + + mp_init(&a); + + /* number to result in a different size for every base: 67^(4 * 67) */ + mp_set(&a, 67); + if ((err = mp_expt_u32(&a, 268u, &a)) != MP_OKAY) { + goto LTM_ERR; + } + + for (radix = 2; radix < 65; radix++) { + if ((err = mp_radix_size_overestimate(&a, radix, &size)) != MP_OKAY) { + goto LTM_ERR; + } + if (size < results[radix]) { + fprintf(stderr, "mp_radix_size_overestimate: result for base %d was %d instead of %d\n", + radix, size, results[radix]); + goto LTM_ERR; + } + } + + mp_clear(&a); + return EXIT_SUCCESS; +LTM_ERR: + mp_clear(&a); + return EXIT_FAILURE; +} static int test_mp_read_write_ubin(void) { @@ -2426,6 +2514,7 @@ static int unit_tests(int argc, char **argv) const char *name; int (*fn)(void); } test[] = { + #define T0(n) { #n, test_##n } #define T1(n, o) { #n, MP_HAS(o) ? test_##n : NULL } #define T2(n, o1, o2) { #n, MP_HAS(o1) && MP_HAS(o2) ? test_##n : NULL } @@ -2461,6 +2550,8 @@ static int unit_tests(int argc, char **argv) T1(mp_read_write_sbin, MP_TO_SBIN), T1(mp_reduce_2k, MP_REDUCE_2K), T1(mp_reduce_2k_l, MP_REDUCE_2K_L), + T1(mp_radix_size, MP_RADIX_SIZE), + T1(mp_radix_size_overestimate, MP_RADIX_SIZE_OVERESTIMATE), #if defined(__STDC_IEC_559__) || defined(__GCC_IEC_559) T1(mp_set_double, MP_SET_DOUBLE), #endif diff --git a/doc/bn.tex b/doc/bn.tex index 0a9939256..713947cee 100644 --- a/doc/bn.tex +++ b/doc/bn.tex @@ -2118,8 +2118,16 @@ \subsection{To ASCII} \begin{alltt} int mp_radix_size (mp_int * a, int radix, int *size) \end{alltt} -This stores in ``size'' the number of characters (including space for the NUL terminator) required. Upon error this -function returns an error code and ``size'' will be zero. +This stores in ``size'' the exact number of characters (including space for the NUL terminator) required. Upon error this function returns an error code and ``size'' will be zero. It uses \texttt{mp\_ilogb} to compute the size in O(log n) with quite a large overhead. This function is deprecated in favor of +\texttt{mp\_radix\_sizeinbase} described below. If the exact size is still required after the removal of this function use \texttt{mp\_ilogb} directly. + +\index{mp\_radix\_overestimate} +\begin{alltt} +int mp_radix_size_overestimate (mp_int * a, int radix, int *size) +\end{alltt} +This stores in ``size'' the number of characters (including space for the NUL terminator) required. Upon error this function returns an error code and ``size'' will be zero. This function can overshoot by one (two in case of \texttt{MP\_8BIT} and also for \texttt{MP\_16BIT} if the type \texttt{int} has more than 16 bits). The results for bases that are powers-of-two are exact. It uses tables to compute the result in O(1) with quite a small overhead. + +The behavior is similar to the behavior of the function \texttt{mpn\_sizeinbase} in GMP for \texttt{MP\_32BIT}, and \texttt{MP\_64BIT}. If \texttt{LTM\_NO\_FILE} is not defined a function to write to a file is also available. \index{mp\_fwrite} diff --git a/libtommath_VS2008.vcproj b/libtommath_VS2008.vcproj index 960d75635..65480ed0f 100644 --- a/libtommath_VS2008.vcproj +++ b/libtommath_VS2008.vcproj @@ -684,6 +684,10 @@ RelativePath="bn_mp_radix_size.c" > + + diff --git a/makefile b/makefile index eecc85274..b7370174a 100644 --- a/makefile +++ b/makefile @@ -42,19 +42,19 @@ bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \ bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \ -bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \ -bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \ -bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o \ -bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o \ -bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o \ -bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o \ -bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o \ -bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o \ -bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o \ -bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o bn_s_mp_prime_is_divisible.o \ -bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \ -bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o +bn_mp_radix_size.o bn_mp_radix_size_overestimate.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o \ +bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o \ +bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o \ +bn_mp_sbin_size.o bn_mp_set.o bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o \ +bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o \ +bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o \ +bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o \ +bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o \ +bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o \ +bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o \ +bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \ +bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \ +bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o #END_INS diff --git a/makefile.mingw b/makefile.mingw index 08db73ef6..3296d5bd9 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -45,19 +45,19 @@ bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \ bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \ -bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \ -bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \ -bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o \ -bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o \ -bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o \ -bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o \ -bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o \ -bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o \ -bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o \ -bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o bn_s_mp_prime_is_divisible.o \ -bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \ -bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o +bn_mp_radix_size.o bn_mp_radix_size_overestimate.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o \ +bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o \ +bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o \ +bn_mp_sbin_size.o bn_mp_set.o bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o \ +bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o \ +bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o \ +bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o \ +bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o \ +bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o \ +bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o \ +bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \ +bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \ +bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o HEADERS_PUB=tommath.h HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB) diff --git a/makefile.msvc b/makefile.msvc index 577235f5d..3d060b9b3 100644 --- a/makefile.msvc +++ b/makefile.msvc @@ -37,19 +37,19 @@ bn_mp_montgomery_setup.obj bn_mp_mul.obj bn_mp_mul_2.obj bn_mp_mul_2d.obj bn_mp_ bn_mp_or.obj bn_mp_pack.obj bn_mp_pack_count.obj bn_mp_prime_fermat.obj bn_mp_prime_frobenius_underwood.obj \ bn_mp_prime_is_prime.obj bn_mp_prime_miller_rabin.obj bn_mp_prime_next_prime.obj \ bn_mp_prime_rabin_miller_trials.obj bn_mp_prime_rand.obj bn_mp_prime_strong_lucas_selfridge.obj \ -bn_mp_radix_size.obj bn_mp_radix_smap.obj bn_mp_rand.obj bn_mp_read_radix.obj bn_mp_reduce.obj bn_mp_reduce_2k.obj \ -bn_mp_reduce_2k_l.obj bn_mp_reduce_2k_setup.obj bn_mp_reduce_2k_setup_l.obj bn_mp_reduce_is_2k.obj \ -bn_mp_reduce_is_2k_l.obj bn_mp_reduce_setup.obj bn_mp_root_u32.obj bn_mp_rshd.obj bn_mp_sbin_size.obj bn_mp_set.obj \ -bn_mp_set_double.obj bn_mp_set_i32.obj bn_mp_set_i64.obj bn_mp_set_l.obj bn_mp_set_ll.obj bn_mp_set_u32.obj \ -bn_mp_set_u64.obj bn_mp_set_ul.obj bn_mp_set_ull.obj bn_mp_shrink.obj bn_mp_signed_rsh.obj bn_mp_sqr.obj \ -bn_mp_sqrmod.obj bn_mp_sqrt.obj bn_mp_sqrtmod_prime.obj bn_mp_sub.obj bn_mp_sub_d.obj bn_mp_submod.obj \ -bn_mp_to_radix.obj bn_mp_to_sbin.obj bn_mp_to_ubin.obj bn_mp_ubin_size.obj bn_mp_unpack.obj bn_mp_xor.obj bn_mp_zero.obj \ -bn_prime_tab.obj bn_s_mp_add.obj bn_s_mp_balance_mul.obj bn_s_mp_exptmod.obj bn_s_mp_exptmod_fast.obj \ -bn_s_mp_get_bit.obj bn_s_mp_invmod_fast.obj bn_s_mp_invmod_slow.obj bn_s_mp_karatsuba_mul.obj \ -bn_s_mp_karatsuba_sqr.obj bn_s_mp_montgomery_reduce_fast.obj bn_s_mp_mul_digs.obj bn_s_mp_mul_digs_fast.obj \ -bn_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs_fast.obj bn_s_mp_prime_is_divisible.obj \ -bn_s_mp_rand_jenkins.obj bn_s_mp_rand_platform.obj bn_s_mp_reverse.obj bn_s_mp_sqr.obj bn_s_mp_sqr_fast.obj \ -bn_s_mp_sub.obj bn_s_mp_toom_mul.obj bn_s_mp_toom_sqr.obj +bn_mp_radix_size.obj bn_mp_radix_size_overestimate.obj bn_mp_radix_smap.obj bn_mp_rand.obj bn_mp_read_radix.obj \ +bn_mp_reduce.obj bn_mp_reduce_2k.obj bn_mp_reduce_2k_l.obj bn_mp_reduce_2k_setup.obj bn_mp_reduce_2k_setup_l.obj \ +bn_mp_reduce_is_2k.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_setup.obj bn_mp_root_u32.obj bn_mp_rshd.obj \ +bn_mp_sbin_size.obj bn_mp_set.obj bn_mp_set_double.obj bn_mp_set_i32.obj bn_mp_set_i64.obj bn_mp_set_l.obj \ +bn_mp_set_ll.obj bn_mp_set_u32.obj bn_mp_set_u64.obj bn_mp_set_ul.obj bn_mp_set_ull.obj bn_mp_shrink.obj \ +bn_mp_signed_rsh.obj bn_mp_sqr.obj bn_mp_sqrmod.obj bn_mp_sqrt.obj bn_mp_sqrtmod_prime.obj bn_mp_sub.obj bn_mp_sub_d.obj \ +bn_mp_submod.obj bn_mp_to_radix.obj bn_mp_to_sbin.obj bn_mp_to_ubin.obj bn_mp_ubin_size.obj bn_mp_unpack.obj \ +bn_mp_xor.obj bn_mp_zero.obj bn_prime_tab.obj bn_s_mp_add.obj bn_s_mp_balance_mul.obj bn_s_mp_exptmod.obj \ +bn_s_mp_exptmod_fast.obj bn_s_mp_get_bit.obj bn_s_mp_invmod_fast.obj bn_s_mp_invmod_slow.obj \ +bn_s_mp_karatsuba_mul.obj bn_s_mp_karatsuba_sqr.obj bn_s_mp_montgomery_reduce_fast.obj bn_s_mp_mul_digs.obj \ +bn_s_mp_mul_digs_fast.obj bn_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs_fast.obj \ +bn_s_mp_prime_is_divisible.obj bn_s_mp_rand_jenkins.obj bn_s_mp_rand_platform.obj bn_s_mp_reverse.obj \ +bn_s_mp_sqr.obj bn_s_mp_sqr_fast.obj bn_s_mp_sub.obj bn_s_mp_toom_mul.obj bn_s_mp_toom_sqr.obj HEADERS_PUB=tommath.h HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB) diff --git a/makefile.shared b/makefile.shared index 130212d09..5b444bc17 100644 --- a/makefile.shared +++ b/makefile.shared @@ -39,19 +39,19 @@ bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \ bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \ -bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \ -bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \ -bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o \ -bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o \ -bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o \ -bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o \ -bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o \ -bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o \ -bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o \ -bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o bn_s_mp_prime_is_divisible.o \ -bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \ -bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o +bn_mp_radix_size.o bn_mp_radix_size_overestimate.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o \ +bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o \ +bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o \ +bn_mp_sbin_size.o bn_mp_set.o bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o \ +bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o \ +bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o \ +bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o \ +bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o \ +bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o \ +bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o \ +bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \ +bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \ +bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o #END_INS diff --git a/makefile.unix b/makefile.unix index aa5e920c3..f58ce36f7 100644 --- a/makefile.unix +++ b/makefile.unix @@ -46,19 +46,19 @@ bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \ bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \ bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \ -bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \ -bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \ -bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \ -bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o \ -bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o \ -bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o \ -bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o \ -bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o \ -bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o \ -bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o \ -bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o bn_s_mp_prime_is_divisible.o \ -bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \ -bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o +bn_mp_radix_size.o bn_mp_radix_size_overestimate.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o \ +bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o \ +bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o \ +bn_mp_sbin_size.o bn_mp_set.o bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o \ +bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o \ +bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o \ +bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o \ +bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o \ +bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o \ +bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o \ +bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \ +bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \ +bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o HEADERS_PUB=tommath.h HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB) diff --git a/tommath.def b/tommath.def index b814186e9..6a644c687 100644 --- a/tommath.def +++ b/tommath.def @@ -101,6 +101,7 @@ EXPORTS mp_prime_rand mp_prime_strong_lucas_selfridge mp_radix_size + mp_radix_size_overestimate mp_rand mp_read_radix mp_reduce diff --git a/tommath.h b/tommath.h index 1e0192b74..597e9c13e 100644 --- a/tommath.h +++ b/tommath.h @@ -749,9 +749,15 @@ mp_err mp_to_sbin(const mp_int *a, unsigned char *buf, size_t maxlen, size_t *wr mp_err mp_read_radix(mp_int *a, const char *str, int radix) MP_WUR; MP_DEPRECATED(mp_to_radix) mp_err mp_toradix(const mp_int *a, char *str, int radix) MP_WUR; MP_DEPRECATED(mp_to_radix) mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) MP_WUR; + mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, int radix) MP_WUR; mp_err mp_radix_size(const mp_int *a, int radix, int *size) MP_WUR; - +/* + Can overshoot by one or two characters but is O(1) (table based with a very small overhead) + Behaves like the function mp(n|z)_sizeinbase of GMP for all digit-sizes except MP_8BIT + and MP_16BIT (if the "int" for MP_16BIT has more than 16 bits) where it can overshoot by two. + */ +mp_err mp_radix_size_overestimate(const mp_int *a, const int base, int *size) MP_WUR; #ifndef MP_NO_FILE mp_err mp_fread(mp_int *a, int radix, FILE *stream) MP_WUR; mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) MP_WUR; diff --git a/tommath_class.h b/tommath_class.h index 3abb55a68..18522715d 100644 --- a/tommath_class.h +++ b/tommath_class.h @@ -104,6 +104,7 @@ # define BN_MP_PRIME_RAND_C # define BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C # define BN_MP_RADIX_SIZE_C +# define BN_MP_RADIX_SIZE_OVERESTIMATE_C # define BN_MP_RADIX_SMAP_C # define BN_MP_RAND_C # define BN_MP_READ_RADIX_C @@ -840,8 +841,20 @@ #if defined(BN_MP_RADIX_SIZE_C) # define BN_MP_CLEAR_C # define BN_MP_COUNT_BITS_C -# define BN_MP_DIV_D_C -# define BN_MP_INIT_COPY_C +# define BN_MP_GET_L_C +# define BN_MP_ILOGB_C +# define BN_MP_INIT_C +#endif + +#if defined(BN_MP_RADIX_SIZE_OVERESTIMATE_C) +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_DIV_C +# define BN_MP_GET_L_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_MUL_2D_C +# define BN_MP_SET_L_C +# define BN_MP_SET_U64_C #endif #if defined(BN_MP_RADIX_SMAP_C) From 1191eaba0d0ebef189736377fb23961799aad1a5 Mon Sep 17 00:00:00 2001 From: czurnieden Date: Sun, 6 Oct 2019 23:07:25 +0200 Subject: [PATCH 2/7] compute all bases of a power of two in the same way --- bn_mp_radix_size_overestimate.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bn_mp_radix_size_overestimate.c b/bn_mp_radix_size_overestimate.c index 86cae8acd..19a36f3b5 100644 --- a/bn_mp_radix_size_overestimate.c +++ b/bn_mp_radix_size_overestimate.c @@ -161,10 +161,6 @@ mp_err mp_radix_size_overestimate(const mp_int *a, const int base, int *size) *size = 2; return MP_OKAY; } - if (base == 2) { - *size = bit_count + 2; - return MP_OKAY; - } /* A small shortcut for powers of two. */ if (!(base&(base-1))) { From cb17f0ec54b6f6bf433b903df3f49fd60a412427 Mon Sep 17 00:00:00 2001 From: czurnieden Date: Mon, 7 Oct 2019 00:38:47 +0200 Subject: [PATCH 3/7] moved check for zero to an earlier point --- bn_mp_radix_size_overestimate.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bn_mp_radix_size_overestimate.c b/bn_mp_radix_size_overestimate.c index 19a36f3b5..347d66cf1 100644 --- a/bn_mp_radix_size_overestimate.c +++ b/bn_mp_radix_size_overestimate.c @@ -154,14 +154,15 @@ mp_err mp_radix_size_overestimate(const mp_int *a, const int base, int *size) *size = 0; return MP_VAL; } - /* floor( log_2(a) ) + 1 */ - bit_count = mp_count_bits(a); - if (bit_count == 0) { + if (a->used == 0) { *size = 2; return MP_OKAY; } + /* floor( log_2(a) ) + 1 */ + bit_count = mp_count_bits(a); + /* A small shortcut for powers of two. */ if (!(base&(base-1))) { unsigned int x = (unsigned int)base; From ad0e8002ffb64812e61f6fcae72d7a660e0b961c Mon Sep 17 00:00:00 2001 From: czurnieden Date: Mon, 7 Oct 2019 17:06:58 +0200 Subject: [PATCH 4/7] cleaned up a bit and added testing of negative values in demo/test.c --- bn_mp_radix_size_overestimate.c | 78 ++++++++++++++------------------- demo/test.c | 10 +++++ tommath.h | 2 +- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/bn_mp_radix_size_overestimate.c b/bn_mp_radix_size_overestimate.c index 347d66cf1..a320ad440 100644 --- a/bn_mp_radix_size_overestimate.c +++ b/bn_mp_radix_size_overestimate.c @@ -141,17 +141,22 @@ static const mp_word logbases[65] = { #endif /* *INDENT-ON* */ -mp_err mp_radix_size_overestimate(const mp_int *a, const int base, int *size) +mp_err mp_radix_size_overestimate(const mp_int *a, const int radix, int *size) { mp_int bi_bit_count, bi_k; #if ( (defined MP_8BIT) || (defined MP_16BIT) ) mp_int bi_k_bis; #endif - int rem, bit_count; - mp_err e = MP_OKAY; + int bit_count; + mp_err err = MP_OKAY; - if ((base < 2) || (base > 64)) { + if (size == NULL) { + return MP_VAL; + } else { *size = 0; + } + + if ((radix < 2) || (radix > 64)) { return MP_VAL; } @@ -160,74 +165,63 @@ mp_err mp_radix_size_overestimate(const mp_int *a, const int base, int *size) return MP_OKAY; } - /* floor( log_2(a) ) + 1 */ bit_count = mp_count_bits(a); /* A small shortcut for powers of two. */ - if (!(base&(base-1))) { - unsigned int x = (unsigned int)base; - int y; + if (!(radix&(radix-1))) { + unsigned int x = (unsigned int)radix; + int y, rem; for (y=0; (y < 7) && !(x & 1u); y++) { x >>= 1; } *size = bit_count/y; rem = bit_count - ((*size) * y); /* Add 1 for the remainder if any and 1 for "\0". */ - *size += (rem == 0) ? 1 : 2; - /* And one extra character for the minus sign */ - if (a->sign == MP_NEG) { - (*size)++; - } + *size += ((rem == 0) ? 1 : 2) + (a->sign == MP_NEG); return MP_OKAY; } - /* d(bitcount,base) = floor( (bitcount * 2^p) / k(base) ) + 1 */ + /* d(bitcount,radix) = floor( (bitcount * 2^p) / k(radix) ) + 1 */ - if ((e = mp_init_multi(&bi_bit_count, &bi_k, NULL)) != MP_OKAY) { - *size = 0; - return e; + if ((err = mp_init_multi(&bi_bit_count, &bi_k, NULL)) != MP_OKAY) { + return err; } #if ( (defined MP_8BIT) || (defined MP_16BIT) ) - if ((e = mp_init(&bi_k_bis)) != MP_OKAY) { + if ((err = mp_init(&bi_k_bis)) != MP_OKAY) { /* No "goto" to avoid cluttering this code with even more preprocessor branches */ mp_clear_multi(&bi_bit_count, &bi_k, NULL); - *size = 0; - return e; + return err; } #endif /* "long" is at least as large as "int" according to even the oldest C standards */ mp_set_l(&bi_bit_count, bit_count); #if ( (defined MP_8BIT) || (defined MP_16BIT) ) /* There is no mp_set_u16 for MP_8BIT */ - mp_set_u32(&bi_k, logbases_high[base]); - if ((e = mp_mul_2d(&bi_k, LTM_RADIX_SIZE_HALF_TABLE_SCALE, &bi_k)) != MP_OKAY) { - *size = 0; - goto LTM_E1; + mp_set_u32(&bi_k, logbases_high[radix]); + if ((err = mp_mul_2d(&bi_k, LTM_RADIX_SIZE_HALF_TABLE_SCALE, &bi_k)) != MP_OKAY) { + goto LTM_ERR; } - mp_set_u32(&bi_k_bis, logbases_low[base]); - if ((e = mp_add(&bi_k_bis, &bi_k, &bi_k)) != MP_OKAY) { - *size = 0; - goto LTM_E1; + mp_set_u32(&bi_k_bis, logbases_low[radix]); + if ((err = mp_add(&bi_k_bis, &bi_k, &bi_k)) != MP_OKAY) { + goto LTM_ERR; } #else - mp_set_u64(&bi_k, logbases[base]); + mp_set_u64(&bi_k, logbases[radix]); #endif - if ((e = mp_mul_2d(&bi_bit_count, LTM_RADIX_SIZE_SCALE, &bi_bit_count)) != MP_OKAY) { - *size = 0; - goto LTM_E1; + if ((err = mp_mul_2d(&bi_bit_count, LTM_RADIX_SIZE_SCALE, &bi_bit_count)) != MP_OKAY) { + goto LTM_ERR; } - if ((e = mp_div(&bi_bit_count, &bi_k, &bi_bit_count, NULL)) != MP_OKAY) { - *size = 0; - goto LTM_E1; + if ((err = mp_div(&bi_bit_count, &bi_k, &bi_bit_count, NULL)) != MP_OKAY) { + goto LTM_ERR; } /* - The first addition of one is done because of the truncating last division, - and the second addition of one is done to make room for NIL ('\0'). + The first addition of one is done because of the truncating division, + and the second addition of one is for NIL ('\0'). Casting from "long" to "int" can be done because "bi_bit_count" fits into an "int" by definition. */ - *size = (int)mp_get_l(&bi_bit_count) + 1 + 1 ; + *size = (int)mp_get_l(&bi_bit_count) + 1 + 1 + (a->sign == MP_NEG); #if ( (defined MP_8BIT) && (INT_MAX > 0xFFFF)) /* TODO: Add a third table? But how likely is it that "int" is 32-bit in @@ -236,17 +230,13 @@ mp_err mp_radix_size_overestimate(const mp_int *a, const int base, int *size) *size += 2; #endif - /* And before we forget it: one extra character for the minus sign */ - if (a->sign == MP_NEG) { - (*size)++; - } -LTM_E1: +LTM_ERR: mp_clear_multi(&bi_bit_count, &bi_k, NULL); #if ( (defined MP_8BIT) || (defined MP_16BIT) ) mp_clear(&bi_k_bis); #endif - return e; + return err; } diff --git a/demo/test.c b/demo/test.c index 130146eed..9524f8d4c 100644 --- a/demo/test.c +++ b/demo/test.c @@ -2331,6 +2331,16 @@ static int test_mp_radix_size(void) radix, size, results[radix]); goto LTM_ERR; } + a.sign = MP_NEG; + if ((err = mp_radix_size_overestimate(&a, radix, &size)) != MP_OKAY) { + goto LTM_ERR; + } + if (size < (results[radix] + 1)) { + fprintf(stderr, "mp_radix_size_overestimate: result for base %d was %d instead of %d\n", + radix, size, results[radix]); + goto LTM_ERR; + } + a.sign = MP_ZPOS; } mp_clear(&a); diff --git a/tommath.h b/tommath.h index 597e9c13e..1bfe67126 100644 --- a/tommath.h +++ b/tommath.h @@ -757,7 +757,7 @@ mp_err mp_radix_size(const mp_int *a, int radix, int *size) MP_WUR; Behaves like the function mp(n|z)_sizeinbase of GMP for all digit-sizes except MP_8BIT and MP_16BIT (if the "int" for MP_16BIT has more than 16 bits) where it can overshoot by two. */ -mp_err mp_radix_size_overestimate(const mp_int *a, const int base, int *size) MP_WUR; +mp_err mp_radix_size_overestimate(const mp_int *a, const int radix, int *size) MP_WUR; #ifndef MP_NO_FILE mp_err mp_fread(mp_int *a, int radix, FILE *stream) MP_WUR; mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) MP_WUR; From 542ca51816fac780106232339965833241158b24 Mon Sep 17 00:00:00 2001 From: czurnieden Date: Mon, 7 Oct 2019 17:30:00 +0200 Subject: [PATCH 5/7] more clean-ups and some adjustments for the new mp_to_radix --- bn_mp_fwrite.c | 8 ++++---- bn_mp_radix_size.c | 30 ++++++++---------------------- 2 files changed, 12 insertions(+), 26 deletions(-) diff --git a/bn_mp_fwrite.c b/bn_mp_fwrite.c index 2471d8948..18b385023 100644 --- a/bn_mp_fwrite.c +++ b/bn_mp_fwrite.c @@ -8,12 +8,13 @@ mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) { char *buf; mp_err err; - int len; + int len = 0; size_t written; - /* TODO: this function is not in this PR */ if (MP_HAS(MP_RADIX_SIZE_OVERESTIMATE)) { - /* if ((err = mp_radix_size_overestimate(&t, base, &len)) != MP_OKAY) goto LBL_ERR; */ + if ((err = mp_radix_size_overestimate(a, radix, &len)) != MP_OKAY) { + return err; + } } else { if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { return err; @@ -36,7 +37,6 @@ mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) err = MP_OKAY; - LBL_ERR: MP_FREE_BUFFER(buf, (size_t)len); return err; diff --git a/bn_mp_radix_size.c b/bn_mp_radix_size.c index 6e78efffb..e6e406f97 100644 --- a/bn_mp_radix_size.c +++ b/bn_mp_radix_size.c @@ -6,14 +6,14 @@ /* returns size of ASCII representation */ mp_err mp_radix_size(const mp_int *a, int radix, int *size) { - mp_err err; - int digs; - mp_int t; - mp_digit d; mp_int a_, b; - *size = 0; + if (size == NULL) { + return MP_VAL; + } else { + *size = 0; + } /* make sure the radix is in range */ if ((radix < 2) || (radix > 64)) { @@ -36,16 +36,10 @@ mp_err mp_radix_size(const mp_int *a, int radix, int *size) *size = bit_count/y; rem = bit_count - ((*size) * y); /* Add 1 for the remainder if any and 1 for "\0". */ - *size += (rem == 0) ? 1 : 2; - /* And one extra character for the minus sign */ - if (a->sign == MP_NEG) { - (*size)++; - } + *size += ((rem == 0) ? 1 : 2) + (a->sign == MP_NEG); return MP_OKAY; } - - if ((err = mp_init(&b)) != MP_OKAY) { goto LBL_ERR; } @@ -58,16 +52,8 @@ mp_err mp_radix_size(const mp_int *a, int radix, int *size) *size = (int)mp_get_l(&b); - /* mp_ilogb truncates to zero, hence we need one extra put on top. */ - (*size)++; - - /* The sign needs to have a place to live, too*/ - if (a->sign == MP_NEG) { - (*size)++; - } - - /* return digs + 1, the 1 is for the NUL byte that would be required. */ - (*size)++; + /* mp_ilogb truncates to zero, hence we need one extra put on top and one for `\0`. */ + *size += 2 + (a->sign == MP_NEG); LBL_ERR: mp_clear(&b); From f4a042462201d99616f0fc52abafa7bdf16fb7e8 Mon Sep 17 00:00:00 2001 From: czurnieden Date: Mon, 7 Oct 2019 17:58:07 +0200 Subject: [PATCH 6/7] corrected demo/test.c --- demo/test.c | 16 +++++++++++++--- tommath_class.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/demo/test.c b/demo/test.c index 9524f8d4c..52873a3d3 100644 --- a/demo/test.c +++ b/demo/test.c @@ -2332,11 +2332,11 @@ static int test_mp_radix_size(void) goto LTM_ERR; } a.sign = MP_NEG; - if ((err = mp_radix_size_overestimate(&a, radix, &size)) != MP_OKAY) { + if ((err = mp_radix_size(&a, radix, &size)) != MP_OKAY) { goto LTM_ERR; } - if (size < (results[radix] + 1)) { - fprintf(stderr, "mp_radix_size_overestimate: result for base %d was %d instead of %d\n", + if (size != (results[radix] + 1)) { + fprintf(stderr, "mp_radix_size: result for base %d was %d instead of %d\n", radix, size, results[radix]); goto LTM_ERR; } @@ -2386,6 +2386,16 @@ static int test_mp_radix_size_overestimate(void) radix, size, results[radix]); goto LTM_ERR; } + a.sign = MP_NEG; + if ((err = mp_radix_size_overestimate(&a, radix, &size)) != MP_OKAY) { + goto LTM_ERR; + } + if (size < results[radix]) { + fprintf(stderr, "mp_radix_size_overestimate: result for base %d was %d instead of %d\n", + radix, size, results[radix]); + goto LTM_ERR; + } + a.sign = MP_ZPOS; } mp_clear(&a); diff --git a/tommath_class.h b/tommath_class.h index 18522715d..6a18cb475 100644 --- a/tommath_class.h +++ b/tommath_class.h @@ -455,6 +455,7 @@ #if defined(BN_MP_FWRITE_C) # define BN_MP_RADIX_SIZE_C +# define BN_MP_RADIX_SIZE_OVERESTIMATE_C # define BN_MP_TO_RADIX_C #endif From 2bf351b00143fc2e2ac42c7b52cc9f3d87db0a9b Mon Sep 17 00:00:00 2001 From: czurnieden Date: Thu, 10 Oct 2019 05:28:12 +0200 Subject: [PATCH 7/7] version minimale --- bn_mp_radix_size_overestimate.c | 201 +++----------------------------- tommath_class.h | 2 +- 2 files changed, 14 insertions(+), 189 deletions(-) diff --git a/bn_mp_radix_size_overestimate.c b/bn_mp_radix_size_overestimate.c index a320ad440..aba15af4f 100644 --- a/bn_mp_radix_size_overestimate.c +++ b/bn_mp_radix_size_overestimate.c @@ -4,40 +4,13 @@ /* SPDX-License-Identifier: Unlicense */ - -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* returns size of ASCII representation */ - /* - - Behaves like the function mp(n|z)_sizeinbase of GMP for all digit-sizes except MP_8BIT - and MP_16BIT (if the "int" for MP_16BIT has more than 16 bits) where it can overshoot by two. - The results for bases that are powers-of-two are exact. -*/ - -/* - Tables of {0, log_2([1..64])} times 2^p where p is the scale + Table of {0, log_2([1..64])} times 2^p where p is the scale factor defined in LTM_RADIX_SIZE_SCALE. - - The tables have been computed with GP/PARI 2.9.4 with the - x86-64/GMP-5.1.3 kernel and (unnecessary) 100 decimal digits - precision. The fractional parts of the results after the - multiplication by 2^p have been discarded (floor(x)). - - The number that measures the number of the digits of the bignum is - of type "int" which is at least 16 bits large and is 32 bit on the - architectures common at the time of writing. If you have hard- or - software that has a different size, please feel free to contact the - author, adding another table can be done quite quickly! */ - /* *INDENT-OFF* */ -#ifdef MP_8BIT -#define LTM_RADIX_SIZE_SCALE 29 -#define LTM_RADIX_SIZE_HALF_TABLE_SCALE 16 -static const mp_word logbases_high[65] = { +#define LTM_RADIX_SIZE_SCALE 13 +static const uint16_t logbases[65] = { 0u, 0u, 8192u, 12984u, 16384u, 19021u, 21176u, 22997u, 24576u, 25968u, 27213u, 28339u, 29368u, 30314u, 31189u, @@ -52,190 +25,42 @@ static const mp_word logbases_high[65] = { 47360u, 47573u, 47783u, 47988u, 48190u, 48389u, 48584u, 48776u, 48965u, 49152u }; -static const mp_word logbases_low[65] = { - 0u, 0u, 0u, 839u, 0u, - 15397u, 839u, 55805u, 0u, 1678u, - 15397u, 43504u, 839u, 142u, 55805u, - 16237u, 0u, 32479u, 1678u, 1454u, - 15397u, 56644u, 43504u, 1280u, 839u, - 30795u, 142u, 2517u, 55805u, 38031u, - 16237u, 50867u, 0u, 44343u, 32479u, - 5667u, 1678u, 55179u, 1454u, 981u, - 15397u, 4326u, 56644u, 62971u, 43504u, - 17076u, 1280u, 12574u, 839u, 46074u, - 30795u, 33318u, 142u, 8150u, 2517u, - 58902u, 55805u, 2293u, 38031u, 40098u, - 16237u, 39339u, 50867u, 57483u, 0u -}; -#elif (defined MP_16BIT) -#define LTM_RADIX_SIZE_SCALE 61 -#define LTM_RADIX_SIZE_HALF_TABLE_SCALE 32 -static const mp_word logbases_high[65] = { - 0ul, 0ul, 536870912ul, 850920263ul, 1073741824ul, - 1246575653ul, 1387791175ul, 1507187197ul, 1610612736ul, 1701840526ul, - 1783446565ul, 1857268208ul, 1924662087ul, 1986658446ul, 2044058109ul, - 2097495917ul, 2147483648ul, 2194439903ul, 2238711438ul, 2280588718ul, - 2320317477ul, 2358107460ul, 2394139120ul, 2428568832ul, 2461532999ul, - 2493151307ul, 2523529358ul, 2552760789ul, 2580929021ul, 2608108687ul, - 2634366829ul, 2659763891ul, 2684354560ul, 2708188471ul, 2731310815ul, - 2753762851ul, 2775582350ul, 2796803979ul, 2817459630ul, 2837578709ul, - 2857188389ul, 2876313830ul, 2894978372ul, 2913203707ul, 2931010032ul, - 2948416180ul, 2965439744ul, 2982097182ul, 2998403911ul, 3014374394ul, - 3030022219ul, 3045360166ul, 3060400270ul, 3075153878ul, 3089631701ul, - 3103843862ul, 3117799933ul, 3131508981ul, 3144979599ul, 3158219938ul, - 3171237741ul, 3184040363ul, 3196634803ul, 3209027723ul, 3221225472ul -}; -static const mp_word logbases_low[65] = { - 0ul, 0ul, 0ul, 1065013491ul, 0ul, - 3868050815ul, 1065013491ul, 1343271782ul, 0ul, 2130026983ul, - 3868050815ul, 427100031ul, 1065013491ul, 1200147405ul, 1343271782ul, - 638097011ul, 0ul, 1495425743ul, 2130026983ul, 1083835016ul, - 3868050815ul, 2408285274ul, 427100031ul, 3594167896ul, 1065013491ul, - 3441134334ul, 1200147405ul, 3195040475ul, 1343271782ul, 1429396043ul, - 638097011ul, 1651143338ul, 0ul, 1492113523ul, 1495425743ul, - 916355301ul, 2130026983ul, 1832592635ul, 1083835016ul, 2265160897ul, - 3868050815ul, 3464916779ul, 2408285274ul, 2621526098ul, 427100031ul, - 1703110503ul, 3594167896ul, 2513440227ul, 1065013491ul, 2686543564ul, - 3441134334ul, 2560439235ul, 1200147405ul, 1309103046ul, 3195040475ul, - 183550ul, 1343271782ul, 2148848508ul, 1429396043ul, 3785381171ul, - 638097011ul, 1073048670ul, 1651143338ul, 3473298766ul, 0ul -}; - -/* TODO: This assumes the type "long long" exists. If it doesn't: use the tables for MP_16BIT */ -#elif ( (defined MP_28BIT) || (defined MP_31BIT) || (defined MP_32BIT) || (defined MP_64BIT) ) -#define LTM_RADIX_SIZE_SCALE 61 -#ifdef MP_64BIT -static const mp_digit logbases[65] = { -#else -static const mp_word logbases[65] = { -#endif - 0ull, 0ull, 2305843009213693952ull, - 3654674702153732339ull, 4611686018427387904ull, 5354001665492895103ull, - 5960517711367426291ull, 6473319721408181094ull, 6917529027641081856ull, - 7309349404307464679ull, 7659844674706589055ull, 7976906213687625599ull, - 8266360720581120243ull, 8532633055092329421ull, 8779162730621875046ull, - 9008676367646627443ull, 9223372036854775808ull, 9425047617917838031ull, - 9615192413521158631ull, 9795053960520401544ull, 9965687683920283007ull, - 10127994423561913434ull, 10282749222901319551ull, 10430623713119086168ull, - 10572203729794814195ull, 10708003330985790206ull, 10838476064306023373ull, - 10964024106461197019ull, 11085005739835568998ull, 11201741516507896395ull, - 11314519376860321395ull, 11423598928577852074ull, 11529215046068469760ull, - 11631580915841357939ull, 11730890627131531983ull, 11827321386901076197ull, - 11921035422734852583ull, 12012181624960263419ull, 12100896969734095496ull, - 12187307757246061761ull, 12271530693133976959ull, 12353673836347420459ull, - 12433837432775607386ull, 12512114650772492370ull, 12588592232115013503ull, - 12663351069800359783ull, 12736466722332780120ull, 12808009872697200099ull, - 12878046739008508147ull, 12946639442816362188ull, 13013846340199484158ull, - 13079722320071570371ull, 13144319073519717325ull, 13207685337486676934ull, - 13269867115674890971ull, 13330907879180520702ull, 13390848749049262950ull, - 13449728662674133884ull, 13507584525721590347ull, 13564451351070528819ull, - 13620362386074015347ull, 13675349229302017118ull, 13729441937791546026ull, - 13782669125715645774ull, 13835058055282163712ull -}; -#else -# ifdef _MSC_VER -# pragma message("mp_radix_size_overestimate: unknown or undefined MP_xBIT type") -# else -# warning "mp_radix_size_overestimate: unknown or undefined MP_xBIT type" -# endif -#endif /* *INDENT-ON* */ - mp_err mp_radix_size_overestimate(const mp_int *a, const int radix, int *size) { mp_int bi_bit_count, bi_k; -#if ( (defined MP_8BIT) || (defined MP_16BIT) ) - mp_int bi_k_bis; -#endif int bit_count; mp_err err = MP_OKAY; - if (size == NULL) { - return MP_VAL; - } else { - *size = 0; - } + *size = 0; if ((radix < 2) || (radix > 64)) { return MP_VAL; } - if (a->used == 0) { - *size = 2; - return MP_OKAY; - } - - bit_count = mp_count_bits(a); + bit_count = mp_count_bits(a) + 1; - /* A small shortcut for powers of two. */ - if (!(radix&(radix-1))) { - unsigned int x = (unsigned int)radix; - int y, rem; - for (y=0; (y < 7) && !(x & 1u); y++) { - x >>= 1; - } - *size = bit_count/y; - rem = bit_count - ((*size) * y); - /* Add 1 for the remainder if any and 1 for "\0". */ - *size += ((rem == 0) ? 1 : 2) + (a->sign == MP_NEG); + if (bit_count == 0) { + *size = 2; return MP_OKAY; } - /* d(bitcount,radix) = floor( (bitcount * 2^p) / k(radix) ) + 1 */ - if ((err = mp_init_multi(&bi_bit_count, &bi_k, NULL)) != MP_OKAY) { return err; } -#if ( (defined MP_8BIT) || (defined MP_16BIT) ) - if ((err = mp_init(&bi_k_bis)) != MP_OKAY) { - /* No "goto" to avoid cluttering this code with even more preprocessor branches */ - mp_clear_multi(&bi_bit_count, &bi_k, NULL); - return err; - } -#endif - /* "long" is at least as large as "int" according to even the oldest C standards */ - mp_set_l(&bi_bit_count, bit_count); -#if ( (defined MP_8BIT) || (defined MP_16BIT) ) - /* There is no mp_set_u16 for MP_8BIT */ - mp_set_u32(&bi_k, logbases_high[radix]); - if ((err = mp_mul_2d(&bi_k, LTM_RADIX_SIZE_HALF_TABLE_SCALE, &bi_k)) != MP_OKAY) { - goto LTM_ERR; - } - mp_set_u32(&bi_k_bis, logbases_low[radix]); - if ((err = mp_add(&bi_k_bis, &bi_k, &bi_k)) != MP_OKAY) { - goto LTM_ERR; - } -#else - mp_set_u64(&bi_k, logbases[radix]); -#endif - if ((err = mp_mul_2d(&bi_bit_count, LTM_RADIX_SIZE_SCALE, &bi_bit_count)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_div(&bi_bit_count, &bi_k, &bi_bit_count, NULL)) != MP_OKAY) { - goto LTM_ERR; - } - /* - The first addition of one is done because of the truncating division, - and the second addition of one is for NIL ('\0'). - Casting from "long" to "int" can be done because "bi_bit_count" fits into an "int" - by definition. - */ - *size = (int)mp_get_l(&bi_bit_count) + 1 + 1 + (a->sign == MP_NEG); + mp_set_l(&bi_bit_count, bit_count); + mp_set_u32(&bi_k, logbases[radix]); + if ((err = mp_mul_2d(&bi_bit_count, LTM_RADIX_SIZE_SCALE, &bi_bit_count)) != MP_OKAY) goto LTM_ERR; + if ((err = mp_div(&bi_bit_count, &bi_k, &bi_bit_count, NULL)) != MP_OKAY) goto LTM_ERR; + *size = (int)mp_get_l(&bi_bit_count) + 4; #if ( (defined MP_8BIT) && (INT_MAX > 0xFFFF)) - /* TODO: Add a third table? But how likely is it that "int" is 32-bit in - an 8-bit environment? */ - /* diff. is 3 bits, hence add 2 (two) */ - *size += 2; + *size += 3; #endif - LTM_ERR: mp_clear_multi(&bi_bit_count, &bi_k, NULL); -#if ( (defined MP_8BIT) || (defined MP_16BIT) ) - mp_clear(&bi_k_bis); -#endif return err; } diff --git a/tommath_class.h b/tommath_class.h index 6a18cb475..7ba934ad8 100644 --- a/tommath_class.h +++ b/tommath_class.h @@ -855,7 +855,7 @@ # define BN_MP_INIT_MULTI_C # define BN_MP_MUL_2D_C # define BN_MP_SET_L_C -# define BN_MP_SET_U64_C +# define BN_MP_SET_U32_C #endif #if defined(BN_MP_RADIX_SMAP_C)