Skip to content

Commit 6ac8135

Browse files
committed
Addition of faster read_radix method
1 parent 8163210 commit 6ac8135

12 files changed

+203
-68
lines changed

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_read_radix.c"
829+
>
830+
</File>
827831
<File
828832
RelativePath="s_mp_faster_to_radix.c"
829833
>
@@ -904,6 +908,10 @@
904908
RelativePath="s_mp_rand_platform.c"
905909
>
906910
</File>
911+
<File
912+
RelativePath="s_mp_slower_read_radix.c"
913+
>
914+
</File>
907915
<File
908916
RelativePath="s_mp_slower_to_radix.c"
909917
>

makefile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,13 @@ 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_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
47+
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_faster_read_radix.o \
48+
s_mp_faster_to_radix.o s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o \
49+
s_mp_log_d.o s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o \
50+
s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o \
51+
s_mp_prime_tab.o s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o \
52+
s_mp_slower_read_radix.o s_mp_slower_to_radix.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \
53+
s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
5354

5455
#END_INS
5556

makefile.mingw

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ 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_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
49+
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_faster_read_radix.o \
50+
s_mp_faster_to_radix.o s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o \
51+
s_mp_log_d.o s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o \
52+
s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o \
53+
s_mp_prime_tab.o s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o \
54+
s_mp_slower_read_radix.o s_mp_slower_to_radix.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
5556

5657
HEADERS_PUB=tommath.h
5758
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)

makefile.msvc

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,13 @@ 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_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
45+
s_mp_div_school.obj s_mp_div_small.obj s_mp_exptmod.obj s_mp_exptmod_fast.obj s_mp_faster_read_radix.obj \
46+
s_mp_faster_to_radix.obj s_mp_get_bit.obj s_mp_invmod.obj s_mp_invmod_odd.obj s_mp_log.obj s_mp_log_2expt.obj \
47+
s_mp_log_d.obj s_mp_montgomery_reduce_comba.obj s_mp_mul.obj s_mp_mul_balance.obj s_mp_mul_comba.obj \
48+
s_mp_mul_high.obj s_mp_mul_high_comba.obj s_mp_mul_karatsuba.obj s_mp_mul_toom.obj s_mp_prime_is_divisible.obj \
49+
s_mp_prime_tab.obj s_mp_radix_map.obj s_mp_radix_size_overestimate.obj s_mp_rand_platform.obj \
50+
s_mp_slower_read_radix.obj s_mp_slower_to_radix.obj s_mp_sqr.obj s_mp_sqr_comba.obj s_mp_sqr_karatsuba.obj \
51+
s_mp_sqr_toom.obj s_mp_sub.obj s_mp_zero_buf.obj s_mp_zero_digs.obj
5152

5253
HEADERS_PUB=tommath.h
5354
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)

makefile.shared

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ 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_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
44+
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_faster_read_radix.o \
45+
s_mp_faster_to_radix.o s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o \
46+
s_mp_log_d.o s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o \
47+
s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o \
48+
s_mp_prime_tab.o s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o \
49+
s_mp_slower_read_radix.o s_mp_slower_to_radix.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \
50+
s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
5051

5152
#END_INS
5253

makefile.unix

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ 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_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
50+
s_mp_div_school.o s_mp_div_small.o s_mp_exptmod.o s_mp_exptmod_fast.o s_mp_faster_read_radix.o \
51+
s_mp_faster_to_radix.o s_mp_get_bit.o s_mp_invmod.o s_mp_invmod_odd.o s_mp_log.o s_mp_log_2expt.o \
52+
s_mp_log_d.o s_mp_montgomery_reduce_comba.o s_mp_mul.o s_mp_mul_balance.o s_mp_mul_comba.o \
53+
s_mp_mul_high.o s_mp_mul_high_comba.o s_mp_mul_karatsuba.o s_mp_mul_toom.o s_mp_prime_is_divisible.o \
54+
s_mp_prime_tab.o s_mp_radix_map.o s_mp_radix_size_overestimate.o s_mp_rand_platform.o \
55+
s_mp_slower_read_radix.o s_mp_slower_to_radix.o s_mp_sqr.o s_mp_sqr_comba.o s_mp_sqr_karatsuba.o \
56+
s_mp_sqr_toom.o s_mp_sub.o s_mp_zero_buf.o s_mp_zero_digs.o
5657

