Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions demo/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1524,8 +1524,8 @@ static int test_mp_reduce_2k_l(void)
return EXIT_SUCCESS;
# endif /* LTM_DEMO_TEST_REDUCE_2K_L */
}
/* stripped down version of mp_radix_size. The faster version can be off by up t
o +3 */

/* stripped down version of mp_radix_size. The faster version can be off by up to +3 */
/* TODO: This function should be removed, replaced by mp_radix_size, mp_radix_size_overestimate in 2.0 */
static mp_err s_rs(const mp_int *a, int radix, uint32_t *size)
{
Expand Down Expand Up @@ -2279,14 +2279,14 @@ static int test_mp_radix_size(void)
size_t size;
/* *INDENT-OFF* */
size_t 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
0u, 0u, 1627u, 1027u, 814u, 702u, 630u, 581u, 543u,
514u, 491u, 471u, 455u, 441u, 428u, 418u, 408u, 399u,
391u, 384u, 378u, 372u, 366u, 361u, 356u, 352u, 347u,
343u, 340u, 336u, 333u, 330u, 327u, 324u, 321u, 318u,
316u, 314u, 311u, 309u, 307u, 305u, 303u, 301u, 299u,
298u, 296u, 294u, 293u, 291u, 290u, 288u, 287u, 285u,
284u, 283u, 281u, 280u, 279u, 278u, 277u, 276u, 275u,
273u, 272u
};
/* *INDENT-ON* */

Expand Down Expand Up @@ -2326,8 +2326,6 @@ static int test_mp_radix_size(void)
return EXIT_FAILURE;
}



static int test_mp_read_write_ubin(void)
{
mp_int a, b, c;
Expand Down
8 changes: 8 additions & 0 deletions libtommath_VS2008.vcproj
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,10 @@
RelativePath="s_mp_log_d.c"
>
</File>
<File
RelativePath="s_mp_log_power_of_two.c"
>
</File>
<File
RelativePath="s_mp_montgomery_reduce_fast.c"
>
Expand All @@ -912,6 +916,10 @@
RelativePath="s_mp_prime_is_divisible.c"
>
</File>
<File
RelativePath="s_mp_radix_size_radix_10.c"
>
</File>
<File
RelativePath="s_mp_rand_jenkins.c"
>
Expand Down
8 changes: 4 additions & 4 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ mp_set_ll.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_set_ull.o mp_shrink.o mp_si
mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o \
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o s_mp_exptmod.o \
s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o \
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o \
s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o \
s_mp_rand_jenkins.o s_mp_rand_platform.o s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o \
s_mp_toom_mul.o s_mp_toom_sqr.o
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_log_power_of_two.o s_mp_montgomery_reduce_fast.o \
s_mp_mul_digs.o s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o \
s_mp_prime_is_divisible.o s_mp_radix_size_radix_10.o s_mp_rand_jenkins.o s_mp_rand_platform.o \
s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o s_mp_toom_mul.o s_mp_toom_sqr.o

#END_INS

Expand Down
8 changes: 4 additions & 4 deletions makefile.mingw
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ mp_set_ll.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_set_ull.o mp_shrink.o mp_si
mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o \
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o s_mp_exptmod.o \
s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o \
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o \
s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o \
s_mp_rand_jenkins.o s_mp_rand_platform.o s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o \
s_mp_toom_mul.o s_mp_toom_sqr.o
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_log_power_of_two.o s_mp_montgomery_reduce_fast.o \
s_mp_mul_digs.o s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o \
s_mp_prime_is_divisible.o s_mp_radix_size_radix_10.o s_mp_rand_jenkins.o s_mp_rand_platform.o \
s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o s_mp_toom_mul.o s_mp_toom_sqr.o

HEADERS_PUB=tommath.h
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)
Expand Down
8 changes: 4 additions & 4 deletions makefile.msvc
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ mp_set_ll.obj mp_set_u32.obj mp_set_u64.obj mp_set_ul.obj mp_set_ull.obj mp_shri
mp_sqrmod.obj mp_sqrt.obj mp_sqrtmod_prime.obj mp_sub.obj mp_sub_d.obj mp_submod.obj mp_to_radix.obj mp_to_sbin.obj \
mp_to_ubin.obj mp_ubin_size.obj mp_unpack.obj mp_xor.obj mp_zero.obj s_mp_add.obj s_mp_balance_mul.obj s_mp_exptmod.obj \
s_mp_exptmod_fast.obj s_mp_get_bit.obj s_mp_invmod_fast.obj s_mp_invmod_slow.obj s_mp_karatsuba_mul.obj \
s_mp_karatsuba_sqr.obj s_mp_log.obj s_mp_log_d.obj s_mp_montgomery_reduce_fast.obj s_mp_mul_digs.obj \
s_mp_mul_digs_fast.obj s_mp_mul_high_digs.obj s_mp_mul_high_digs_fast.obj s_mp_prime_is_divisible.obj \
s_mp_rand_jenkins.obj s_mp_rand_platform.obj s_mp_reverse.obj s_mp_sqr.obj s_mp_sqr_fast.obj s_mp_sub.obj \
s_mp_toom_mul.obj s_mp_toom_sqr.obj
s_mp_karatsuba_sqr.obj s_mp_log.obj s_mp_log_d.obj s_mp_log_power_of_two.obj s_mp_montgomery_reduce_fast.obj \
s_mp_mul_digs.obj s_mp_mul_digs_fast.obj s_mp_mul_high_digs.obj s_mp_mul_high_digs_fast.obj \
s_mp_prime_is_divisible.obj s_mp_radix_size_radix_10.obj s_mp_rand_jenkins.obj s_mp_rand_platform.obj \
s_mp_reverse.obj s_mp_sqr.obj s_mp_sqr_fast.obj s_mp_sub.obj s_mp_toom_mul.obj s_mp_toom_sqr.obj

