Skip to content

Commit f0f5bb7

Browse files
committed
Fix problems found by travis and appveyor
1 parent 78be8b8 commit f0f5bb7

File tree

3 files changed

+185
-183
lines changed

3 files changed

+185
-183
lines changed

bn_mp_todecimal_fast.c

+181-177
Original file line numberDiff line numberDiff line change
@@ -1,199 +1,203 @@
11
#include "tommath_private.h"
22
#include <string.h>
3+
#include <stdio.h>
34
#ifdef BN_MP_TODECIMAL_FAST_C
45
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
56
/* SPDX-License-Identifier: Unlicense */
67

78
/* store a bignum as a decimal ASCII string */
8-
mp_err mp_todecimal_fast_rec(mp_int *number, mp_int *nL, mp_int *shiftL, mp_int *mL, int index, int left, char **result) {
9-
mp_int q, nLq, r;
10-
mp_err err;
11-
12-
if (index < 0) {
13-
char *next_piece = calloc(4, sizeof(char));
14-
int s_s = snprintf(next_piece, 4, left ? "%u" : "%03u", mp_get_u32(number));
15-
int r_s = strlen(*result);
16-
(*result) = realloc(*result, r_s + s_s + 2);
17-
strcat(*result, next_piece);
18-
return MP_OKAY;
19-
}
20-
21-
if ((err = mp_init_multi(&q, &nLq, &r, NULL)) != MP_OKAY) {
22-
goto LBL_ERR;
23-
}
24-
if ((err = mp_mul(number, &mL[index], &q)) != MP_OKAY) {
25-
goto LBL_ERR;
26-
}
27-
if ((err = mp_div_2d(&q, mp_get_u32(&shiftL[index]), &q, NULL)) != MP_OKAY) {
28-
goto LBL_ERR;
29-
}
30-
31-
if ((err = mp_mul(&nL[index], &q, &nLq)) != MP_OKAY) {
32-
goto LBL_ERR;
33-
}
34-
35-
if ((err = mp_sub(number, &nLq, &r)) != MP_OKAY) {
36-
goto LBL_ERR;
37-
}
38-
39-
if (mp_isneg(&r)) {
40-
if ((err = mp_sub_d(&q, 1, &q)) != MP_OKAY) {
9+
mp_err mp_todecimal_fast_rec(mp_int *number, mp_int *nL, mp_int *shiftL, mp_int *mL, int precalc_array_index, int left,
10+
char **result)
11+
{
12+
mp_int q, nLq, r;
13+
mp_err err;
14+
15+
if (precalc_array_index < 0) {
16+
char *next_piece = calloc(4, sizeof(char));
17+
int s_s = left ? snprintf(next_piece, 4, "%u", mp_get_i32(number)) : snprintf(next_piece, 4, "%03u",
18+
mp_get_i32(number));
19+
int r_s = (int)strlen(*result);
20+
(*result) = realloc(*result, (size_t)(r_s + s_s + 2));
21+
strcat(*result, next_piece);
22+
return MP_OKAY;
23+
}
24+
25+
if ((err = mp_init_multi(&q, &nLq, &r, NULL)) != MP_OKAY) {
26+
goto LBL_ERR;
27+
}
28+
if ((err = mp_mul(number, &mL[precalc_array_index], &q)) != MP_OKAY) {
29+
goto LBL_ERR;
30+
}
31+
if ((err = mp_div_2d(&q, mp_get_i32(&shiftL[precalc_array_index]), &q, NULL)) != MP_OKAY) {
32+
goto LBL_ERR;
33+
}
34+
35+
if ((err = mp_mul(&nL[precalc_array_index], &q, &nLq)) != MP_OKAY) {
36+
goto LBL_ERR;
37+
}
38+
39+
if ((err = mp_sub(number, &nLq, &r)) != MP_OKAY) {
40+
goto LBL_ERR;
41+
}
42+
43+
if (mp_isneg(&r)) {
44+
if ((err = mp_sub_d(&q, 1, &q)) != MP_OKAY) {
45+
goto LBL_ERR;
46+
}
47+
if ((err = mp_add(&r, &nL[precalc_array_index], &r)) != MP_OKAY) {
48+
goto LBL_ERR;
49+
}
50+
}
51+
52+
--precalc_array_index;
53+
if (left && mp_iszero(&q)) {
54+
if ((err = mp_todecimal_fast_rec(&r, nL, shiftL, mL, precalc_array_index, 1, result)) != MP_OKAY) {
55+
goto LBL_ERR;
56+
}
57+
} else {
58+
if ((err = mp_todecimal_fast_rec(&q, nL, shiftL, mL, precalc_array_index, left, result)) != MP_OKAY) {
59+
goto LBL_ERR;
60+
}
61+
if ((err = mp_todecimal_fast_rec(&r, nL, shiftL, mL, precalc_array_index, 0, result)) != MP_OKAY) {
62+
goto LBL_ERR;
63+
}
64+
}
65+
66+
err = MP_OKAY;
67+
68+
LBL_ERR:
69+
mp_clear_multi(&q, &nLq, &r, NULL);
70+
return err;
71+
}
72+
73+
mp_err mp_todecimal_fast(mp_int *number, char **result)
74+
{
75+
mp_int n, shift, M, M2, M22, M4, M44;
76+
mp_int nL[20], shiftL[20], mL[20];
77+
mp_err err;
78+
int precalc_array_index = 1;
79+
80+
if ((err = mp_init_multi(&M2, &M22, &M4, &M44, NULL)) != MP_OKAY) {
81+
goto LBL_ERR;
82+
}
83+
84+
if (mp_isneg(number)) {
85+
if ((err = mp_neg(number, number)) != MP_OKAY) {
86+
goto LBL_ERR;
87+
}
88+
*result[0] = '-';
89+
}
90+
if ((err = mp_init_set(&n, (mp_digit)1000)) != MP_OKAY) {
91+
goto LBL_ERR;
92+
}
93+
94+
if ((err = mp_init_copy(&nL[0], &n)) != MP_OKAY) {
95+
goto LBL_ERR;
96+
}
97+
98+
if ((err = mp_init_set(&shift, (mp_digit)20)) != MP_OKAY) {
99+
goto LBL_ERR;
100+
}
101+
102+
if ((err = mp_init_copy(&shiftL[0], &shift)) != MP_OKAY) {
103+
goto LBL_ERR;
104+
}
105+
106+
/* (8 * 2**$shift) / $n rounded up */
107+
if ((err = mp_init_set(&M, (mp_digit)8389)) != MP_OKAY) {
108+
goto LBL_ERR;
109+
}
110+
111+
/* $M / 8, rounded up */
112+
if ((err = mp_init_set(&mL[0], (mp_digit)1049)) != MP_OKAY) {
113+
goto LBL_ERR;
114+
}
115+
116+
while (1) {
117+
if ((err = mp_sqr(&n, &n)) != MP_OKAY) {
118+
goto LBL_ERR;
119+
}
120+
if (mp_cmp(&n, number) == MP_GT) {
121+
break;
122+
}
123+
124+
if ((err = mp_mul_2(&shift, &shift)) != MP_OKAY) {
125+
goto LBL_ERR;
126+
}
127+
128+
/* The following is a Newton-Raphson step, to restore the invariant
129+
* that $M is (8 * 2**$shift) / $n, rounded up. */
130+
{
131+
if ((err = mp_sqr(&M, &M2)) != MP_OKAY) {
41132
goto LBL_ERR;
42-
}
43-
if ((err = mp_add(&r, &nL[index], &r)) != MP_OKAY) {
133+
}
134+
if ((err = mp_sqr(&M2, &M4)) != MP_OKAY) {
44135
goto LBL_ERR;
45-
}
46-
}
136+
}
47137

48-
--index;
49-
if (left && mp_iszero(&q)) {
50-
if ((err = mp_todecimal_fast_rec(&r, nL, shiftL, mL, index, 1, result)) != MP_OKAY) {
138+
if ((err = mp_mul(&M4, &n, &M4)) != MP_OKAY) {
51139
goto LBL_ERR;
52-
}
53-
} else {
54-
if ((err = mp_todecimal_fast_rec(&q, nL, shiftL, mL, index, left, result)) != MP_OKAY) {
140+
}
141+
if ((err = mp_div_2d(&M4, mp_get_i32(&shift) + 6, &M4, NULL)) != MP_OKAY) {
55142
goto LBL_ERR;
56-
}
57-
if ((err = mp_todecimal_fast_rec(&r, nL, shiftL, mL, index, 0, result)) != MP_OKAY) {
143+
}
144+
if ((err = mp_mul_2(&M2, &M2)) != MP_OKAY) {
58145
goto LBL_ERR;
59-
}
60-
}
61-
62-
err = MP_OKAY;
63-
64-
LBL_ERR:mp_clear_multi (&q, &nLq, &r, NULL);
65-
return err;
66-
}
67-
68-
mp_err mp_todecimal_fast(mp_int *number, char **result) {
69-
mp_int n, shift, M, M2, M22, M4, M44;
70-
mp_int *nL, *shiftL, *mL;
71-
mp_err err;
72-
int index = 1;
73-
74-
if ((err = mp_init_multi(&M2, &M22, &M4, &M44, NULL)) != MP_OKAY) {
75-
goto LBL_ERR;
76-
}
77-
78-
if (mp_isneg(number)) {
79-
if ((err = mp_neg(number, number)) != MP_OKAY) {
146+
}
147+
if ((err = mp_sub(&M4, &M2, &M4)) != MP_OKAY) {
80148
goto LBL_ERR;
81-
}
82-
*result[0] = '-';
83-
}
84-
if ((err = mp_init_set(&n, 1000)) != MP_OKAY) {
85-
goto LBL_ERR;
86-
}
87-
88-
nL = malloc(20 * sizeof(mp_int));
89-
if ((err = mp_init_copy(&nL[0], &n)) != MP_OKAY) {
90-
goto LBL_ERR;
91-
}
92-
93-
if ((err = mp_init_set(&shift, 20)) != MP_OKAY) {
94-
goto LBL_ERR;
95-
}
96-
97-
shiftL = malloc(20 * sizeof(mp_int));
98-
if ((err = mp_init_copy(&shiftL[0], &shift)) != MP_OKAY) {
99-
goto LBL_ERR;
100-
}
101-
102-
/* (8 * 2**$shift) / $n rounded up */
103-
if ((err = mp_init_set(&M, 8389)) != MP_OKAY) {
104-
goto LBL_ERR;
105-
}
106-
107-
/* $M / 8, rounded up */
108-
mL = malloc(20 * sizeof(mp_int));
109-
if ((err = mp_init_set(&mL[0], 1049)) != MP_OKAY) {
110-
goto LBL_ERR;
111-
}
112-
113-
while (1) {
114-
if ((err = mp_sqr(&n, &n)) != MP_OKAY) {
149+
}
150+
if ((err = mp_add_d(&M4, 1, &M4)) != MP_OKAY) {
115151
goto LBL_ERR;
116-
}
117-
if (mp_cmp(&n, number) == MP_GT) {
118-
break;
119-
}
120-
121-
if ((err = mp_mul_2(&shift, &shift)) != MP_OKAY) {
152+
}
153+
if ((err = mp_div_2d(&M4, 3, &M4, NULL)) != MP_OKAY) {
122154
goto LBL_ERR;
123-
}
124-
125-
/* The following is a Newton-Raphson step, to restore the invariant
126-
* that $M is (8 * 2**$shift) / $n, rounded up. */
127-
{
128-
if ((err = mp_sqr(&M, &M2)) != MP_OKAY) {
129-
goto LBL_ERR;
130-
}
131-
if ((err = mp_sqr(&M2, &M4)) != MP_OKAY) {
132-
goto LBL_ERR;
133-
}
134-
135-
if ((err = mp_mul(&M4, &n, &M4)) != MP_OKAY) {
136-
goto LBL_ERR;
137-
}
138-
if ((err = mp_div_2d(&M4, mp_get_ul(&shift) + 6, &M4, NULL)) != MP_OKAY) {
139-
goto LBL_ERR;
140-
}
141-
if ((err = mp_mul_2(&M2, &M2)) != MP_OKAY) {
142-
goto LBL_ERR;
143-
}
144-
if ((err = mp_sub(&M4, &M2, &M4)) != MP_OKAY) {
145-
goto LBL_ERR;
146-
}
147-
if ((err = mp_add_d(&M4, 1, &M4)) != MP_OKAY) {
148-
goto LBL_ERR;
149-
}
150-
if ((err = mp_div_2d(&M4, 3, &M4, NULL)) != MP_OKAY) {
151-
goto LBL_ERR;
152-
}
153-
if ((err = mp_sub_d(&M4, 1, &M4)) != MP_OKAY) {
154-
goto LBL_ERR;
155-
}
156-
if ((err = mp_neg(&M4, &M)) != MP_OKAY) {
157-
goto LBL_ERR;
158-
}
159-
}
160-
161-
if ((err = mp_init_copy(&nL[index], &n)) != MP_OKAY) {
155+
}
156+
if ((err = mp_sub_d(&M4, 1, &M4)) != MP_OKAY) {
162157
goto LBL_ERR;
163-
}
164-
if ((err = mp_init_copy(&shiftL[index], &shift)) != MP_OKAY) {
158+
}
159+
if ((err = mp_neg(&M4, &M)) != MP_OKAY) {
165160
goto LBL_ERR;
166-
}
167-
168-
/* Divide by 8, round up */
169-
{
170-
if ((err = mp_add_d(&M4, 1, &M4)) != MP_OKAY) {
171-
goto LBL_ERR;
172-
}
173-
if ((err = mp_div_2d(&M4, 3, &M4, NULL)) != MP_OKAY) {
174-
goto LBL_ERR;
175-
}
176-
if ((err = mp_sub_d(&M4, 1, &M4)) != MP_OKAY) {
177-
goto LBL_ERR;
178-
}
179-
if ((err = mp_neg(&M4, &M4)) != MP_OKAY) {
180-
goto LBL_ERR;
181-
}
182-
}
183-
if ((err = mp_init_copy(&mL[index], &M4)) != MP_OKAY) {
161+
}
162+
}
163+
164+
if ((err = mp_init_copy(&nL[precalc_array_index], &n)) != MP_OKAY) {
165+
goto LBL_ERR;
166+
}
167+
if ((err = mp_init_copy(&shiftL[precalc_array_index], &shift)) != MP_OKAY) {
168+
goto LBL_ERR;
169+
}
170+
171+
/* Divide by 8, round up */
172+
{
173+
if ((err = mp_add_d(&M4, 1, &M4)) != MP_OKAY) {
184174
goto LBL_ERR;
185-
}
186-
index++;
187-
}
188-
189-
if ((err = mp_todecimal_fast_rec(number, nL, shiftL, mL, index - 1, 1, result)) != MP_OKAY) {
190-
goto LBL_ERR;
191-
}
192-
193-
err = MP_OKAY;
194-
195-
LBL_ERR:mp_clear_multi (&n, &shift, &M, &M2, &M22, &M4, &M44, NULL);
196-
return err;
175+
}
176+
if ((err = mp_div_2d(&M4, 3, &M4, NULL)) != MP_OKAY) {
177+
goto LBL_ERR;
178+
}
179+
if ((err = mp_sub_d(&M4, 1, &M4)) != MP_OKAY) {
180+
goto LBL_ERR;
181+
}
182+
if ((err = mp_neg(&M4, &M4)) != MP_OKAY) {
183+
goto LBL_ERR;
184+
}
185+
}
186+
if ((err = mp_init_copy(&mL[precalc_array_index], &M4)) != MP_OKAY) {
187+
goto LBL_ERR;
188+
}
189+
precalc_array_index++;
190+
}
191+
192+
if ((err = mp_todecimal_fast_rec(number, nL, shiftL, mL, precalc_array_index - 1, 1, result)) != MP_OKAY) {
193+
goto LBL_ERR;
194+
}
195+
196+
err = MP_OKAY;
197+
198+
LBL_ERR:
199+
mp_clear_multi(&n, &shift, &M, &M2, &M22, &M4, &M44, NULL);
200+
return err;
197201
}
198202

199203
#endif

tommath.def

+1
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ EXPORTS
140140
mp_to_signed_bin_n
141141
mp_to_unsigned_bin
142142
mp_to_unsigned_bin_n
143+
mp_todecimal_fast
143144
mp_toradix
144145
mp_toradix_n
145146
mp_unsigned_bin_size

0 commit comments

Comments
 (0)