diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-10-17 09:41:54 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2019-10-17 09:41:54 (GMT) |
commit | 6dd152f0407fefebbdd94e2aa2e3c9fd7e23ad6e (patch) | |
tree | 2faf9fc59ff89c42f2cfb67ce66c213c4bf48d68 /libtommath/bn_mp_unpack.c | |
parent | 16a6b9c3c11a42703b6a95fdd027633b5e1cd1fa (diff) | |
download | tcl-6dd152f0407fefebbdd94e2aa2e3c9fd7e23ad6e.zip tcl-6dd152f0407fefebbdd94e2aa2e3c9fd7e23ad6e.tar.gz tcl-6dd152f0407fefebbdd94e2aa2e3c9fd7e23ad6e.tar.bz2 |
Update libtommath to v1.2.0-rc1
Diffstat (limited to 'libtommath/bn_mp_unpack.c')
-rw-r--r-- | libtommath/bn_mp_unpack.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/libtommath/bn_mp_unpack.c b/libtommath/bn_mp_unpack.c new file mode 100644 index 0000000..d4eb90e --- /dev/null +++ b/libtommath/bn_mp_unpack.c @@ -0,0 +1,49 @@ +#include "tommath_private.h" +#ifdef BN_MP_UNPACK_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +/* based on gmp's mpz_import. + * see http://gmplib.org/manual/Integer-Import-and-Export.html + */ +mp_err mp_unpack(mp_int *rop, size_t count, mp_order order, size_t size, + mp_endian endian, size_t nails, const void *op) +{ + mp_err err; + size_t odd_nails, nail_bytes, i, j; + unsigned char odd_nail_mask; + + mp_zero(rop); + + if (endian == MP_NATIVE_ENDIAN) { + MP_GET_ENDIANNESS(endian); + } + + odd_nails = (nails % 8u); + odd_nail_mask = 0xff; + for (i = 0; i < odd_nails; ++i) { + odd_nail_mask ^= (unsigned char)(1u << (7u - i)); + } + nail_bytes = nails / 8u; + + for (i = 0; i < count; ++i) { + for (j = 0; j < (size - nail_bytes); ++j) { + unsigned char byte = *((const unsigned char *)op + + (((order == MP_MSB_FIRST) ? i : ((count - 1u) - i)) * size) + + ((endian == MP_BIG_ENDIAN) ? (j + nail_bytes) : (((size - 1u) - j) - nail_bytes))); + + if ((err = mp_mul_2d(rop, (j == 0u) ? (int)(8u - odd_nails) : 8, rop)) != MP_OKAY) { + return err; + } + + rop->dp[0] |= (j == 0u) ? (mp_digit)(byte & odd_nail_mask) : (mp_digit)byte; + rop->used += 1; + } + } + + mp_clamp(rop); + + return MP_OKAY; +} + +#endif |