Line data Source code
1 : #include "tommath_private.h" 2 : #ifdef BN_MP_READ_RADIX_C 3 : /* LibTomMath, multiple-precision integer library -- Tom St Denis */ 4 : /* SPDX-License-Identifier: Unlicense */ 5 : 6 : #define MP_TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (((c) + 'A') - 'a') : (c)) 7 : 8 : /* read a string [ASCII] in a given radix */ 9 0 : mp_err mp_read_radix(mp_int *a, const char *str, int radix) 10 : { 11 0 : mp_err err; 12 0 : int y; 13 0 : mp_sign neg; 14 0 : unsigned pos; 15 0 : char ch; 16 : 17 : /* zero the digit bignum */ 18 0 : mp_zero(a); 19 : 20 : /* make sure the radix is ok */ 21 0 : if ((radix < 2) || (radix > 64)) { 22 0 : return MP_VAL; 23 : } 24 : 25 : /* if the leading digit is a 26 : * minus set the sign to negative. 27 : */ 28 0 : if (*str == '-') { 29 0 : ++str; 30 0 : neg = MP_NEG; 31 : } else { 32 0 : neg = MP_ZPOS; 33 : } 34 : 35 : /* set the integer to the default of zero */ 36 0 : mp_zero(a); 37 : 38 : /* process each digit of the string */ 39 0 : while (*str != '\0') { 40 : /* if the radix <= 36 the conversion is case insensitive 41 : * this allows numbers like 1AB and 1ab to represent the same value 42 : * [e.g. in hex] 43 : */ 44 0 : ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str; 45 0 : pos = (unsigned)(ch - '('); 46 0 : if (mp_s_rmap_reverse_sz < pos) { 47 0 : break; 48 : } 49 0 : y = (int)mp_s_rmap_reverse[pos]; 50 : 51 : /* if the char was found in the map 52 : * and is less than the given radix add it 53 : * to the number, otherwise exit the loop. 54 : */ 55 0 : if ((y == 0xff) || (y >= radix)) { 56 : break; 57 : } 58 0 : if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { 59 0 : return err; 60 : } 61 0 : if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { 62 0 : return err; 63 : } 64 0 : ++str; 65 : } 66 : 67 : /* if an illegal character was found, fail. */ 68 0 : if (!((*str == '\0') || (*str == '\r') || (*str == '\n'))) { 69 0 : mp_zero(a); 70 0 : return MP_VAL; 71 : } 72 : 73 : /* set the sign only if a != 0 */ 74 0 : if (!MP_IS_ZERO(a)) { 75 0 : a->sign = neg; 76 : } 77 0 : return MP_OKAY; 78 : } 79 : #endif