Skip to content

Commit 8163210

Browse files
committed
Addition of faster to_radix function
1 parent 1b3792b commit 8163210

13 files changed

+462
-82
lines changed

demo/test.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,9 +1016,10 @@ static int test_mp_read_radix(void)
10161016
{
10171017
char buf[4096];
10181018
size_t written;
1019+
int bignum, i;
10191020

1020-
mp_int a;
1021-
DOR(mp_init_multi(&a, NULL));
1021+
mp_int a, b;
1022+
DOR(mp_init_multi(&a, &b, NULL));
10221023

10231024
DO(mp_read_radix(&a, "123456", 10));
10241025

@@ -1044,6 +1045,30 @@ static int test_mp_read_radix(void)
10441045
DO(mp_to_radix(&a, buf, sizeof(buf), &written, 10));
10451046
printf("\r '0' a == %s, length = %zu", buf, written);
10461047

1048+
/* Test the fast method with a slightly larger number */
1049+
1050+
/* Must be bigger than the cut-off value, of course */
1051+
bignum = 2* (2 * s_mp_radix_exponent_y[2] * MP_RADIX_BARRETT_START_MULTIPLICATOR);
1052+
printf("Size of bignum_size = %d\n", bignum);
1053+
/* Check if "bignum" is small enough for the result to fit into "buf"
1054+
otherwise lead tester to this function */
1055+
if (bignum >= 4096) {
1056+
fprintf(stderr, "Buffer too small, please check function \"test_mp_read_radix\" in \"test.c\"");
1057+
goto LBL_ERR;
1058+
}
1059+
/* Produce a random number */
1060+
bignum /= MP_DIGIT_BIT;
1061+
DO(mp_rand(&b, bignum));
1062+
/* Check if it makes the round */
1063+
printf("Number of limbs in &b = %d, bit_count of &b = %d\n", bignum, mp_count_bits(&b));
1064+
for (i = 2; i < 65; i++) {
1065+
DO(mp_to_radix(&b, buf, sizeof(buf), &written, i));
1066+
DO(mp_read_radix(&a, buf, i));
1067+
EXPECT(mp_cmp(&a, &b) == MP_EQ);
1068+
/* fprintf(stderr,"radix = %d\n",i); */
1069+
}
1070+
1071+
10471072
while (0) {
10481073
char *s = fgets(buf, sizeof(buf), stdin);
10491074
if (s != buf) break;
@@ -1053,10 +1078,10 @@ static int test_mp_read_radix(void)
10531078
printf("%s, %lu\n", buf, (unsigned long)a.dp[0] & 3uL);
10541079
}
10551080

1056-
mp_clear(&a);
1081+
mp_clear_multi(&a, &b, NULL);
10571082
return EXIT_SUCCESS;
10581083
LBL_ERR:
1059-
mp_clear(&a);
1084+
mp_clear_multi(&a, &b, NULL);
10601085
return EXIT_FAILURE;
10611086
}
10621087

libtommath_VS2008.vcproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,10 @@
824824
RelativePath="s_mp_exptmod_fast.c"
825825
>
826826
</File>
827+
<File
828+
RelativePath="s_mp_faster_to_radix.c"
829+
>
830+
</File>
827831
<File
828832
RelativePath="s_mp_get_bit.c"
829833
>
@@ -900,6 +904,10 @@
900904
RelativePath="s_mp_rand_platform.c"
901905
>
902906
</File>
907+
<File
908+
RelativePath="s_mp_slower_to_radix.c"
909+
>
910+
</File>
903911
<File
904912
RelativePath="s_mp_sqr.c"
905913
>

makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,12 @@ mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o
4444
mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \
4545
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 \
4646
mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \
47-
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod.o \
48-
s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o s_mp_log_d.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \
49-
s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \
50-
s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \
51-
s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \
52-
s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
47+
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_faster_to_radix.o \
48+
s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o s_mp_log_d.o \
49+
s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o \
50+
s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o \
51+
s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_slower_to_radix.o s_mp_sqr.o \
52+
s_mp_sqr_comba.o s_mp_sqr_karatsuba.o s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
5353

5454
#END_INS
5555

