Skip to content

Commit e66be11

Browse files
authored
Merge pull request #366 from czurnieden/radix_size_with_log
Use of mp_ilogb in mp_radix_size
2 parents 0a3fa32 + 80f5818 commit e66be11

File tree

4 files changed

+69
-42
lines changed

4 files changed

+69
-42
lines changed

bn_mp_radix_size.c

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@
66
/* returns size of ASCII representation */
77
mp_err mp_radix_size(const mp_int *a, int radix, int *size)
88
{
9-
mp_err err;
10-
int digs;
11-
mp_int t;
12-
mp_digit d;
13-
14-
*size = 0;
9+
mp_err err;
10+
mp_int a_;
11+
uint32_t b;
1512

1613
/* make sure the radix is in range */
1714
if ((radix < 2) || (radix > 64)) {
@@ -23,43 +20,18 @@ mp_err mp_radix_size(const mp_int *a, int radix, int *size)
2320
return MP_OKAY;
2421
}
2522

26-
/* special case for binary */
27-
if (radix == 2) {
28-
*size = (mp_count_bits(a) + ((a->sign == MP_NEG) ? 1 : 0) + 1);
29-
return MP_OKAY;
30-
}
31-
32-
/* digs is the digit count */
33-
digs = 0;
34-
35-
/* if it's negative add one for the sign */
36-
if (a->sign == MP_NEG) {
37-
++digs;
38-
}
39-
40-
/* init a copy of the input */
41-
if ((err = mp_init_copy(&t, a)) != MP_OKAY) {
42-
return err;
23+
a_ = *a;
24+
a_.sign = MP_ZPOS;
25+
if ((err = mp_log_u32(&a_, (uint32_t)radix, &b)) != MP_OKAY) {
26+
goto LBL_ERR;
4327
}
4428

45-
/* force temp to positive */
46-
t.sign = MP_ZPOS;
29+
*size = (int)b;
4730

48-
/* fetch out all of the digits */
49-
while (!MP_IS_ZERO(&t)) {
50-
if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) {
51-
goto LBL_ERR;
52-
}
53-
++digs;
54-
}
55-
56-
/* return digs + 1, the 1 is for the NULL byte that would be required. */
57-
*size = digs + 1;
58-
err = MP_OKAY;
31+
/* mp_ilogb truncates to zero, hence we need one extra put on top and one for `\0`. */
32+
*size += 2 + (a->sign == MP_NEG);
5933

6034
LBL_ERR:
61-
mp_clear(&t);
6235
return err;
6336
}
64-
6537
#endif

demo/test.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2282,6 +2282,62 @@ static int test_s_mp_toom_sqr(void)
22822282
return EXIT_FAILURE;
22832283
}
22842284

2285+
static int test_mp_radix_size(void)
2286+
{
2287+
mp_err err;
2288+
mp_int a;
2289+
int radix, size;
2290+
/* *INDENT-OFF* */
2291+
int results[65] = {
2292+
0, 0, 1627, 1027, 814, 702, 630, 581, 543,
2293+
514, 491, 471, 455, 441, 428, 418, 408, 399,
2294+
391, 384, 378, 372, 366, 361, 356, 352, 347,
2295+
343, 340, 336, 333, 330, 327, 324, 321, 318,
2296+
316, 314, 311, 309, 307, 305, 303, 301, 299,
2297+
298, 296, 294, 293, 291, 290, 288, 287, 285,
2298+
284, 283, 281, 280, 279, 278, 277, 276, 275,
2299+
273, 272
2300+
};
2301+
/* *INDENT-ON* */
2302+
2303+
mp_init(&a);
2304+
2305+
/* number to result in a different size for every base: 67^(4 * 67) */
2306+
mp_set(&a, 67);
2307+
if ((err = mp_expt_u32(&a, 268u, &a)) != MP_OKAY) {
2308+
goto LTM_ERR;
2309+
}
2310+
2311+
for (radix = 2; radix < 65; radix++) {
2312+
if ((err = mp_radix_size(&a, radix, &size)) != MP_OKAY) {
2313+
goto LTM_ERR;
2314+
}
2315+
if (size != results[radix]) {
2316+
fprintf(stderr, "mp_radix_size: result for base %d was %d instead of %d\n",
2317+
radix, size, results[radix]);
2318+
goto LTM_ERR;
2319+
}
2320+
a.sign = MP_NEG;
2321+
if ((err = mp_radix_size(&a, radix, &size)) != MP_OKAY) {
2322+
goto LTM_ERR;
2323+
}
2324+
if (size != (results[radix] + 1)) {
2325+
fprintf(stderr, "mp_radix_size: result for base %d was %d instead of %d\n",
2326+
radix, size, results[radix]);
2327+
goto LTM_ERR;
2328+
}
2329+
a.sign = MP_ZPOS;
2330+
}
2331+
2332+
mp_clear(&a);
2333+
return EXIT_SUCCESS;
2334+
LTM_ERR:
2335+
mp_clear(&a);
2336+
return EXIT_FAILURE;
2337+
}
2338+
2339+
2340+
22852341
static int test_mp_read_write_ubin(void)
22862342
{
22872343
mp_int a, b, c;
@@ -2446,6 +2502,7 @@ static int unit_tests(int argc, char **argv)
24462502
T1(mp_read_write_sbin, MP_TO_SBIN),
24472503
T1(mp_reduce_2k, MP_REDUCE_2K),
24482504
T1(mp_reduce_2k_l, MP_REDUCE_2K_L),
2505+
T1(mp_radix_size, MP_RADIX_SIZE),
24492506
#if defined(__STDC_IEC_559__) || defined(__GCC_IEC_559)
24502507
T1(mp_set_double, MP_SET_DOUBLE),
24512508
#endif

tommath_class.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -750,10 +750,7 @@
750750
#endif
751751

752752
#if defined(BN_MP_RADIX_SIZE_C)
753-
# define BN_MP_CLEAR_C
754-
# define BN_MP_COUNT_BITS_C
755-
# define BN_MP_DIV_D_C
756-
# define BN_MP_INIT_COPY_C
753+
# define BN_MP_LOG_U32_C
757754
#endif
758755

759756
#if defined(BN_MP_RADIX_SMAP_C)

tommath_superclass.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
# define BN_MP_NEG_C
2929
# define BN_MP_PRIME_FROBENIUS_UNDERWOOD_C
3030
# define BN_MP_RADIX_SIZE_C
31+
# define BN_MP_LOG_U32_C
3132
# define BN_MP_RAND_C
3233
# define BN_MP_REDUCE_C
3334
# define BN_MP_REDUCE_2K_L_C

0 commit comments

Comments
 (0)