diff --git a/bn_mp_fread.c b/bn_mp_fread.c index d0de595..85e5ee3 100644 --- a/bn_mp_fread.c +++ b/bn_mp_fread.c @@ -20,6 +20,7 @@ int mp_fread(mp_int *a, int radix, FILE *stream) { int err, ch, neg, y; + unsigned pos; /* clear a */ mp_zero(a); @@ -34,13 +35,14 @@ int mp_fread(mp_int *a, int radix, FILE *stream) } for (;;) { - /* find y in the radix map */ - for (y = 0; y < radix; y++) { - if (mp_s_rmap[y] == ch) { - break; - } + pos = ch - '('; + if (mp_s_rmap_reverse_sz < pos) { + break; } - if (y == radix) { + + y = mp_s_rmap_reverse[pos]; + + if (y == 0xff || y >= radix) { break; } diff --git a/bn_mp_radix_smap.c b/bn_mp_radix_smap.c index 4c6e57c..262775c 100644 --- a/bn_mp_radix_smap.c +++ b/bn_mp_radix_smap.c @@ -17,6 +17,20 @@ /* chars used in radix conversions */ const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; +const uint8_t mp_s_rmap_reverse[] = { + 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, /* ()*+,-./ */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */ + 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */ + 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, /* @ABCDEFG */ + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, /* HIJKLMNO */ + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, /* PQRSTUVW */ + 0x21, 0x22, 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */ + 0xff, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, /* `abcdefg */ + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, /* hijklmno */ + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, /* pqrstuvw */ + 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, /* xyz{|}~. */ +}; +const size_t mp_s_rmap_reverse_sz = sizeof(mp_s_rmap_reverse); #endif /* ref: $Format:%D$ */ diff --git a/bn_mp_read_radix.c b/bn_mp_read_radix.c index bc31cc5..c82f85d 100644 --- a/bn_mp_read_radix.c +++ b/bn_mp_read_radix.c @@ -19,6 +19,7 @@ int mp_read_radix(mp_int *a, const char *str, int radix) { int y, res, neg; + unsigned pos; char ch; /* zero the digit bignum */ @@ -49,26 +50,25 @@ int mp_read_radix(mp_int *a, const char *str, int radix) * [e.g. in hex] */ ch = (radix <= 36) ? (char)toupper((int)*str) : *str; - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } + pos = ch - '('; + if (mp_s_rmap_reverse_sz < pos) { + break; } + y = 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 < radix) { - if ((res = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { - return res; - } - } else { + if (y == 0xff || y >= radix) { break; } + if ((res = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { + return res; + } + if ((res = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { + return res; + } ++str; } diff --git a/tommath_private.h b/tommath_private.h index 087ddcd..7e47f18 100644 --- a/tommath_private.h +++ b/tommath_private.h @@ -76,6 +76,8 @@ int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, i void bn_reverse(unsigned char *s, int len); extern const char *mp_s_rmap; +extern const uint8_t mp_s_rmap_reverse[]; +extern const size_t mp_s_rmap_reverse_sz; /* Fancy macro to set an MPI from another type. * There are several things assumed: