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 */
2211mp_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
9064LBL_ERR :
91- mp_clear (& t );
9265 return err ;
9366}
9467
0 commit comments