diff --git a/bn_deprecated.c b/bn_deprecated.c
index 19b0e49fa..419ff86cc 100644
--- a/bn_deprecated.c
+++ b/bn_deprecated.c
@@ -313,4 +313,18 @@ mp_err mp_toradix(const mp_int *a, char *str, int radix)
return mp_to_radix(a, str, SIZE_MAX, radix);
}
#endif
+#ifdef BN_MP_IMPORT_C
+mp_err mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails,
+ const void *op)
+{
+ return mp_unpack(rop, count, order, size, endian, nails, op);
+}
+#endif
+#ifdef BN_MP_EXPORT_C
+mp_err mp_export(void *rop, size_t *countp, int order, size_t size,
+ int endian, size_t nails, const mp_int *op)
+{
+ return mp_pack(rop, countp, order, size, endian, nails, op, SIZE_MAX);
+}
+#endif
#endif
diff --git a/bn_mp_export.c b/bn_mp_pack.c
similarity index 53%
rename from bn_mp_export.c
rename to bn_mp_pack.c
index 9dea54eb1..4464847cc 100644
--- a/bn_mp_export.c
+++ b/bn_mp_pack.c
@@ -1,49 +1,60 @@
#include "tommath_private.h"
-#ifdef BN_MP_EXPORT_C
+#ifdef BN_MP_PACK_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
+
+
/* based on gmp's mpz_export.
* see http://gmplib.org/manual/Integer-Import-and-Export.html
*/
-mp_err mp_export(void *rop, size_t *countp, int order, size_t size,
- int endian, size_t nails, const mp_int *op)
+mp_err mp_pack(void *rop, size_t *countp, mp_order order, size_t size,
+ mp_endian endian, size_t nails, const mp_int *op,
+ size_t maxsize)
{
mp_err err;
- size_t odd_nails, nail_bytes, i, j, bits, count;
+ size_t odd_nails, nail_bytes, i, j, count, written;
unsigned char odd_nail_mask;
mp_int t;
+ if (rop == NULL) {
+ return MP_MEM;
+ }
+
+ if (maxsize == 0u) {
+ return MP_VAL;
+ }
+
if ((err = mp_init_copy(&t, op)) != MP_OKAY) {
return err;
}
- if (endian == 0) {
- union {
- unsigned int i;
- char c[4];
- } lint;
- lint.i = 0x01020304;
-
- endian = (lint.c[0] == '\x04') ? -1 : 1;
+ if (endian == MP_NATIVE_ENDIAN) {
+ MP_GET_ENDIANNESS(endian);
}
odd_nails = (nails % 8u);
odd_nail_mask = 0xff;
- for (i = 0; i < odd_nails; ++i) {
+ for (i = 0u; i < odd_nails; ++i) {
odd_nail_mask ^= (unsigned char)(1u << (7u - i));
}
nail_bytes = nails / 8u;
- bits = (size_t)mp_count_bits(&t);
- count = (bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u);
+ count = mp_pack_count(&t, nails, size);
- for (i = 0; i < count; ++i) {
- for (j = 0; j < size; ++j) {
+ written = 0u;
+ for (i = 0u; i < count; ++i) {
+ for (j = 0u; j < size; ++j) {
unsigned char *byte = (unsigned char *)rop +
- (((order == -1) ? i : ((count - 1u) - i)) * size) +
- ((endian == -1) ? j : ((size - 1u) - j));
+ (((order == MP_LSB_FIRST) ? i : ((count - 1u) - i)) * size) +
+ ((endian == MP_LITTLE_ENDIAN) ? j : ((size - 1u) - j));
+ if (maxsize == 0u) {
+ err = MP_VAL;
+ break;
+ }
+ maxsize--;
+ written++;
if (j >= (size - nail_bytes)) {
*byte = 0;
@@ -55,11 +66,12 @@ mp_err mp_export(void *rop, size_t *countp, int order, size_t size,
if ((err = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) {
goto LBL_ERR;
}
+
}
}
if (countp != NULL) {
- *countp = count;
+ *countp = written;
}
err = MP_OKAY;
@@ -68,4 +80,5 @@ mp_err mp_export(void *rop, size_t *countp, int order, size_t size,
return err;
}
+
#endif
diff --git a/bn_mp_pack_count.c b/bn_mp_pack_count.c
new file mode 100644
index 000000000..7f8fc6413
--- /dev/null
+++ b/bn_mp_pack_count.c
@@ -0,0 +1,13 @@
+#include "tommath_private.h"
+#ifdef BN_MP_PACK_COUNT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+
+size_t mp_pack_count(mp_int *a, size_t nails, size_t size)
+{
+ size_t bits = (size_t)mp_count_bits(a);
+ return ((bits / ((size * 8u) - nails)) + (((bits % ((size * 8u) - nails)) != 0u) ? 1u : 0u));
+}
+
+#endif
diff --git a/bn_mp_import.c b/bn_mp_unpack.c
similarity index 65%
rename from bn_mp_import.c
rename to bn_mp_unpack.c
index bd83b96c1..de88f1848 100644
--- a/bn_mp_import.c
+++ b/bn_mp_unpack.c
@@ -1,13 +1,14 @@
#include "tommath_private.h"
-#ifdef BN_MP_IMPORT_C
+#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_import(mp_int *rop, size_t count, int order, size_t size,
- int endian, size_t nails, const void *op)
+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;
@@ -15,14 +16,8 @@ mp_err mp_import(mp_int *rop, size_t count, int order, size_t size,
mp_zero(rop);
- if (endian == 0) {
- union {
- unsigned int i;
- char c[4];
- } lint;
- lint.i = 0x01020304;
-
- endian = (lint.c[0] == '\x04') ? -1 : 1;
+ if (endian == MP_NATIVE_ENDIAN) {
+ MP_GET_ENDIANNESS(endian);
}
odd_nails = (nails % 8u);
@@ -35,8 +30,8 @@ mp_err mp_import(mp_int *rop, size_t count, int order, size_t size,
for (i = 0; i < count; ++i) {
for (j = 0; j < (size - nail_bytes); ++j) {
unsigned char byte = *((const unsigned char *)op +
- (((order == 1) ? i : ((count - 1u) - i)) * size) +
- ((endian == 1) ? (j + nail_bytes) : (((size - 1u) - j) - nail_bytes)));
+ (((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;
@@ -52,4 +47,5 @@ mp_err mp_import(mp_int *rop, size_t count, int order, size_t size,
return MP_OKAY;
}
+
#endif
diff --git a/demo/test.c b/demo/test.c
index 7d4f0658b..701ca4cac 100644
--- a/demo/test.c
+++ b/demo/test.c
@@ -2345,6 +2345,53 @@ static int test_mp_read_write_sbin(void)
return EXIT_FAILURE;
}
+static int test_mp_pack_unpack(void)
+{
+ mp_int a, b;
+ int err;
+ size_t countp, size, bits, bytes;
+ unsigned char *buf = NULL;
+
+ mp_order order = MP_LSB_FIRST;
+ mp_endian endianess = MP_NATIVE_ENDIAN;
+
+ if ((err = mp_init_multi(&a, &b, NULL)) != MP_OKAY) goto LTM_ERR;
+ if ((err = mp_rand(&a, 15)) != MP_OKAY) goto LTM_ERR;
+
+ bits = (size_t)mp_count_bits(&a);
+ bytes = (size_t)(((bits + 1u) + (size_t)(CHAR_BIT - 1)) / (size_t)CHAR_BIT);
+ size = bytes * mp_pack_count(&a, 0, 1);
+
+ buf = MP_MALLOC(size);
+ if (buf == NULL) {
+ fprintf(stderr, "test_pack_unpack failed to allocate %zu bytes\n",
+ sizeof(*buf) * size);
+ goto LTM_ERR;
+ }
+
+ if ((err = mp_pack((void *)buf, &countp, order, 1,
+ endianess, 0, &a, size)) != MP_OKAY) goto LTM_ERR;
+ printf("size = %zu, countp = %zu, countp * byte_size = %zu\n",
+ size, countp, countp * bits);
+ if ((err = mp_unpack(&b, countp, order, 1,
+ endianess, 0, (const void *)buf)) != MP_OKAY) goto LTM_ERR;
+
+ if (mp_cmp(&a, &b) != MP_EQ) {
+ fprintf(stderr, "pack/unpack cycle failed\n");
+ goto LTM_ERR;
+ }
+
+ MP_FREE(buf, size);
+ mp_clear_multi(&a, &b, NULL);
+ return EXIT_SUCCESS;
+LTM_ERR:
+ if (buf != NULL) {
+ MP_FREE(buf, size);
+ }
+ mp_clear_multi(&a, &b, NULL);
+ return EXIT_FAILURE;
+}
+
static int unit_tests(int argc, char **argv)
{
static const struct {
@@ -2364,6 +2411,7 @@ static int unit_tests(int argc, char **argv)
T1(mp_decr, MP_DECR),
T1(mp_div_3, MP_DIV_3),
T1(mp_dr_reduce, MP_DR_REDUCE),
+ T2(mp_pack_unpack,MP_PACK, MP_UNPACK),
T2(mp_fread_fwrite, MP_FREAD, MP_FWRITE),
T1(mp_get_u32, MP_GET_I32),
T1(mp_get_u64, MP_GET_I64),
diff --git a/doc/bn.tex b/doc/bn.tex
index 850e1ce3a..50fd67ab7 100644
--- a/doc/bn.tex
+++ b/doc/bn.tex
@@ -2176,12 +2176,38 @@ \section{Binary Conversions}
byte depending on the sign. If the sign is zpos (e.g. not negative) the prefix is zero, otherwise the prefix
is non--zero.
-The two functions \texttt{mp\_import} and \texttt{mp\_export} implement the corresponding GMP functions as described at \url{http://gmplib.org/manual/Integer-Import-and-Export.html}.
-\index{mp\_import} \index{mp\_export}
+The two functions \texttt{mp\_unpack} (get your gifts out of the box, import binary data) and \texttt{mp\_pack} (put your gifts into the box, export binary data) implement the similarly working GMP functions as described at \url{http://gmplib.org/manual/Integer-Import-and-Export.html} with the exception that \texttt{mp\_pack} will not allocate memory if \texttt{rop} is \texttt{NULL}.
+\index{mp\_unpack} \index{mp\_pack}
\begin{alltt}
-int mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails, const void *op);
-int mp_export(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, const mp_int *op);
+int mp_unpack(mp_int *rop, size_t count, mp_order order, size_t size,
+ mp_endian endian, size_t nails, const void *op, size_t maxsize);
+int mp_pack(void *rop, size_t *countp, mp_order order, size_t size,
+ mp_endian endian, size_t nails, const mp_int *op);
\end{alltt}
+The function \texttt{mp\_pack} has the additional variable \texttt{maxsize} which must hold the size of the buffer \texttt{rop} in bytes. Use
+\begin{alltt}
+/* Parameters "nails" and "size" are the same as in mp_pack */
+size_t mp_pack_size(mp_int *a, size_t nails, size_t size);
+\end{alltt}
+To get the size in bytes necessary to be put in \texttt{maxsize}).
+
+To enhance the readability of your code, the following enums have been wrought for your convenience.
+\begin{alltt}
+#ifdef MP_USE_ENUMS
+typedef enum {
+ MP_LSB_FIRST = -1,
+ MP_MSB_FIRST = 1
+} mp_order;
+typedef enum {
+ MP_LITTLE_ENDIAN = -1,
+ MP_NATIVE_ENDIAN = 0,
+ MP_BIG_ENDIAN = 1
+} mp_endian;
+\end{alltt}
+Also available as preprocessor macros.
+
+
+
\chapter{Algebraic Functions}
\section{Extended Euclidean Algorithm}
diff --git a/libtommath_VS2008.vcproj b/libtommath_VS2008.vcproj
index 6a1a294fb..960d75635 100644
--- a/libtommath_VS2008.vcproj
+++ b/libtommath_VS2008.vcproj
@@ -428,10 +428,6 @@
RelativePath="bn_mp_exch.c"
>
-
-
@@ -508,10 +504,6 @@
RelativePath="bn_mp_ilogb.c"
>
-
-
@@ -648,6 +640,14 @@
RelativePath="bn_mp_or.c"
>
+
+
+
+
@@ -832,6 +832,10 @@
RelativePath="bn_mp_ubin_size.c"
>
+
+
diff --git a/makefile b/makefile
index a68d22c51..eecc85274 100644
--- a/makefile
+++ b/makefile
@@ -30,30 +30,31 @@ OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp
bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \
bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \
bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
-bn_mp_error_to_string.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o \
-bn_mp_fread.o bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o \
-bn_mp_get_i32.o bn_mp_get_i64.o bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o \
-bn_mp_get_mag_ul.o bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_import.o bn_mp_incr.o bn_mp_init.o \
-bn_mp_init_copy.o bn_mp_init_i32.o bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o \
-bn_mp_init_set.o bn_mp_init_size.o bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o \
-bn_mp_invmod.o bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o \
-bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
+bn_mp_error_to_string.o bn_mp_exch.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o bn_mp_fread.o \
+bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o bn_mp_get_i32.o \
+bn_mp_get_i64.o bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o bn_mp_get_mag_ul.o \
+bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_incr.o bn_mp_init.o bn_mp_init_copy.o \
+bn_mp_init_i32.o bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o bn_mp_init_set.o \
+bn_mp_init_size.o bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o bn_mp_invmod.o \
+bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o \
+bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \
-bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_prime.o \
-bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \
-bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o bn_mp_radix_size.o bn_mp_radix_smap.o \
-bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o \
-bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o \
-bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o bn_mp_set_double.o \
-bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o \
-bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \
-bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o \
-bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o \
-bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o \
-bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
-bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
-bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \
-bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
+bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \
+bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \
+bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \
+bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \
+bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \
+bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \
+bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o \
+bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o \
+bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o \
+bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o \
+bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o \
+bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o \
+bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o \
+bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o bn_s_mp_prime_is_divisible.o \
+bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \
+bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
#END_INS
diff --git a/makefile.mingw b/makefile.mingw
index 2d334d076..08db73ef6 100644
--- a/makefile.mingw
+++ b/makefile.mingw
@@ -33,30 +33,31 @@ OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp
bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \
bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \
bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
-bn_mp_error_to_string.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o \
-bn_mp_fread.o bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o \
-bn_mp_get_i32.o bn_mp_get_i64.o bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o \
-bn_mp_get_mag_ul.o bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_import.o bn_mp_incr.o bn_mp_init.o \
-bn_mp_init_copy.o bn_mp_init_i32.o bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o \
-bn_mp_init_set.o bn_mp_init_size.o bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o \
-bn_mp_invmod.o bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o \
-bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
+bn_mp_error_to_string.o bn_mp_exch.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o bn_mp_fread.o \
+bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o bn_mp_get_i32.o \
+bn_mp_get_i64.o bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o bn_mp_get_mag_ul.o \
+bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_incr.o bn_mp_init.o bn_mp_init_copy.o \
+bn_mp_init_i32.o bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o bn_mp_init_set.o \
+bn_mp_init_size.o bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o bn_mp_invmod.o \
+bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o \
+bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \
-bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_prime.o \
-bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \
-bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o bn_mp_radix_size.o bn_mp_radix_smap.o \
-bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o \
-bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o \
-bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o bn_mp_set_double.o \
-bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o \
-bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \
-bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o \
-bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o \
-bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o \
-bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
-bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
-bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \
-bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
+bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \
+bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \
+bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \
+bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \
+bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \
+bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \
+bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o \
+bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o \
+bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o \
+bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o \
+bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o \
+bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o \
+bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o \
+bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o bn_s_mp_prime_is_divisible.o \
+bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \
+bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
HEADERS_PUB=tommath.h
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)
diff --git a/makefile.msvc b/makefile.msvc
index 8419b5386..577235f5d 100644
--- a/makefile.msvc
+++ b/makefile.msvc
@@ -25,30 +25,31 @@ OBJECTS=bn_cutoffs.obj bn_deprecated.obj bn_mp_2expt.obj bn_mp_abs.obj bn_mp_add
bn_mp_and.obj bn_mp_clamp.obj bn_mp_clear.obj bn_mp_clear_multi.obj bn_mp_cmp.obj bn_mp_cmp_d.obj bn_mp_cmp_mag.obj \
bn_mp_cnt_lsb.obj bn_mp_complement.obj bn_mp_copy.obj bn_mp_count_bits.obj bn_mp_decr.obj bn_mp_div.obj bn_mp_div_2.obj \
bn_mp_div_2d.obj bn_mp_div_3.obj bn_mp_div_d.obj bn_mp_dr_is_modulus.obj bn_mp_dr_reduce.obj bn_mp_dr_setup.obj \
-bn_mp_error_to_string.obj bn_mp_exch.obj bn_mp_export.obj bn_mp_expt_u32.obj bn_mp_exptmod.obj bn_mp_exteuclid.obj \
-bn_mp_fread.obj bn_mp_from_sbin.obj bn_mp_from_ubin.obj bn_mp_fwrite.obj bn_mp_gcd.obj bn_mp_get_double.obj \
-bn_mp_get_i32.obj bn_mp_get_i64.obj bn_mp_get_l.obj bn_mp_get_ll.obj bn_mp_get_mag_u32.obj bn_mp_get_mag_u64.obj \
-bn_mp_get_mag_ul.obj bn_mp_get_mag_ull.obj bn_mp_grow.obj bn_mp_ilogb.obj bn_mp_import.obj bn_mp_incr.obj bn_mp_init.obj \
-bn_mp_init_copy.obj bn_mp_init_i32.obj bn_mp_init_i64.obj bn_mp_init_l.obj bn_mp_init_ll.obj bn_mp_init_multi.obj \
-bn_mp_init_set.obj bn_mp_init_size.obj bn_mp_init_u32.obj bn_mp_init_u64.obj bn_mp_init_ul.obj bn_mp_init_ull.obj \
-bn_mp_invmod.obj bn_mp_is_square.obj bn_mp_iseven.obj bn_mp_isodd.obj bn_mp_kronecker.obj bn_mp_lcm.obj bn_mp_lshd.obj \
-bn_mp_mod.obj bn_mp_mod_2d.obj bn_mp_mod_d.obj bn_mp_montgomery_calc_normalization.obj bn_mp_montgomery_reduce.obj \
+bn_mp_error_to_string.obj bn_mp_exch.obj bn_mp_expt_u32.obj bn_mp_exptmod.obj bn_mp_exteuclid.obj bn_mp_fread.obj \
+bn_mp_from_sbin.obj bn_mp_from_ubin.obj bn_mp_fwrite.obj bn_mp_gcd.obj bn_mp_get_double.obj bn_mp_get_i32.obj \
+bn_mp_get_i64.obj bn_mp_get_l.obj bn_mp_get_ll.obj bn_mp_get_mag_u32.obj bn_mp_get_mag_u64.obj bn_mp_get_mag_ul.obj \
+bn_mp_get_mag_ull.obj bn_mp_grow.obj bn_mp_ilogb.obj bn_mp_incr.obj bn_mp_init.obj bn_mp_init_copy.obj \
+bn_mp_init_i32.obj bn_mp_init_i64.obj bn_mp_init_l.obj bn_mp_init_ll.obj bn_mp_init_multi.obj bn_mp_init_set.obj \
+bn_mp_init_size.obj bn_mp_init_u32.obj bn_mp_init_u64.obj bn_mp_init_ul.obj bn_mp_init_ull.obj bn_mp_invmod.obj \
+bn_mp_is_square.obj bn_mp_iseven.obj bn_mp_isodd.obj bn_mp_kronecker.obj bn_mp_lcm.obj bn_mp_lshd.obj bn_mp_mod.obj \
+bn_mp_mod_2d.obj bn_mp_mod_d.obj bn_mp_montgomery_calc_normalization.obj bn_mp_montgomery_reduce.obj \
bn_mp_montgomery_setup.obj bn_mp_mul.obj bn_mp_mul_2.obj bn_mp_mul_2d.obj bn_mp_mul_d.obj bn_mp_mulmod.obj bn_mp_neg.obj \
-bn_mp_or.obj bn_mp_prime_fermat.obj bn_mp_prime_frobenius_underwood.obj bn_mp_prime_is_prime.obj \
-bn_mp_prime_miller_rabin.obj bn_mp_prime_next_prime.obj bn_mp_prime_rabin_miller_trials.obj \
-bn_mp_prime_rand.obj bn_mp_prime_strong_lucas_selfridge.obj bn_mp_radix_size.obj bn_mp_radix_smap.obj \
-bn_mp_rand.obj bn_mp_read_radix.obj bn_mp_reduce.obj bn_mp_reduce_2k.obj bn_mp_reduce_2k_l.obj \
-bn_mp_reduce_2k_setup.obj bn_mp_reduce_2k_setup_l.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_is_2k_l.obj \
-bn_mp_reduce_setup.obj bn_mp_root_u32.obj bn_mp_rshd.obj bn_mp_sbin_size.obj bn_mp_set.obj bn_mp_set_double.obj \
-bn_mp_set_i32.obj bn_mp_set_i64.obj bn_mp_set_l.obj bn_mp_set_ll.obj bn_mp_set_u32.obj bn_mp_set_u64.obj \
-bn_mp_set_ul.obj bn_mp_set_ull.obj bn_mp_shrink.obj bn_mp_signed_rsh.obj bn_mp_sqr.obj bn_mp_sqrmod.obj bn_mp_sqrt.obj \
-bn_mp_sqrtmod_prime.obj bn_mp_sub.obj bn_mp_sub_d.obj bn_mp_submod.obj bn_mp_to_radix.obj bn_mp_to_sbin.obj \
-bn_mp_to_ubin.obj bn_mp_ubin_size.obj bn_mp_xor.obj bn_mp_zero.obj bn_prime_tab.obj bn_s_mp_add.obj \
-bn_s_mp_balance_mul.obj bn_s_mp_exptmod.obj bn_s_mp_exptmod_fast.obj bn_s_mp_get_bit.obj bn_s_mp_invmod_fast.obj \
-bn_s_mp_invmod_slow.obj bn_s_mp_karatsuba_mul.obj bn_s_mp_karatsuba_sqr.obj bn_s_mp_montgomery_reduce_fast.obj \
-bn_s_mp_mul_digs.obj bn_s_mp_mul_digs_fast.obj bn_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs_fast.obj \
-bn_s_mp_prime_is_divisible.obj bn_s_mp_rand_jenkins.obj bn_s_mp_rand_platform.obj bn_s_mp_reverse.obj \
-bn_s_mp_sqr.obj bn_s_mp_sqr_fast.obj bn_s_mp_sub.obj bn_s_mp_toom_mul.obj bn_s_mp_toom_sqr.obj
+bn_mp_or.obj bn_mp_pack.obj bn_mp_pack_count.obj bn_mp_prime_fermat.obj bn_mp_prime_frobenius_underwood.obj \
+bn_mp_prime_is_prime.obj bn_mp_prime_miller_rabin.obj bn_mp_prime_next_prime.obj \
+bn_mp_prime_rabin_miller_trials.obj bn_mp_prime_rand.obj bn_mp_prime_strong_lucas_selfridge.obj \
+bn_mp_radix_size.obj bn_mp_radix_smap.obj bn_mp_rand.obj bn_mp_read_radix.obj bn_mp_reduce.obj bn_mp_reduce_2k.obj \
+bn_mp_reduce_2k_l.obj bn_mp_reduce_2k_setup.obj bn_mp_reduce_2k_setup_l.obj bn_mp_reduce_is_2k.obj \
+bn_mp_reduce_is_2k_l.obj bn_mp_reduce_setup.obj bn_mp_root_u32.obj bn_mp_rshd.obj bn_mp_sbin_size.obj bn_mp_set.obj \
+bn_mp_set_double.obj bn_mp_set_i32.obj bn_mp_set_i64.obj bn_mp_set_l.obj bn_mp_set_ll.obj bn_mp_set_u32.obj \
+bn_mp_set_u64.obj bn_mp_set_ul.obj bn_mp_set_ull.obj bn_mp_shrink.obj bn_mp_signed_rsh.obj bn_mp_sqr.obj \
+bn_mp_sqrmod.obj bn_mp_sqrt.obj bn_mp_sqrtmod_prime.obj bn_mp_sub.obj bn_mp_sub_d.obj bn_mp_submod.obj \
+bn_mp_to_radix.obj bn_mp_to_sbin.obj bn_mp_to_ubin.obj bn_mp_ubin_size.obj bn_mp_unpack.obj bn_mp_xor.obj bn_mp_zero.obj \
+bn_prime_tab.obj bn_s_mp_add.obj bn_s_mp_balance_mul.obj bn_s_mp_exptmod.obj bn_s_mp_exptmod_fast.obj \
+bn_s_mp_get_bit.obj bn_s_mp_invmod_fast.obj bn_s_mp_invmod_slow.obj bn_s_mp_karatsuba_mul.obj \
+bn_s_mp_karatsuba_sqr.obj bn_s_mp_montgomery_reduce_fast.obj bn_s_mp_mul_digs.obj bn_s_mp_mul_digs_fast.obj \
+bn_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs_fast.obj bn_s_mp_prime_is_divisible.obj \
+bn_s_mp_rand_jenkins.obj bn_s_mp_rand_platform.obj bn_s_mp_reverse.obj bn_s_mp_sqr.obj bn_s_mp_sqr_fast.obj \
+bn_s_mp_sub.obj bn_s_mp_toom_mul.obj bn_s_mp_toom_sqr.obj
HEADERS_PUB=tommath.h
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)
diff --git a/makefile.shared b/makefile.shared
index a6dc2bbd1..130212d09 100644
--- a/makefile.shared
+++ b/makefile.shared
@@ -27,30 +27,31 @@ OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp
bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \
bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \
bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
-bn_mp_error_to_string.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o \
-bn_mp_fread.o bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o \
-bn_mp_get_i32.o bn_mp_get_i64.o bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o \
-bn_mp_get_mag_ul.o bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_import.o bn_mp_incr.o bn_mp_init.o \
-bn_mp_init_copy.o bn_mp_init_i32.o bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o \
-bn_mp_init_set.o bn_mp_init_size.o bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o \
-bn_mp_invmod.o bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o \
-bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
+bn_mp_error_to_string.o bn_mp_exch.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o bn_mp_fread.o \
+bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o bn_mp_get_i32.o \
+bn_mp_get_i64.o bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o bn_mp_get_mag_ul.o \
+bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_incr.o bn_mp_init.o bn_mp_init_copy.o \
+bn_mp_init_i32.o bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o bn_mp_init_set.o \
+bn_mp_init_size.o bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o bn_mp_invmod.o \
+bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o \
+bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \
-bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_prime.o \
-bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \
-bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o bn_mp_radix_size.o bn_mp_radix_smap.o \
-bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o \
-bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o \
-bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o bn_mp_set_double.o \
-bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o \
-bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \
-bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o \
-bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o \
-bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o \
-bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
-bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
-bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \
-bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
+bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \
+bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \
+bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \
+bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \
+bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \
+bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \
+bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o \
+bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o \
+bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o \
+bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o \
+bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o \
+bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o \
+bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o \
+bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o bn_s_mp_prime_is_divisible.o \
+bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \
+bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
#END_INS
diff --git a/makefile.unix b/makefile.unix
index be008b076..aa5e920c3 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -34,30 +34,31 @@ OBJECTS=bn_cutoffs.o bn_deprecated.o bn_mp_2expt.o bn_mp_abs.o bn_mp_add.o bn_mp
bn_mp_and.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \
bn_mp_cnt_lsb.o bn_mp_complement.o bn_mp_copy.o bn_mp_count_bits.o bn_mp_decr.o bn_mp_div.o bn_mp_div_2.o \
bn_mp_div_2d.o bn_mp_div_3.o bn_mp_div_d.o bn_mp_dr_is_modulus.o bn_mp_dr_reduce.o bn_mp_dr_setup.o \
-bn_mp_error_to_string.o bn_mp_exch.o bn_mp_export.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o \
-bn_mp_fread.o bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o \
-bn_mp_get_i32.o bn_mp_get_i64.o bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o \
-bn_mp_get_mag_ul.o bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_import.o bn_mp_incr.o bn_mp_init.o \
-bn_mp_init_copy.o bn_mp_init_i32.o bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o \
-bn_mp_init_set.o bn_mp_init_size.o bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o \
-bn_mp_invmod.o bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o \
-bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
+bn_mp_error_to_string.o bn_mp_exch.o bn_mp_expt_u32.o bn_mp_exptmod.o bn_mp_exteuclid.o bn_mp_fread.o \
+bn_mp_from_sbin.o bn_mp_from_ubin.o bn_mp_fwrite.o bn_mp_gcd.o bn_mp_get_double.o bn_mp_get_i32.o \
+bn_mp_get_i64.o bn_mp_get_l.o bn_mp_get_ll.o bn_mp_get_mag_u32.o bn_mp_get_mag_u64.o bn_mp_get_mag_ul.o \
+bn_mp_get_mag_ull.o bn_mp_grow.o bn_mp_ilogb.o bn_mp_incr.o bn_mp_init.o bn_mp_init_copy.o \
+bn_mp_init_i32.o bn_mp_init_i64.o bn_mp_init_l.o bn_mp_init_ll.o bn_mp_init_multi.o bn_mp_init_set.o \
+bn_mp_init_size.o bn_mp_init_u32.o bn_mp_init_u64.o bn_mp_init_ul.o bn_mp_init_ull.o bn_mp_invmod.o \
+bn_mp_is_square.o bn_mp_iseven.o bn_mp_isodd.o bn_mp_kronecker.o bn_mp_lcm.o bn_mp_lshd.o bn_mp_mod.o \
+bn_mp_mod_2d.o bn_mp_mod_d.o bn_mp_montgomery_calc_normalization.o bn_mp_montgomery_reduce.o \
bn_mp_montgomery_setup.o bn_mp_mul.o bn_mp_mul_2.o bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_mulmod.o bn_mp_neg.o \
-bn_mp_or.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o bn_mp_prime_is_prime.o \
-bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o bn_mp_prime_rabin_miller_trials.o \
-bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o bn_mp_radix_size.o bn_mp_radix_smap.o \
-bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o bn_mp_reduce_2k_l.o \
-bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o bn_mp_reduce_is_2k_l.o \
-bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o bn_mp_set_double.o \
-bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o bn_mp_set_u64.o \
-bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o bn_mp_sqrmod.o bn_mp_sqrt.o \
-bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o bn_mp_to_radix.o bn_mp_to_sbin.o \
-bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_xor.o bn_mp_zero.o bn_prime_tab.o bn_s_mp_add.o \
-bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o \
-bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o \
-bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o \
-bn_s_mp_prime_is_divisible.o bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o \
-bn_s_mp_sqr.o bn_s_mp_sqr_fast.o bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
+bn_mp_or.o bn_mp_pack.o bn_mp_pack_count.o bn_mp_prime_fermat.o bn_mp_prime_frobenius_underwood.o \
+bn_mp_prime_is_prime.o bn_mp_prime_miller_rabin.o bn_mp_prime_next_prime.o \
+bn_mp_prime_rabin_miller_trials.o bn_mp_prime_rand.o bn_mp_prime_strong_lucas_selfridge.o \
+bn_mp_radix_size.o bn_mp_radix_smap.o bn_mp_rand.o bn_mp_read_radix.o bn_mp_reduce.o bn_mp_reduce_2k.o \
+bn_mp_reduce_2k_l.o bn_mp_reduce_2k_setup.o bn_mp_reduce_2k_setup_l.o bn_mp_reduce_is_2k.o \
+bn_mp_reduce_is_2k_l.o bn_mp_reduce_setup.o bn_mp_root_u32.o bn_mp_rshd.o bn_mp_sbin_size.o bn_mp_set.o \
+bn_mp_set_double.o bn_mp_set_i32.o bn_mp_set_i64.o bn_mp_set_l.o bn_mp_set_ll.o bn_mp_set_u32.o \
+bn_mp_set_u64.o bn_mp_set_ul.o bn_mp_set_ull.o bn_mp_shrink.o bn_mp_signed_rsh.o bn_mp_sqr.o \
+bn_mp_sqrmod.o bn_mp_sqrt.o bn_mp_sqrtmod_prime.o bn_mp_sub.o bn_mp_sub_d.o bn_mp_submod.o \
+bn_mp_to_radix.o bn_mp_to_sbin.o bn_mp_to_ubin.o bn_mp_ubin_size.o bn_mp_unpack.o bn_mp_xor.o bn_mp_zero.o \
+bn_prime_tab.o bn_s_mp_add.o bn_s_mp_balance_mul.o bn_s_mp_exptmod.o bn_s_mp_exptmod_fast.o \
+bn_s_mp_get_bit.o bn_s_mp_invmod_fast.o bn_s_mp_invmod_slow.o bn_s_mp_karatsuba_mul.o \
+bn_s_mp_karatsuba_sqr.o bn_s_mp_montgomery_reduce_fast.o bn_s_mp_mul_digs.o bn_s_mp_mul_digs_fast.o \
+bn_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs_fast.o bn_s_mp_prime_is_divisible.o \
+bn_s_mp_rand_jenkins.o bn_s_mp_rand_platform.o bn_s_mp_reverse.o bn_s_mp_sqr.o bn_s_mp_sqr_fast.o \
+bn_s_mp_sub.o bn_s_mp_toom_mul.o bn_s_mp_toom_sqr.o
HEADERS_PUB=tommath.h
HEADERS=tommath_private.h tommath_class.h tommath_superclass.h tommath_cutoffs.h $(HEADERS_PUB)
diff --git a/tommath.def b/tommath.def
index 6ad2b89de..b814186e9 100644
--- a/tommath.def
+++ b/tommath.def
@@ -33,7 +33,6 @@ EXPORTS
mp_dr_setup
mp_error_to_string
mp_exch
- mp_export
mp_expt_u32
mp_exptmod
mp_exteuclid
@@ -56,7 +55,6 @@ EXPORTS
mp_get_mag_ull
mp_grow
mp_ilogb
- mp_import
mp_incr
mp_init
mp_init_copy
@@ -92,6 +90,8 @@ EXPORTS
mp_mulmod
mp_neg
mp_or
+ mp_pack
+ mp_pack_count
mp_prime_fermat
mp_prime_frobenius_underwood
mp_prime_is_prime
@@ -140,5 +140,6 @@ EXPORTS
mp_to_sbin
mp_to_ubin
mp_ubin_size
+ mp_unpack
mp_xor
mp_zero
diff --git a/tommath.h b/tommath.h
index 8c67c0efe..2a3770993 100644
--- a/tommath.h
+++ b/tommath.h
@@ -136,6 +136,15 @@ typedef enum {
MP_VAL = -3,
MP_ITER = -4
} mp_err;
+typedef enum {
+ MP_LSB_FIRST = -1,
+ MP_MSB_FIRST = 1
+} mp_order;
+typedef enum {
+ MP_LITTLE_ENDIAN = -1,
+ MP_NATIVE_ENDIAN = 0,
+ MP_BIG_ENDIAN = 1
+} mp_endian;
#else
typedef int mp_sign;
#define MP_ZPOS 0 /* positive integer */
@@ -154,6 +163,13 @@ typedef int mp_err;
#define MP_VAL -3 /* invalid input */
#define MP_RANGE (MP_DEPRECATED_PRAGMA("MP_RANGE has been deprecated in favor of MP_VAL") MP_VAL)
#define MP_ITER -4 /* Max. iterations reached */
+typedef int mp_order;
+#define MP_LSB_FIRST -1
+#define MP_MSB_FIRST 1
+typedef int mp_endian;
+#define MP_LITTLE_ENDIAN -1
+#define MP_NATIVE_ENDIAN 0
+#define MP_BIG_ENDIAN 1
#endif
/* tunable cutoffs */
@@ -352,10 +368,21 @@ mp_err mp_init_copy(mp_int *a, const mp_int *b) MP_WUR;
void mp_clamp(mp_int *a);
/* import binary data */
-mp_err mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails, const void *op) MP_WUR;
+
+MP_DEPRECATED(mp_unpack) mp_err mp_import(mp_int *rop, size_t count, int order,
+ size_t size, int endian, size_t nails,
+ const void *op) MP_WUR;
+
+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_WUR;
/* export binary data */
-mp_err mp_export(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, const mp_int *op) MP_WUR;
+MP_DEPRECATED(mp_pack) mp_err mp_export(void *rop, size_t *countp, int order, size_t size,
+ int endian, size_t nails, const mp_int *op) MP_WUR;
+
+size_t mp_pack_count(mp_int *a, size_t nails, size_t size) MP_WUR;
+mp_err mp_pack(void *rop, size_t *countp, mp_order order, size_t size, mp_endian endian,
+ size_t nails, const mp_int *op, size_t maxsize) MP_WUR;
/* ---> digit manipulation <--- */
diff --git a/tommath_class.h b/tommath_class.h
index a60a757e9..ee30b291a 100644
--- a/tommath_class.h
+++ b/tommath_class.h
@@ -40,7 +40,6 @@
# define BN_MP_DR_SETUP_C
# define BN_MP_ERROR_TO_STRING_C
# define BN_MP_EXCH_C
-# define BN_MP_EXPORT_C
# define BN_MP_EXPT_U32_C
# define BN_MP_EXPTMOD_C
# define BN_MP_EXTEUCLID_C
@@ -60,7 +59,6 @@
# define BN_MP_GET_MAG_ULL_C
# define BN_MP_GROW_C
# define BN_MP_ILOGB_C
-# define BN_MP_IMPORT_C
# define BN_MP_INCR_C
# define BN_MP_INIT_C
# define BN_MP_INIT_COPY_C
@@ -95,6 +93,8 @@
# define BN_MP_MULMOD_C
# define BN_MP_NEG_C
# define BN_MP_OR_C
+# define BN_MP_PACK_C
+# define BN_MP_PACK_COUNT_C
# define BN_MP_PRIME_FERMAT_C
# define BN_MP_PRIME_FROBENIUS_UNDERWOOD_C
# define BN_MP_PRIME_IS_PRIME_C
@@ -141,6 +141,7 @@
# define BN_MP_TO_SBIN_C
# define BN_MP_TO_UBIN_C
# define BN_MP_UBIN_SIZE_C
+# define BN_MP_UNPACK_C
# define BN_MP_XOR_C
# define BN_MP_ZERO_C
# define BN_PRIME_TAB_C
@@ -181,6 +182,7 @@
# define BN_MP_AND_C
# define BN_MP_BALANCE_MUL_C
# define BN_MP_CMP_D_C
+# define BN_MP_EXPORT_C
# define BN_MP_EXPTMOD_FAST_C
# define BN_MP_EXPT_D_C
# define BN_MP_EXPT_D_EX_C
@@ -194,6 +196,7 @@
# define BN_MP_GET_MAG_U32_C
# define BN_MP_GET_MAG_ULL_C
# define BN_MP_GET_MAG_UL_C
+# define BN_MP_IMPORT_C
# define BN_MP_INIT_SET_INT_C
# define BN_MP_INIT_U32_C
# define BN_MP_INVMOD_SLOW_C
@@ -204,6 +207,7 @@
# define BN_MP_N_ROOT_C
# define BN_MP_N_ROOT_EX_C
# define BN_MP_OR_C
+# define BN_MP_PACK_C
# define BN_MP_PRIME_IS_DIVISIBLE_C
# define BN_MP_PRIME_RANDOM_EX_C
# define BN_MP_RAND_DIGIT_C
@@ -232,6 +236,7 @@
# define BN_MP_TO_UNSIGNED_BIN_C
# define BN_MP_TO_UNSIGNED_BIN_N_C
# define BN_MP_UBIN_SIZE_C
+# define BN_MP_UNPACK_C
# define BN_MP_UNSIGNED_BIN_SIZE_C
# define BN_MP_XOR_C
# define BN_S_MP_BALANCE_MUL_C
@@ -398,13 +403,6 @@
#if defined(BN_MP_EXCH_C)
#endif
-#if defined(BN_MP_EXPORT_C)
-# define BN_MP_CLEAR_C
-# define BN_MP_COUNT_BITS_C
-# define BN_MP_DIV_2D_C
-# define BN_MP_INIT_COPY_C
-#endif
-
#if defined(BN_MP_EXPT_U32_C)
# define BN_MP_CLEAR_C
# define BN_MP_INIT_COPY_C
@@ -521,12 +519,6 @@
# define BN_MP_ZERO_C
#endif
-#if defined(BN_MP_IMPORT_C)
-# define BN_MP_CLAMP_C
-# define BN_MP_MUL_2D_C
-# define BN_MP_ZERO_C
-#endif
-
#if defined(BN_MP_INCR_C)
# define BN_MP_ADD_D_C
# define BN_MP_DECR_C
@@ -721,6 +713,17 @@
# define BN_MP_GROW_C
#endif
+#if defined(BN_MP_PACK_C)
+# define BN_MP_CLEAR_C
+# define BN_MP_DIV_2D_C
+# define BN_MP_INIT_COPY_C
+# define BN_MP_PACK_COUNT_C
+#endif
+
+#if defined(BN_MP_PACK_COUNT_C)
+# define BN_MP_COUNT_BITS_C
+#endif
+
#if defined(BN_MP_PRIME_FERMAT_C)
# define BN_MP_CLEAR_C
# define BN_MP_CMP_C
@@ -1084,6 +1087,12 @@
# define BN_MP_COUNT_BITS_C
#endif
+#if defined(BN_MP_UNPACK_C)
+# define BN_MP_CLAMP_C
+# define BN_MP_MUL_2D_C
+# define BN_MP_ZERO_C
+#endif
+
#if defined(BN_MP_XOR_C)
# define BN_MP_CLAMP_C
# define BN_MP_GROW_C
diff --git a/tommath_private.h b/tommath_private.h
index ff6f7cf52..ff80d76a9 100644
--- a/tommath_private.h
+++ b/tommath_private.h
@@ -236,6 +236,14 @@ MP_DEPRECATED(s_mp_toom_mul) mp_err mp_toom_mul(const mp_int *a, const mp_int *b
MP_DEPRECATED(s_mp_toom_sqr) mp_err mp_toom_sqr(const mp_int *a, mp_int *b);
MP_DEPRECATED(s_mp_reverse) void bn_reverse(unsigned char *s, int len);
+#define MP_GET_ENDIANNESS(x) \
+ do{\
+ int16_t n = 0x1; \
+ char *p = (char *)&n; \
+ x = (p[0] == 1) ? MP_LITTLE_ENDIAN : MP_BIG_ENDIAN; \
+ }while(0)
+
+
/* code-generating macros */
#define MP_SET_UNSIGNED(name, type) \
void name(mp_int * a, type b) \