5758

5859
HEADERS_PUB=tommath.h

mp_read_radix.c

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

6+
static size_t s_mp_strlen(const char *s)
7+
{
8+
const char *p;
9+
p = s;
10+
while (*p != '\0') {
11+
p++;
12+
}
13+
return (size_t)(p - s);
14+
}
15+
616
/* read a string [ASCII] in a given radix */
717
mp_err mp_read_radix(mp_int *a, const char *str, int radix)
818
{
19+
920
mp_err err;
1021
mp_sign sign = MP_ZPOS;
1122

@@ -22,48 +33,25 @@ mp_err mp_read_radix(mp_int *a, const char *str, int radix)
2233
sign = MP_NEG;
2334
}
2435

25-
/* set the integer to the default of zero */
2636
mp_zero(a);
2737

28-
/* process each digit of the string */
29-
while (*str != '\0') {
30-
/* if the radix <= 36 the conversion is case insensitive
31-
* this allows numbers like 1AB and 1ab to represent the same value
32-
* [e.g. in hex]
33-
*/
34-
uint8_t y;
35-
char ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str;
36-
unsigned pos = (unsigned)(ch - '+');
37-
if (MP_RADIX_MAP_REVERSE_SIZE <= pos) {
38-
break;
39-
}
40-
y = s_mp_radix_map_reverse[pos];
41-
42-
/* if the char was found in the map
43-
* and is less than the given radix add it
44-
* to the number, otherwise exit the loop.
45-
*/
46-
if (y >= radix) {
47-
break;
48-
}
49-
if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) {
50-
return err;
51-
}
52-
if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
53-
return err;
54-
}
55-
++str;
56-
}
57-
58-
/* if an illegal character was found, fail. */
59-
if ((*str != '\0') && (*str != '\r') && (*str != '\n')) {
60-
return MP_VAL;
38+
/* Try faster version first */
39+
if (MP_HAS(S_MP_FASTER_READ_RADIX)) {
40+
if ((err = s_mp_faster_read_radix(a, str, 0, (int)s_mp_strlen(str),
41+
radix)) != MP_OKAY) goto LTM_ERR;
42+
} else if (MP_HAS(S_MP_SLOWER_READ_RADIX)) {
43+
if ((err = s_mp_slower_read_radix(a, str, 0, (int)s_mp_strlen(str),
44+
radix)) != MP_OKAY) goto LTM_ERR;
6145
}
6246

6347
/* set the sign only if a != 0 */
6448
if (!mp_iszero(a)) {
6549
a->sign = sign;
6650
}
67-
return MP_OKAY;
51+
52+
LTM_ERR:
53+
return err;
54+
6855
}
56+
6957
#endif

