diff options
Diffstat (limited to 'third_party/heimdal/lib/hcrypto/libtommath/bn_mp_read_radix.c')
-rw-r--r-- | third_party/heimdal/lib/hcrypto/libtommath/bn_mp_read_radix.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/third_party/heimdal/lib/hcrypto/libtommath/bn_mp_read_radix.c b/third_party/heimdal/lib/hcrypto/libtommath/bn_mp_read_radix.c new file mode 100644 index 00000000000..de18e06fc33 --- /dev/null +++ b/third_party/heimdal/lib/hcrypto/libtommath/bn_mp_read_radix.c @@ -0,0 +1,79 @@ +#include "tommath_private.h" +#ifdef BN_MP_READ_RADIX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#define MP_TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (((c) + 'A') - 'a') : (c)) + +/* read a string [ASCII] in a given radix */ +mp_err mp_read_radix(mp_int *a, const char *str, int radix) +{ + mp_err err; + int y; + mp_sign neg; + unsigned pos; + char ch; + + /* zero the digit bignum */ + mp_zero(a); + + /* make sure the radix is ok */ + if ((radix < 2) || (radix > 64)) { + return MP_VAL; + } + + /* if the leading digit is a + * minus set the sign to negative. + */ + if (*str == '-') { + ++str; + neg = MP_NEG; + } else { + neg = MP_ZPOS; + } + + /* set the integer to the default of zero */ + mp_zero(a); + + /* process each digit of the string */ + while (*str != '\0') { + /* if the radix <= 36 the conversion is case insensitive + * this allows numbers like 1AB and 1ab to represent the same value + * [e.g. in hex] + */ + ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str; + pos = (unsigned)(ch - '('); + if (mp_s_rmap_reverse_sz < pos) { + break; + } + y = (int)mp_s_rmap_reverse[pos]; + + /* if the char was found in the map + * and is less than the given radix add it + * to the number, otherwise exit the loop. + */ + if ((y == 0xff) || (y >= radix)) { + break; + } + if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { + return err; + } + if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { + return err; + } + ++str; + } + + /* if an illegal character was found, fail. */ + if (!((*str == '\0') || (*str == '\r') || (*str == '\n'))) { + mp_zero(a); + return MP_VAL; + } + + /* set the sign only if a != 0 */ + if (!MP_IS_ZERO(a)) { + a->sign = neg; + } + return MP_OKAY; +} +#endif |