Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions bn_deprecated.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
53 changes: 33 additions & 20 deletions bn_mp_export.c → bn_mp_pack.c
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;

Expand All @@ -68,4 +80,5 @@ mp_err mp_export(void *rop, size_t *countp, int order, size_t size,
return err;
}


#endif
13 changes: 13 additions & 0 deletions bn_mp_pack_count.c
Original file line number Diff line number Diff line change
@@ -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
22 changes: 9 additions & 13 deletions bn_mp_import.c → bn_mp_unpack.c
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
#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;
unsigned char odd_nail_mask;

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);
Expand All @@ -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;
Expand All @@ -52,4 +47,5 @@ mp_err mp_import(mp_int *rop, size_t count, int order, size_t size,
return MP_OKAY;
}


#endif
48 changes: 48 additions & 0 deletions demo/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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),
Expand Down
34 changes: 30 additions & 4 deletions doc/bn.tex
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
20 changes: 12 additions & 8 deletions libtommath_VS2008.vcproj
Original file line number Diff line number Diff line change
Expand Up @@ -428,10 +428,6 @@
RelativePath="bn_mp_exch.c"
>
</File>
<File
RelativePath="bn_mp_export.c"
>
</File>
<File
RelativePath="bn_mp_expt_u32.c"
>
Expand Down Expand Up @@ -508,10 +504,6 @@
RelativePath="bn_mp_ilogb.c"
>
</File>
<File
RelativePath="bn_mp_import.c"
>
</File>
<File
RelativePath="bn_mp_incr.c"
>
Expand Down Expand Up @@ -648,6 +640,14 @@
RelativePath="bn_mp_or.c"
>
</File>
<File
RelativePath="bn_mp_pack.c"
>
</File>
<File
RelativePath="bn_mp_pack_count.c"
>
</File>
<File
RelativePath="bn_mp_prime_fermat.c"
>
Expand Down Expand Up @@ -832,6 +832,10 @@
RelativePath="bn_mp_ubin_size.c"
>
</File>
<File
RelativePath="bn_mp_unpack.c"
>
</File>
<File
RelativePath="bn_mp_xor.c"
>
Expand Down
47 changes: 24 additions & 23 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading