diff --git a/etc/tune.c b/etc/tune.c index f7ff94df..3f44cb12 100644 --- a/etc/tune.c +++ b/etc/tune.c @@ -188,11 +188,21 @@ static uint64_t s_time_radix_conversion_read(int size) uint64_t t1; /* "size" is given as "number of limbs" and starts at 8 */ - length = ((size_t)size - 7u) * MP_DIGIT_BIT; - - /* Over-estimate number of base 10 digits */ - /* TODO: can overflow with small INT_MAX */ - length = (length * 28u) / 93u + 2u; + length = (size_t)(size * MP_DIGIT_BIT); + + /* Over-estimate number of base 10 digits + Magick number: 28/93 = CF(log_10(2))_(p_3, q_3) + */ + written = (length * 28u); + /* May happen e.g. if size > 2184 with MP_16BIT + but cutoff should be about a couple of thousand bits + at most (around or above Karatsuba cutoff). + */ + if (length != written / 28u) { + t1 = UINT64_MAX; + goto LBL_ERR_1; + } + length = written / 93u + 2u; if ((err = random_number(&str_a, length)) != MP_OKAY) { t1 = UINT64_MAX; @@ -659,9 +669,11 @@ int main(int argc, char **argv) if (test[n].fn != NULL) { s_run(test[n].name, test[n].fn, test[n].cutoff); /* TODO: can overflow for small INT_MAX */ - *test[n].update = ((*test[n].cutoff) * MP_DIGIT_BIT * 93)/28; + *test[n].update = (*test[n].cutoff) * MP_DIGIT_BIT; + *test[n].cutoff = INT_MAX; } } + } if (args.terse == 1) { printf("%d %d %d %d %d %d\n", diff --git a/s_mp_faster_to_radix.c b/s_mp_faster_to_radix.c index daaf343b..cb87820c 100644 --- a/s_mp_faster_to_radix.c +++ b/s_mp_faster_to_radix.c @@ -61,11 +61,14 @@ static mp_err s_mp_to_radix_recursive(const mp_int *a, char **str, size_t *part_ } /* Q = floor(A1 * I / 2^Beta) */ /* I = floor( (2^(2*Beta)) / B) Here we have R[t] = I, P[t] = B */ - /* TODO: we don't need the full "a" only the upper part: a = a_1\beta + a_0 with 0 < a_0 < \beta - (high short-product with s_mp_mul_high). - Problem: s_mp_mul_high does not make use of fast multiplication except COMBA. - (You can do it with Toom-Cook algorithms, but that is work for another day.) */# - /*if( (err = s_mp_mul_high(a, &R[t], &q, (a->used/2) + 1) ) != MP_OKAY) goto LTM_ERR;*/ + /* TODO: We don't need the full "a" only the upper part: a = a_1\beta + a_0 with 0 < a_0 < \beta + The cutoff with s_mp_mul_high is so low that the gap between that and the general cutoff + is too small to be worth the hassle. + But if somebody implements Thom Mulder's short products... + (There are successors. See e.g. D. Harvey and P. Zimmermann "Short Division of Long Integers", + Laszlo Hars "Fast Truncated Multiplication for Cryptographic Applications", Daniel Lemire "Exact Short + Products From Truncated Multipliers", and many^Wsome more. + */ if ((err = mp_mul(a, &R[t], &q)) != MP_OKAY) goto LTM_ERR; if ((err = mp_div_2d(&q, Beta, &q, NULL)) != MP_OKAY) goto LTM_ERR;