makefile.mingw

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o
4646
mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \
4747
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 \
4848
mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \
49-
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod.o \
50-
s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o s_mp_log_d.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \
51-
s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \
52-
s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \
53-
s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \
54-
s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
49+
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_faster_to_radix.o \
50+
s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o s_mp_log_d.o \
51+
s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o \
52+
s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o \
53+
s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_slower_to_radix.o s_mp_sqr.o \
54+
s_mp_sqr_comba.o s_mp_sqr_karatsuba.o s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
5555

5656
HEADERS_PUB=tommath.h
5757
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)

makefile.msvc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,12 @@ mp_reduce_setup.obj mp_root_n.obj mp_rshd.obj mp_sbin_size.obj mp_set.obj mp_set
4242
mp_set_l.obj mp_set_u32.obj mp_set_u64.obj mp_set_ul.obj mp_shrink.obj mp_signed_rsh.obj mp_sqrmod.obj mp_sqrt.obj \
4343
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 \
4444
mp_unpack.obj mp_xor.obj mp_zero.obj s_mp_add.obj s_mp_copy_digs.obj s_mp_div_3.obj s_mp_div_recursive.obj \
45-
s_mp_div_school.obj s_mp_div_small.obj s_mp_exptmod.obj s_mp_exptmod_fast.obj s_mp_get_bit.obj s_mp_invmod.obj \
46-
s_mp_invmod_odd.obj s_mp_log.obj s_mp_log_2expt.obj s_mp_log_d.obj s_mp_montgomery_reduce_comba.obj s_mp_mul.obj \
47-
s_mp_mul_balance.obj s_mp_mul_comba.obj s_mp_mul_high.obj s_mp_mul_high_comba.obj s_mp_mul_karatsuba.obj \
48-
s_mp_mul_toom.obj s_mp_prime_is_divisible.obj s_mp_prime_tab.obj s_mp_radix_map.obj \
49-
s_mp_radix_size_overestimate.obj s_mp_rand_platform.obj s_mp_sqr.obj s_mp_sqr_comba.obj s_mp_sqr_karatsuba.obj \
50-
s_mp_sqr_toom.obj s_mp_sub.obj s_mp_zero_buf.obj s_mp_zero_digs.obj
45+
s_mp_div_school.obj s_mp_div_small.obj s_mp_exptmod.obj s_mp_exptmod_fast.obj s_mp_faster_to_radix.obj \
46+
s_mp_get_bit.obj s_mp_invmod.obj s_mp_invmod_odd.obj s_mp_log.obj s_mp_log_2expt.obj s_mp_log_d.obj \
47+
s_mp_montgomery_reduce_comba.obj s_mp_mul.obj s_mp_mul_balance.obj s_mp_mul_comba.obj s_mp_mul_high.obj \
48+
s_mp_mul_high_comba.obj s_mp_mul_karatsuba.obj s_mp_mul_toom.obj s_mp_prime_is_divisible.obj s_mp_prime_tab.obj \
49+
s_mp_radix_map.obj s_mp_radix_size_overestimate.obj s_mp_rand_platform.obj s_mp_slower_to_radix.obj s_mp_sqr.obj \
50+
s_mp_sqr_comba.obj s_mp_sqr_karatsuba.obj s_mp_sqr_toom.obj s_mp_sub.obj s_mp_zero_buf.obj s_mp_zero_digs.obj
5151

5252
HEADERS_PUB=tommath.h
5353
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)

makefile.shared

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o
4141
mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \
4242
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 \
4343
mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \
44-
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod.o \
45-
s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o s_mp_log_d.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \
46-
s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \
47-
s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \
48-
s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \
49-
s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
44+
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_faster_to_radix.o \
45+
s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o s_mp_log_d.o \
46+
s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o \
47+
s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o \
48+
s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_slower_to_radix.o s_mp_sqr.o \
49+
s_mp_sqr_comba.o s_mp_sqr_karatsuba.o s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
5050

5151
#END_INS
5252

