diff --git a/mpint.c b/mpint.c index 4dcb8b83..72ae0ea1 100644 --- a/mpint.c +++ b/mpint.c @@ -257,6 +257,18 @@ unsigned mp_get_bit(mp_int *x, size_t bit) (bit % BIGNUM_INT_BITS)); } +uintmax_t mp_get_integer(mp_int *x) +{ + uintmax_t toret = 0; + for (size_t i = x->nw; i-- > 0 ;) { + /* Shift in two stages to avoid undefined behaviour if the + * shift count equals the integer width */ + toret = (toret << (BIGNUM_INT_BITS/2)) << (BIGNUM_INT_BITS/2); + toret |= x->w[i]; + } + return toret; +} + void mp_set_bit(mp_int *x, size_t bit, unsigned val) { size_t word = bit / BIGNUM_INT_BITS; diff --git a/mpint.h b/mpint.h index e05f1dab..e15312b3 100644 --- a/mpint.h +++ b/mpint.h @@ -100,6 +100,12 @@ mp_int *mp_power_2(size_t power); uint8_t mp_get_byte(mp_int *x, size_t byte); unsigned mp_get_bit(mp_int *x, size_t bit); +/* + * Retrieve the value of an mp_int as a uintmax_t, assuming it's small + * enough to fit. + */ +uintmax_t mp_get_integer(mp_int *x); + /* * Set an mp_int bit. Again, the bit index is not considered secret. * Do not pass an out-of-range index, on pain of assertion failure.