Skip to content

Commit fcaa30f

Browse files
committed
variation b
1 parent 4e76ff9 commit fcaa30f

File tree

8 files changed

+178
-96
lines changed

8 files changed

+178
-96
lines changed

bn_deprecated.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,20 +232,16 @@ mp_err mp_n_root(const mp_int *a, mp_digit b, mp_int *c)
232232
#ifdef BN_MP_TORADIX_N_C
233233
mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen)
234234
{
235-
size_t length[1];
236235
if (maxlen < 0) {
237236
return MP_VAL;
238237
}
239-
*length = (size_t)maxlen;
240-
return mp_to_radix(a, str, length, radix);
238+
return mp_to_radix(a, &str, maxlen, NULL, radix);
241239
}
242240
#endif
243241
#ifdef BN_MP_TORADIX_C
244242
mp_err mp_toradix(const mp_int *a, char *str, int radix)
245243
{
246-
size_t length[1];
247-
*length = SIZE_MAX;
248-
return mp_to_radix(a, str, length, radix);
244+
return mp_to_radix(a, &str, 0u, NULL, radix);
249245
}
250246
#endif
251247
#endif

bn_mp_fwrite.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,22 @@
66
#ifndef MP_NO_FILE
77
mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream)
88
{
9-
char *buf;
9+
/* To avoid "uninitialized" warnings */
10+
char *buf = NULL;
1011
mp_err err;
11-
int len;
12-
/* TODO: that's a bit awkward */
13-
size_t length[1];
12+
size_t written;
1413

15-
if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
16-
return err;
17-
}
18-
19-
*length = (size_t)len;
20-
21-
buf = (char *) MP_MALLOC(*length);
22-
if (buf == NULL) {
23-
return MP_MEM;
24-
}
25-
if ((err = mp_to_radix(a, buf, length, radix)) != MP_OKAY) {
14+
if ((err = mp_to_radix(a, &buf, 0u, &written, radix)) != MP_OKAY) {
2615
goto LBL_ERR;
2716
}
28-
if (fwrite(buf, *length, 1uL, stream) != 1uL) {
17+
if (fwrite(buf, written, 1uL, stream) != 1uL) {
2918
err = MP_ERR;
3019
goto LBL_ERR;
3120
}
32-
err = MP_OKAY;
3321

3422
LBL_ERR:
35-
MP_FREE_BUFFER(buf, *length);
23+
/* "written" can be small than the allocated buffer! */
24+
MP_FREE_BUFFER(buf, written);
3625
return err;
3726
}
3827
#endif

bn_mp_radix_size.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
/* SPDX-License-Identifier: Unlicense */
55

66
/* returns size of ASCII reprensentation */
7-
mp_err mp_radix_size(const mp_int *a, int radix, int *size)
7+
mp_err mp_radix_size(const mp_int *a, int radix, size_t *size)
88
{
99
mp_err err;
1010
int digs;

bn_mp_to_radix.c

Lines changed: 94 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,57 +5,132 @@
55

66
/* stores a bignum as a ASCII string in a given radix (2..64)
77
*
8-
* Stores upto maxlen-1 chars and always a NULL byte
8+
* Stores upto "size - 1" chars and always a NULL byte, puts the number of characters
9+
* written, including the '\0', in "written".
10+
* For "size == 0u" the whole number in "a" will get converted.
911
*/
10-
mp_err mp_to_radix(const mp_int *a, char *str, size_t *maxlen, int radix)
12+
mp_err mp_to_radix(const mp_int *a, char **str, size_t size, size_t *written, int radix)
1113
{
12-
int digs;
14+
size_t digs;
1315
mp_err err;
1416
mp_int t;
1517
mp_digit d;
16-
char *_s = str;
18+
char *_s, *tmp;
19+
size_t len;
1720

18-
/* check range of the maxlen, radix */
19-
if ((*maxlen < 2u) || (radix < 2) || (radix > 64)) {
21+
/* check range of radix and size*/
22+
/* "size" includes the NUL byte so must be at least two if it isn't zero which
23+
starts the automatic length-evaluation */
24+
if ((size == 1u) || (radix < 2) || (radix > 64)) {
2025
return MP_VAL;
2126
}
22-
2327
/* quick out if its zero */
2428
if (MP_IS_ZERO(a)) {
25-
*str++ = '0';
26-
*str = '\0';
29+
if (size == 0u) {
30+
if (*str != NULL) {
31+
/* No MP_REALLOC because the old size is unknown */
32+
tmp = realloc(*str, 2u);
33+
if (tmp == NULL) {
34+
return MP_MEM;
35+
}
36+
*str = tmp;
37+
} else {
38+
*str = MP_MALLOC(2u);
39+
if (*str == NULL) {
40+
return MP_MEM;
41+
}
42+
}
43+
}
44+
**str = '0';
45+
(*str)++;
46+
**str = '\0';
47+
if (written != NULL) {
48+
*written = 2u;
49+
}
2750
return MP_OKAY;
2851
}
2952

3053
if ((err = mp_init_copy(&t, a)) != MP_OKAY) {
3154
return err;
3255
}
3356

57+
if (size == 0u) {
58+
/* TODO: is not in this PR */
59+
if (MP_HAS(MP_RADIX_SIZEINBASE)) {
60+
/* if ((err = mp_radix_sizeinbase(&t, base, &len)) != MP_OKAY) goto LBL_ERR; */
61+
} else {
62+
/* TODO: exchange with direct use of mp_ilogb later? */
63+
if ((err = mp_radix_size(&t, radix, &len)) != MP_OKAY) goto LBL_ERR;
64+
}
65+
if (t.sign == MP_NEG) {
66+
/* TODO: check for overflow? */
67+
len++;
68+
}
69+
if (*str != NULL) {
70+
/* No MP_REALLOC because the old size is unknown */
71+
tmp = realloc(*str, len);
72+
if (tmp == NULL) {
73+
return MP_MEM;
74+
}
75+
*str = tmp;
76+
} else {
77+
*str = MP_MALLOC(len);
78+
if (*str == NULL) {
79+
return MP_MEM;
80+
}
81+
}
82+
size = len;
83+
} else {
84+
len = size;
85+
if (t.sign == MP_NEG) {
86+
len++;
87+
}
88+
if (*str != NULL) {
89+
tmp = realloc(*str, len);
90+
if (tmp == NULL) {
91+
return MP_MEM;
92+
}
93+
*str = tmp;
94+
} else {
95+
*str = MP_MALLOC(len);
96+
if (*str == NULL) {
97+
return MP_MEM;
98+
}
99+
}
100+
}
101+
102+
_s = *str;
103+
34104
/* if it is negative output a - */
35105
if (t.sign == MP_NEG) {
36106
/* we have to reverse our digits later... but not the - sign!! */
37107
++_s;
38108

39109
/* store the flag and mark the number as positive */
40-
*str++ = '-';
110+
**str = '-';
111+
(*str)++;
41112
t.sign = MP_ZPOS;
42113

43114
/* subtract a char */
44-
--maxlen;
115+
--len;
45116
}
46117

47118
digs = 0;
48119
while (!MP_IS_ZERO(&t)) {
49-
if (--(*maxlen) < 1u) {
120+
if (--len < 1u) {
50121
/* no more room */
51122
err = MP_VAL;
52123
break;
53124
}
54125
if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
55126
goto LBL_ERR;
56127
}
57-
*str++ = mp_s_rmap[d];
128+
**str = mp_s_rmap[d];
129+
(*str)++;
58130
++digs;
131+
if (digs == size) {
132+
break;
133+
}
59134
}
60135

61136
/* reverse the digits of the string. In this case _s points
@@ -64,9 +139,12 @@ mp_err mp_to_radix(const mp_int *a, char *str, size_t *maxlen, int radix)
64139
s_mp_reverse((unsigned char *)_s, digs);
65140

66141
/* append a NULL so the string is properly terminated */
67-
*str = '\0';
68-
digs++;
69-
*maxlen = (size_t)digs;
142+
**str = '\0';
143+
/* rewind */
144+
*str = _s;
145+
if (written != NULL) {
146+
*written = digs + 1;
147+
}
70148

71149
LBL_ERR:
72150
mp_clear(&t);

demo/main.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,15 @@ int unit_tests(int argc, char **argv);
55

66
void ndraw(mp_int *a, const char *name)
77
{
8-
char *buf;
9-
int size;
10-
size_t length[1];
11-
12-
mp_radix_size(a, 10, &size);
13-
*length = (size_t)size;
14-
buf = (char *)malloc(*length);
15-
if (buf == NULL) {
16-
fprintf(stderr, "\nndraw: malloc(%d) failed\n", size);
17-
exit(EXIT_FAILURE);
18-
}
8+
char *buf = NULL;
9+
size_t written;
10+
11+
1912

2013
printf("%s: ", name);
21-
mp_to_radix(a, buf, length, 10);
14+
mp_to_radix(a, &buf, 0u, &written, 10);
2215
printf("%s\n", buf);
23-
mp_to_radix(a, buf, length, 16);
16+
mp_to_radix(a, &buf, 0u, &written, 16);
2417
printf("0x%s\n", buf);
2518

2619
free(buf);

demo/test.c

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,8 +1187,8 @@ static int test_mp_montgomery_reduce(void)
11871187
{
11881188
mp_digit mp;
11891189
int ix, i, n;
1190-
char buf[4096];
1191-
size_t length[1];
1190+
char *buf = NULL;
1191+
/* size_t written; */
11921192

11931193
mp_int a, b, c, d, e;
11941194
if (mp_init_multi(&a, &b, &c, &d, &e, NULL)!= MP_OKAY) {
@@ -1222,17 +1222,18 @@ static int test_mp_montgomery_reduce(void)
12221222
if (mp_cmp(&c, &d) != MP_EQ) {
12231223
/* *INDENT-OFF* */
12241224
printf("d = e mod a, c = e MOD a\n");
1225-
*length = sizeof(buf);
1226-
mp_to_radix(&a, buf, length, 10); printf("a = %s, length = %zu\n", buf, *length);
1227-
mp_to_radix(&e, buf, length, 10); printf("e = %s, length = %zu\n", buf, *length);
1228-
mp_to_radix(&d, buf, length, 10); printf("d = %s, length = %zu\n", buf, *length);
1229-
mp_to_radix(&c, buf, length, 10); printf("c = %s, length = %zu\n", buf, *length);
12301225
/*
1231-
mp_to_decimal(&a, buf, sizeof(buf)); printf("a = %s\n", buf);
1232-
mp_to_decimal(&e, buf, sizeof(buf)); printf("e = %s\n", buf);
1233-
mp_to_decimal(&d, buf, sizeof(buf)); printf("d = %s\n", buf);
1234-
mp_to_decimal(&c, buf, sizeof(buf)); printf("c = %s\n", buf);
1226+
mp_to_radix(&a, &buf, 0u, &written, 10); printf("a = %s, written = %zu\n", buf, written);
1227+
mp_to_radix(&e, &buf, 0u, &written, 10); printf("e = %s, written = %zu\n", buf, written);
1228+
mp_to_radix(&d, &buf, 0u, &written, 10); printf("d = %s, written = %zu\n", buf, written);
1229+
mp_to_radix(&c, &buf, 0u, &written, 10); printf("c = %s, written = %zu\n", buf, written);
12351230
*/
1231+
1232+
mp_to_decimal(&a, &buf, 0u); printf("a = %s\n", buf);
1233+
mp_to_decimal(&e, &buf, 0u); printf("e = %s\n", buf);
1234+
mp_to_decimal(&d, &buf, 0u); printf("d = %s\n", buf);
1235+
mp_to_decimal(&c, &buf, 0u); printf("c = %s\n", buf);
1236+
12361237
printf("compare no compare!\n"); goto LBL_ERR;
12371238
/* *INDENT-ON* */
12381239
}
@@ -1246,46 +1247,47 @@ static int test_mp_montgomery_reduce(void)
12461247
}
12471248

12481249
printf("\n\n");
1250+
free(buf);
12491251

12501252
mp_clear_multi(&a, &b, &c, &d, &e, NULL);
12511253
return EXIT_SUCCESS;
12521254
LBL_ERR:
1255+
free(buf);
12531256
mp_clear_multi(&a, &b, &c, &d, &e, NULL);
12541257
return EXIT_FAILURE;
12551258

12561259
}
12571260

12581261
static int test_mp_read_radix(void)
12591262
{
1260-
char buf[4096];
1261-
size_t length[1];
1263+
char *buf = NULL;
1264+
size_t written;
12621265

12631266
mp_int a;
12641267
if (mp_init_multi(&a, NULL)!= MP_OKAY) {
12651268
return EXIT_FAILURE;
12661269
}
12671270

12681271
mp_read_radix(&a, "123456", 10);
1269-
*length = 3u;
1270-
mp_to_radix(&a, buf, length, 10);
1271-
printf("a == %s, length = %zu\n", buf, *length);
1272-
*length = 4u;
1273-
mp_to_radix(&a, buf, length, 10);
1274-
printf("a == %s, length = %zu\n", buf, *length);
1275-
*length = 30u;
1276-
mp_to_radix(&a, buf, length, 10);
1277-
printf("a == %s, length = %zu\n", buf, *length);
1272+
1273+
mp_to_radix(&a, &buf, 3u, &written, 10);
1274+
printf("a == %s, length = %zu\n", buf, written);
1275+
mp_to_radix(&a, &buf, 4u, &written, 10);
1276+
printf("a == %s, length = %zu\n", buf, written);
1277+
mp_to_radix(&a, &buf, 30u, &written, 10);
1278+
printf("a == %s, length = %zu\n", buf, written);
12781279

12791280
while (0) {
1280-
char *s = fgets(buf, sizeof(buf), stdin);
1281-
if (s != buf) break;
1282-
mp_read_radix(&a, buf, 10);
1281+
char line_buffer[4096];
1282+
char *s = fgets(line_buffer, sizeof(line_buffer), stdin);
1283+
if (s != line_buffer) break;
1284+
mp_read_radix(&a, line_buffer, 10);
12831285
mp_prime_next_prime(&a, 5, 1);
1284-
*length = sizeof(buf);
1285-
mp_to_radix(&a, buf, length, 10);
1286+
mp_to_radix(&a, &buf, 0u, NULL, 10);
12861287
printf("%s, %lu\n", buf, (unsigned long)a.dp[0] & 3uL);
12871288
}
12881289

1290+
free(buf);
12891291
mp_clear_multi(&a, NULL);
12901292
return EXIT_SUCCESS;
12911293
}
@@ -1838,6 +1840,7 @@ static int test_mp_decr(void)
18381840
All numbers as strings to simplifiy things, especially for the
18391841
low-mp branch.
18401842
*/
1843+
18411844
static int test_mp_root_u32(void)
18421845
{
18431846
mp_int a, c, r;

0 commit comments

Comments
 (0)