HEADERS_PUB=tommath.h
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)
Expand Down
8 changes: 4 additions & 4 deletions makefile.shared
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ mp_set_ll.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_set_ull.o mp_shrink.o mp_si
mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o \
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o s_mp_exptmod.o \
s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o \
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o \
s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o \
s_mp_rand_jenkins.o s_mp_rand_platform.o s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o \
s_mp_toom_mul.o s_mp_toom_sqr.o
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_log_power_of_two.o s_mp_montgomery_reduce_fast.o \
s_mp_mul_digs.o s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o \
s_mp_prime_is_divisible.o s_mp_radix_size_radix_10.o s_mp_rand_jenkins.o s_mp_rand_platform.o \
s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o s_mp_toom_mul.o s_mp_toom_sqr.o

#END_INS

Expand Down
8 changes: 4 additions & 4 deletions makefile.unix
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ mp_set_ll.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_set_ull.o mp_shrink.o mp_si
mp_sqrmod.o mp_sqrt.o mp_sqrtmod_prime.o mp_sub.o mp_sub_d.o mp_submod.o mp_to_radix.o mp_to_sbin.o \
mp_to_ubin.o mp_ubin_size.o mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_balance_mul.o s_mp_exptmod.o \
s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod_fast.o s_mp_invmod_slow.o s_mp_karatsuba_mul.o \
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_montgomery_reduce_fast.o s_mp_mul_digs.o \
s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o s_mp_prime_is_divisible.o \
s_mp_rand_jenkins.o s_mp_rand_platform.o s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o \
s_mp_toom_mul.o s_mp_toom_sqr.o
s_mp_karatsuba_sqr.o s_mp_log.o s_mp_log_d.o s_mp_log_power_of_two.o s_mp_montgomery_reduce_fast.o \
s_mp_mul_digs.o s_mp_mul_digs_fast.o s_mp_mul_high_digs.o s_mp_mul_high_digs_fast.o \
s_mp_prime_is_divisible.o s_mp_radix_size_radix_10.o s_mp_rand_jenkins.o s_mp_rand_platform.o \
s_mp_reverse.o s_mp_sqr.o s_mp_sqr_fast.o s_mp_sub.o s_mp_toom_mul.o s_mp_toom_sqr.o