makefile.unix

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ mp_reduce_setup.o mp_root_n.o mp_rshd.o mp_sbin_size.o mp_set.o mp_set_double.o
4747
mp_set_l.o mp_set_u32.o mp_set_u64.o mp_set_ul.o mp_shrink.o mp_signed_rsh.o mp_sqrmod.o mp_sqrt.o \
4848
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 \
4949
mp_unpack.o mp_xor.o mp_zero.o s_mp_add.o s_mp_copy_digs.o s_mp_div_3.o s_mp_div_recursive.o \
50-
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_get_bit.o s_mp_invmod.o \
51-
s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o s_mp_log_d.o s_mp_montgomery_reduce_comba.o s_mp_mul.o \
52-
s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o \
53-
s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o s_mp_radix_map.o \
54-
s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \
55-
s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
50+
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_faster_to_radix.o \
51+
s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o s_mp_log_d.o \
52+
s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o s_mp_mul_high.o \
53+
s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o s_mp_prime_tab.o \
54+
s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o s_mp_slower_to_radix.o s_mp_sqr.o \
55+
s_mp_sqr_comba.o s_mp_sqr_karatsuba.o s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
5656

5757

5858
HEADERS_PUB=tommath.h

mp_to_radix.c

Lines changed: 18 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,16 @@
33
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
44
/* SPDX-License-Identifier: Unlicense */
55

6-
/* reverse an array, used for radix code */
7-
static void s_reverse(char *s, size_t len)
8-
{
9-
size_t ix = 0, iy = len - 1u;
10-
while (ix < iy) {
11-
MP_EXCH(char, s[ix], s[iy]);
12-
++ix;
13-
--iy;
14-
}
15-
}
16-
176
/* stores a bignum as a ASCII string in a given radix (2..64)
187
*
198
* Stores upto "size - 1" chars and always a NULL byte, puts the number of characters
209
* written, including the '\0', in "written".
2110
*/
2211
mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, int radix)
2312
{
24-
size_t digs;
25-
mp_err err;
26-
mp_int t;
27-
mp_digit d;
28-
char *_s = str;
13+
mp_err err;
14+
mp_int a_bar = *a;
15+
size_t part_written = 0;
2916

3017
/* check range of radix and size*/
3118
if (maxlen < 2u) {
@@ -45,50 +32,36 @@ mp_err mp_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, i
4532
return MP_OKAY;
4633
}
4734

48-
if ((err = mp_init_copy(&t, a)) != MP_OKAY) {
49-
return err;
50-
}
51-
5235
/* if it is negative output a - */
53-
if (mp_isneg(&t)) {
54-
/* we have to reverse our digits later... but not the - sign!! */
55-
++_s;
56-
36+
if (mp_isneg(a)) {
5737
/* store the flag and mark the number as positive */
5838
*str++ = '-';
59-
t.sign = MP_ZPOS;
39+
a_bar.sign = MP_ZPOS;
6040

6141
/* subtract a char */
6242
--maxlen;
6343
}
64-
digs = 0u;
65-
while (!mp_iszero(&t)) {
66-
if (--maxlen < 1u) {
67-
/* no more room */
68-
err = MP_BUF;
69-
goto LBL_ERR;
70-
}
71-
if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
72-
goto LBL_ERR;
44+
45+
/* TODO: check if it can be done better */
46+
if (MP_HAS(S_MP_FASTER_TO_RADIX)) {
47+
if ((err = s_mp_faster_to_radix(&a_bar, str, maxlen, &part_written, radix)) != MP_OKAY) goto LBL_ERR;
48+
} else {
49+
if (MP_HAS(S_MP_SLOWER_TO_RADIX)) {
50+
if ((err = s_mp_slower_to_radix(&a_bar, &str, &maxlen, &part_written, radix, false)) != MP_OKAY) goto LBL_ERR;
51+
/* part_written does not count EOS */
52+
part_written++;
7353
}
74-
*str++ = s_mp_radix_map[d];
75-
++digs;
7654
}
77-
/* reverse the digits of the string. In this case _s points
78-
* to the first digit [excluding the sign] of the number
79-
*/
80-
s_reverse(_s, digs);
8155

82-
/* append a NULL so the string is properly terminated */
83-
*str = '\0';
84-
digs++;
56+
/* TODO: Think about adding a function for base-2 radices only although
57+
s_faster_to_radix is rather quick with such radices. */
8558

8659
if (written != NULL) {
87-
*written = mp_isneg(a) ? (digs + 1u): digs;
60+
part_written += mp_isneg(a) ? 1: 0;
61+
*written = part_written;
8862
}
8963

9064
LBL_ERR:
91-
mp_clear(&t);
9265
return err;
9366
}
9467

0 commit comments

Comments
 (0)