s_mp_faster_read_radix.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include "tommath_private.h"
2+
#ifdef S_MP_FASTER_READ_RADIX_C
3+
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
4+
/* SPDX-License-Identifier: Unlicense */
5+
6+
/* TODO: It is tunable */
7+
#define MP_READ_RADIX_CUTOFF_MULTIPLICATOR 3
8+
9+
/* for(n=2,64,t = ceil(log(2^100)/log(n)); printf(t", "); ) */
10+
static const uint8_t s_read_radix_cutoff[65] = { 0, 0, /* 0 .. 1*/
11+
100, 64, 50, 44, 39, 36, 34, 32, /* 2 .. 9 */
12+
31, 29, 28, 28, 27, 26, 25, 25, /* 10 .. 17 */
13+
24, 24, 24, 23, 23, 23, 22, 22, /* 18 .. 25 */
14+
22, 22, 21, 21, 21, 21, 20, 20, /* 26 .. 33 */
15+
20, 20, 20, 20, 20, 19, 19, 19, /* 34 .. 41 */
16+
19, 19, 19, 19, 19, 19, 18, 18, /* 42 .. 49 */
17+
18, 18, 18, 18, 18, 18, 18, 18, /* 51 .. 57 */
18+
18, 17, 17, 17, 17, 17, 17 /* 58 .. 64 */
19+
};
20+
21+
/* This is in mp_prime_is_prime.c and can be reused */
22+
static int s_floor_ilog2(int value)
23+
{
24+
unsigned int r = 0;
25+
while ((value >>= 1) != 0) {
26+
r++;
27+
}
28+
return r;
29+
}
30+
31+
32+
mp_err s_mp_faster_read_radix(mp_int *a, const char *str, int start, int end, int radix)
33+
{
34+
int len, mid;
35+
mp_int A, B, m;
36+
mp_err err = MP_OKAY;
37+
38+
len = end - start;
39+
40+
if (len < (s_read_radix_cutoff[radix] * MP_READ_RADIX_CUTOFF_MULTIPLICATOR)) {
41+
return s_mp_slower_read_radix(a, str, start, end, radix);
42+
}
43+
44+
mid = len / 2;
45+
46+
if ((err = mp_init_set(&m, radix)) != MP_OKAY) {
47+
return err;
48+
}
49+
if ((err = mp_init_multi(&A, &B, NULL)) != MP_OKAY) {
50+
mp_clear(&m);
51+
return err;
52+
}
53+
54+
if ((err = s_mp_slower_read_radix(&A, str, start, start + mid + 1, radix)) != MP_OKAY) goto LTM_ERR;
55+
if ((err = s_mp_slower_read_radix(&B, str, start + mid + 1, end, radix)) != MP_OKAY) goto LTM_ERR;
56+
57+
if (MP_IS_2EXPT(radix)) {
58+
if ((err = mp_mul_2d(&A, ((len - mid) -1) * s_floor_ilog2(radix), &A)) != MP_OKAY) goto LTM_ERR;
59+
} else {
60+
if ((err = mp_expt_n(&m, (len - mid) - 1, &m)) != MP_OKAY) goto LTM_ERR;
61+
if ((err = mp_mul(&A, &m, &A)) != MP_OKAY) goto LTM_ERR;
62+
}
63+
if ((err = mp_add(&A, &B, a)) != MP_OKAY) goto LTM_ERR;
64+
65+
LTM_ERR:
66+
mp_clear_multi(&A, &B, &m, NULL);
67+
return err;
68+
}
69+
70+
#endif

s_mp_faster_to_radix.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static mp_err s_mp_to_radix_recursive(const mp_int *a, char **str, size_t *part_
9191
mp_err s_mp_faster_to_radix(const mp_int *a, char *str, size_t maxlen, size_t *written, int radix)
9292
{
9393
mp_err err;
94-
int32_t n = 0, k, t = 0, steps;
94+
int32_t n = 0, k, t = 0, steps = 0;
9595
int ilog2a;
9696

9797
/* Use given buffer directly, no temporary buffers for the individual chunks */

s_mp_slower_read_radix.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "tommath_private.h"
2+
#ifdef S_MP_SLOWER_READ_RADIX_C
3+
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
4+
/* SPDX-License-Identifier: Unlicense */
5+
6+
mp_err s_mp_slower_read_radix(mp_int *a, const char *str, int start, int end, int radix)
7+
{
8+
mp_err err;
9+
int i;
10+
11+
/* checks are done by caller */
12+
13+
char *_s = (char *)(str + start);
14+
for (i = start; i < end; i++) {
15+
uint8_t y;
16+
17+
char ch = (radix <= 36) ? (char)MP_TOUPPER((int)*_s) : *_s;
18+
unsigned int pos = (unsigned int)(ch - '+');
19+
if (MP_RADIX_MAP_REVERSE_SIZE <= pos) {
20+
err = MP_VAL;
21+
goto LBL_ERR;
22+
}
23+
y = s_mp_radix_map_reverse[pos];
24+
if (y >= radix) {
25+
err = MP_VAL;
26+
goto LBL_ERR;
27+
}
28+
if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) goto LBL_ERR;
29+
if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) goto LBL_ERR;
30+
_s++;
31+
}
32+
33+
return MP_OKAY;
34+
LBL_ERR:
35+
mp_zero(a);
36+
return err;
37+
}
38+
39+
#endif

0 commit comments

Comments
 (0)