HEADERS_PUB=tommath.h
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)
Expand Down
12 changes: 12 additions & 0 deletions mp_radix_size.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
/* returns size of ASCII representation */
mp_err mp_radix_size(const mp_int *a, int radix, size_t *size)
{

mp_err err;
mp_int a_;
uint32_t b;

*size = 0;

/* make sure the radix is in range */
if ((radix < 2) || (radix > 64)) {
return MP_VAL;
Expand All @@ -20,6 +23,10 @@ mp_err mp_radix_size(const mp_int *a, int radix, size_t *size)
return MP_OKAY;
}

if (radix == 10) {
return s_mp_radix_size_radix_10(a, size);
}

a_ = *a;
a_.sign = MP_ZPOS;
if ((err = mp_log_u32(&a_, (uint32_t)radix, &b)) != MP_OKAY) {
Expand All @@ -29,6 +36,11 @@ mp_err mp_radix_size(const mp_int *a, int radix, size_t *size)
/* mp_ilogb truncates to zero, hence we need one extra put on top and one for `\0`. */
*size = (size_t)b + 2U + ((a->sign == MP_NEG) ? 1U : 0U);

/* This can overflow for e.g.: radix = 2 and bit_count >= 2147483645 with a 32 bit "int" */
if (*size > (size_t)(INT_MAX - 3)) {
return MP_VAL;
}

LBL_ERR:
return err;
}
Expand Down
19 changes: 19 additions & 0 deletions s_mp_log_power_of_two.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "tommath_private.h"
#ifdef S_MP_LOG_POWER_OF_TWO_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */



int s_mp_log_power_of_two(const mp_int *a, int p_of_2)
{
int x, bit_count;
for (x = 0; (x < 7) && !((unsigned int)p_of_2 & 1u); x++) {
p_of_2 >>= 1;
}
bit_count = mp_count_bits(a) - 1;
return (bit_count/x);
}


#endif
65 changes: 65 additions & 0 deletions s_mp_radix_size_radix_10.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "tommath_private.h"
#ifdef S_MP_RADIX_SIZE_RADIX_10_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */

#define LTM_RADIX_SIZE_SCALE 64
int s_mp_radix_size_radix_10(const mp_int *a, size_t *size)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@czurnieden why don't you add a function s_mp_log10 which is called from mp_log and used indirectly bymp_radix_size?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was, and still am, a bit torn between calling that optimization in mp_log or in mp_radix_size.

Calling it in mp_radix_size allows for easy reduction to the restricted radix-set 2,4,8,10,16,32,64 and would also getting rid of the dependency mp_log which isn't a very small function.

Calling it in mp_log is cleaner if we want to keep the full radix-set.

Mmh…
*strokes sesquipedalian beard*
I don't know.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, but you can strip down mp_log by disabling s_mp_log and only enabling the power of two and base 10 versions. We had that discussion in #389. I think it should go to mp_log since it is more general.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you strip down 'mp_log' you don't have a general log-function anymore.

If you strip down 'mp_radix_size' you still have a radix-size function, just not for the small range of radices 2-64, only for the smaller range of powers-of-two and base 10.

You expect of a log-function that it works over the whole range, with no holes in it.

You expect from a radix-size function to work over a very small range, it might even have holes in it. Restricting the string out/input to only a handfull of bases, sometimes down to only two (10 and 16) won't get many complains (vid. e.g.: printf).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but we don't get an optimized log function if we add the base10 optimization only to radix_size. We already have other functions with holes in it if configured as such.

{
mp_err err;
/*
floor(2^64/log_2(10)) = 5553023288523357132

We need that much precision. Example:

log_2(x) = log(x)/log(2)
198096465/log_2(10) = 59632978.000000002598316594477929217520

Which are more than 16 decimal digits, so with BINARY_64 (C's "double")
a 'ceil(198096465/log_2(10))' would result wrongly in 59632978.0.
*/
mp_int bi_bit_count, bi_k, t;
int bit_count;

#ifdef MP_16BIT
#define LTM_RADIX_SIZE_CONST_SHIFT 32
const uint32_t inv_log_2_10[2] = {0x4d104d42UL, 0x7de7fbccUL};
#endif
if ((err = mp_init_multi(&bi_bit_count, &bi_k, &t, NULL)) != MP_OKAY) {
return err;
}
#ifdef MP_16BIT
mp_set_u32(&t, inv_log_2_10[0]);
if ((err = mp_mul_2d(&bi_k, LTM_RADIX_SIZE_CONST_SHIFT, &bi_k)) != MP_OKAY) {
goto LTM_E1;
}
if ((err = mp_add(&bi_k, &t, &bi_k)) != MP_OKAY) {
goto LTM_E1;
}
mp_set_u32(&t, inv_log_2_10[1]);
if ((err = mp_mul_2d(&bi_k, LTM_RADIX_SIZE_CONST_SHIFT, &bi_k)) != MP_OKAY) {
goto LTM_E1;
}
if ((err = mp_add(&bi_k, &t, &bi_k)) != MP_OKAY) {
goto LTM_E1;
}
#else
mp_set_u64(&bi_k, 0x4d104d427de7fbccULL);
#endif
bit_count = mp_count_bits(a) + 1;
mp_set_l(&bi_bit_count, bit_count);
if ((err = mp_mul(&bi_bit_count, &bi_k, &bi_k)) != MP_OKAY) {
goto LTM_E1;
}
if ((err = mp_div_2d(&bi_k, LTM_RADIX_SIZE_SCALE, &bi_k, NULL)) != MP_OKAY) {
goto LTM_E1;
}
*size = (size_t)mp_get_ul(&bi_k);
*size += 2u + (size_t)(a->sign == MP_NEG);
LTM_E1:
mp_clear_multi(&bi_bit_count, &bi_k, &t, NULL);
return err;
}


#endif
18 changes: 18 additions & 0 deletions tommath_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,14 @@
# define S_MP_KARATSUBA_SQR_C
# define S_MP_LOG_C
# define S_MP_LOG_D_C
# define S_MP_LOG_POWER_OF_TWO_C
# define S_MP_MONTGOMERY_REDUCE_FAST_C
# define S_MP_MUL_DIGS_C
# define S_MP_MUL_DIGS_FAST_C
# define S_MP_MUL_HIGH_DIGS_C
# define S_MP_MUL_HIGH_DIGS_FAST_C
# define S_MP_PRIME_IS_DIVISIBLE_C
# define S_MP_RADIX_SIZE_RADIX_10_C
# define S_MP_RAND_JENKINS_C
# define S_MP_RAND_PLATFORM_C
# define S_MP_REVERSE_C
Expand Down Expand Up @@ -747,6 +749,7 @@

#if defined(MP_RADIX_SIZE_C)
# define MP_LOG_U32_C
# define S_MP_RADIX_SIZE_RADIX_10_C
#endif

#if defined(MP_RADIX_SMAP_C)
Expand Down Expand Up @@ -1130,6 +1133,10 @@
#if defined(S_MP_LOG_D_C)
#endif

#if defined(S_MP_LOG_POWER_OF_TWO_C)
# define MP_COUNT_BITS_C
#endif

#if defined(S_MP_MONTGOMERY_REDUCE_FAST_C)
# define MP_CLAMP_C
# define MP_CMP_MAG_C
Expand Down Expand Up @@ -1167,6 +1174,17 @@
# define MP_MOD_D_C
#endif

#if defined(S_MP_RADIX_SIZE_RADIX_10_C)
# define MP_CLEAR_MULTI_C
# define MP_COUNT_BITS_C
# define MP_DIV_2D_C
# define MP_GET_L_C
# define MP_INIT_MULTI_C
# define MP_MUL_C
# define MP_SET_L_C
# define MP_SET_U64_C
#endif

#if defined(S_MP_RAND_JENKINS_C)
# define S_MP_RAND_JENKINS_INIT_C
#endif
Expand Down
5 changes: 5 additions & 0 deletions tommath_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ MP_PRIVATE mp_err s_mp_log(const mp_int *a, uint32_t base, uint32_t *c);
MP_PRIVATE mp_err s_mp_rand_jenkins(void *p, size_t n) MP_WUR;
MP_PRIVATE void s_mp_rand_jenkins_init(uint64_t seed);

/* Expects a power of two as the input "p_of_2" and 2 <= "p_of_2" <= 64*/
MP_PRIVATE int s_mp_log_power_of_two(const mp_int *a, int p_of_2) MP_WUR;
/* Like mp_radix_size but for radix 10 only */
MP_PRIVATE int s_mp_radix_size_radix_10(const mp_int *a, size_t *size) MP_WUR;

#define MP_RMAP_REVERSE_SIZE 88
extern MP_PRIVATE const char s_mp_rmap[];
extern MP_PRIVATE const uint8_t s_mp_rmap_reverse[];
Expand Down