diff options
Diffstat (limited to 'src')
172 files changed, 5646 insertions, 4449 deletions
diff --git a/src/Makefile b/src/Makefile index 3841f2c3..f528bd05 100644 --- a/src/Makefile +++ b/src/Makefile @@ -133,41 +133,39 @@ ltc/stream/salsa20/salsa20_crypt.o ltc/stream/salsa20/salsa20_done.o ltc/stream/ ltc/stream/salsa20/salsa20_keystream.o ltc/stream/salsa20/salsa20_memory.o ltc/stream/salsa20/salsa20_setup.o \ ltc/stream/salsa20/xsalsa20_memory.o ltc/stream/salsa20/xsalsa20_setup.o ltc/stream/sober128/sober128_stream.o \ ltc/stream/sober128/sober128_stream_memory.o ltc/stream/sosemanuk/sosemanuk.o ltc/stream/sosemanuk/sosemanuk_memory.o \ -ltm/bn_cutoffs.o ltm/bn_deprecated.o ltm/bn_mp_2expt.o ltm/bn_mp_abs.o ltm/bn_mp_add.o \ -ltm/bn_mp_addmod.o ltm/bn_mp_add_d.o ltm/bn_mp_and.o ltm/bn_mp_clamp.o ltm/bn_mp_clear.o \ -ltm/bn_mp_clear_multi.o ltm/bn_mp_cmp.o ltm/bn_mp_cmp_d.o ltm/bn_mp_cmp_mag.o ltm/bn_mp_cnt_lsb.o \ -ltm/bn_mp_complement.o ltm/bn_mp_copy.o ltm/bn_mp_count_bits.o ltm/bn_mp_decr.o ltm/bn_mp_div.o \ -ltm/bn_mp_div_2.o ltm/bn_mp_div_2d.o ltm/bn_mp_div_3.o ltm/bn_mp_div_d.o ltm/bn_mp_dr_is_modulus.o \ -ltm/bn_mp_dr_reduce.o ltm/bn_mp_dr_setup.o ltm/bn_mp_error_to_string.o ltm/bn_mp_exch.o \ -ltm/bn_mp_export.o ltm/bn_mp_exptmod.o ltm/bn_mp_expt_d.o ltm/bn_mp_exteuclid.o ltm/bn_mp_fread.o \ -ltm/bn_mp_fwrite.o ltm/bn_mp_gcd.o ltm/bn_mp_get_i32.o ltm/bn_mp_get_i64.o ltm/bn_mp_get_mag32.o \ -ltm/bn_mp_get_mag64.o ltm/bn_mp_grow.o ltm/bn_mp_ilogb.o ltm/bn_mp_import.o ltm/bn_mp_incr.o \ -ltm/bn_mp_init.o ltm/bn_mp_init_copy.o ltm/bn_mp_init_i32.o ltm/bn_mp_init_i64.o \ -ltm/bn_mp_init_multi.o ltm/bn_mp_init_set.o ltm/bn_mp_init_size.o ltm/bn_mp_init_u32.o \ -ltm/bn_mp_init_u64.o ltm/bn_mp_invmod.o ltm/bn_mp_iseven.o ltm/bn_mp_isodd.o ltm/bn_mp_is_square.o \ -ltm/bn_mp_kronecker.o ltm/bn_mp_lcm.o ltm/bn_mp_lshd.o ltm/bn_mp_mod.o ltm/bn_mp_mod_2d.o \ -ltm/bn_mp_mod_d.o ltm/bn_mp_montgomery_calc_normalization.o ltm/bn_mp_montgomery_reduce.o \ -ltm/bn_mp_montgomery_setup.o ltm/bn_mp_mul.o ltm/bn_mp_mulmod.o ltm/bn_mp_mul_2.o \ -ltm/bn_mp_mul_2d.o ltm/bn_mp_mul_d.o ltm/bn_mp_neg.o ltm/bn_mp_n_root.o ltm/bn_mp_or.o \ -ltm/bn_mp_prime_fermat.o ltm/bn_mp_prime_frobenius_underwood.o ltm/bn_mp_prime_is_prime.o \ -ltm/bn_mp_prime_miller_rabin.o ltm/bn_mp_prime_next_prime.o ltm/bn_mp_prime_rabin_miller_trials.o \ -ltm/bn_mp_prime_rand.o ltm/bn_mp_prime_strong_lucas_selfridge.o ltm/bn_mp_radix_size.o \ -ltm/bn_mp_radix_smap.o ltm/bn_mp_rand.o ltm/bn_mp_read_radix.o ltm/bn_mp_read_signed_bin.o \ -ltm/bn_mp_read_unsigned_bin.o ltm/bn_mp_reduce.o ltm/bn_mp_reduce_2k.o ltm/bn_mp_reduce_2k_l.o \ -ltm/bn_mp_reduce_2k_setup.o ltm/bn_mp_reduce_2k_setup_l.o ltm/bn_mp_reduce_is_2k.o \ -ltm/bn_mp_reduce_is_2k_l.o ltm/bn_mp_reduce_setup.o ltm/bn_mp_rshd.o ltm/bn_mp_set.o \ -ltm/bn_mp_set_i32.o ltm/bn_mp_set_i64.o ltm/bn_mp_set_u32.o ltm/bn_mp_set_u64.o ltm/bn_mp_shrink.o \ -ltm/bn_mp_signed_bin_size.o ltm/bn_mp_signed_rsh.o ltm/bn_mp_sqr.o ltm/bn_mp_sqrmod.o \ +ltm/bncore.o ltm/bn_error.o ltm/bn_fast_mp_invmod.o ltm/bn_fast_mp_montgomery_reduce.o \ +ltm/bn_fast_s_mp_mul_digs.o ltm/bn_fast_s_mp_mul_high_digs.o ltm/bn_fast_s_mp_sqr.o \ +ltm/bn_mp_2expt.o ltm/bn_mp_abs.o ltm/bn_mp_add.o ltm/bn_mp_addmod.o ltm/bn_mp_add_d.o \ +ltm/bn_mp_and.o ltm/bn_mp_clamp.o ltm/bn_mp_clear.o ltm/bn_mp_clear_multi.o ltm/bn_mp_cmp.o \ +ltm/bn_mp_cmp_d.o ltm/bn_mp_cmp_mag.o ltm/bn_mp_cnt_lsb.o ltm/bn_mp_complement.o \ +ltm/bn_mp_copy.o ltm/bn_mp_count_bits.o ltm/bn_mp_div.o ltm/bn_mp_div_2.o ltm/bn_mp_div_2d.o \ +ltm/bn_mp_div_3.o ltm/bn_mp_div_d.o ltm/bn_mp_dr_is_modulus.o ltm/bn_mp_dr_reduce.o \ +ltm/bn_mp_dr_setup.o ltm/bn_mp_exch.o ltm/bn_mp_export.o ltm/bn_mp_exptmod.o ltm/bn_mp_exptmod_fast.o \ +ltm/bn_mp_expt_d.o ltm/bn_mp_expt_d_ex.o ltm/bn_mp_exteuclid.o ltm/bn_mp_fread.o \ +ltm/bn_mp_fwrite.o ltm/bn_mp_gcd.o ltm/bn_mp_get_bit.o ltm/bn_mp_get_int.o ltm/bn_mp_get_long.o \ +ltm/bn_mp_grow.o ltm/bn_mp_import.o ltm/bn_mp_init.o ltm/bn_mp_init_copy.o ltm/bn_mp_init_multi.o \ +ltm/bn_mp_init_set.o ltm/bn_mp_init_set_int.o ltm/bn_mp_init_size.o ltm/bn_mp_invmod.o \ +ltm/bn_mp_invmod_slow.o ltm/bn_mp_is_square.o ltm/bn_mp_jacobi.o ltm/bn_mp_karatsuba_mul.o \ +ltm/bn_mp_karatsuba_sqr.o ltm/bn_mp_kronecker.o ltm/bn_mp_lcm.o ltm/bn_mp_lshd.o \ +ltm/bn_mp_mod.o ltm/bn_mp_mod_2d.o ltm/bn_mp_mod_d.o ltm/bn_mp_montgomery_calc_normalization.o \ +ltm/bn_mp_montgomery_reduce.o ltm/bn_mp_montgomery_setup.o ltm/bn_mp_mul.o ltm/bn_mp_mulmod.o \ +ltm/bn_mp_mul_2.o ltm/bn_mp_mul_2d.o ltm/bn_mp_mul_d.o ltm/bn_mp_neg.o ltm/bn_mp_n_root.o \ +ltm/bn_mp_n_root_ex.o ltm/bn_mp_or.o ltm/bn_mp_prime_fermat.o ltm/bn_mp_prime_frobenius_underwood.o \ +ltm/bn_mp_prime_is_divisible.o ltm/bn_mp_prime_is_prime.o ltm/bn_mp_prime_miller_rabin.o \ +ltm/bn_mp_prime_next_prime.o ltm/bn_mp_prime_rabin_miller_trials.o ltm/bn_mp_prime_random_ex.o \ +ltm/bn_mp_prime_strong_lucas_selfridge.o ltm/bn_mp_radix_size.o ltm/bn_mp_radix_smap.o \ +ltm/bn_mp_rand.o ltm/bn_mp_read_radix.o ltm/bn_mp_read_signed_bin.o ltm/bn_mp_read_unsigned_bin.o \ +ltm/bn_mp_reduce.o ltm/bn_mp_reduce_2k.o ltm/bn_mp_reduce_2k_l.o ltm/bn_mp_reduce_2k_setup.o \ +ltm/bn_mp_reduce_2k_setup_l.o ltm/bn_mp_reduce_is_2k.o ltm/bn_mp_reduce_is_2k_l.o \ +ltm/bn_mp_reduce_setup.o ltm/bn_mp_rshd.o ltm/bn_mp_set.o ltm/bn_mp_set_int.o ltm/bn_mp_set_long.o \ +ltm/bn_mp_shrink.o ltm/bn_mp_signed_bin_size.o ltm/bn_mp_sqr.o ltm/bn_mp_sqrmod.o \ ltm/bn_mp_sqrt.o ltm/bn_mp_sqrtmod_prime.o ltm/bn_mp_sub.o ltm/bn_mp_submod.o ltm/bn_mp_sub_d.o \ -ltm/bn_mp_toradix.o ltm/bn_mp_toradix_n.o ltm/bn_mp_to_signed_bin.o ltm/bn_mp_to_signed_bin_n.o \ -ltm/bn_mp_to_unsigned_bin.o ltm/bn_mp_to_unsigned_bin_n.o ltm/bn_mp_unsigned_bin_size.o \ -ltm/bn_mp_xor.o ltm/bn_mp_zero.o ltm/bn_prime_tab.o ltm/bn_s_mp_add.o ltm/bn_s_mp_balance_mul.o \ -ltm/bn_s_mp_exptmod.o ltm/bn_s_mp_exptmod_fast.o ltm/bn_s_mp_get_bit.o ltm/bn_s_mp_invmod_fast.o \ -ltm/bn_s_mp_invmod_slow.o ltm/bn_s_mp_karatsuba_mul.o ltm/bn_s_mp_karatsuba_sqr.o \ -ltm/bn_s_mp_montgomery_reduce_fast.o ltm/bn_s_mp_mul_digs.o ltm/bn_s_mp_mul_digs_fast.o \ -ltm/bn_s_mp_mul_high_digs.o ltm/bn_s_mp_mul_high_digs_fast.o ltm/bn_s_mp_prime_is_divisible.o \ -ltm/bn_s_mp_rand_jenkins.o ltm/bn_s_mp_rand_platform.o ltm/bn_s_mp_reverse.o ltm/bn_s_mp_sqr.o \ -ltm/bn_s_mp_sqr_fast.o ltm/bn_s_mp_sub.o ltm/bn_s_mp_toom_mul.o ltm/bn_s_mp_toom_sqr.o +ltm/bn_mp_tc_and.o ltm/bn_mp_tc_div_2d.o ltm/bn_mp_tc_or.o ltm/bn_mp_tc_xor.o ltm/bn_mp_toom_mul.o \ +ltm/bn_mp_toom_sqr.o ltm/bn_mp_toradix.o ltm/bn_mp_toradix_n.o ltm/bn_mp_to_signed_bin.o \ +ltm/bn_mp_to_signed_bin_n.o ltm/bn_mp_to_unsigned_bin.o ltm/bn_mp_to_unsigned_bin_n.o \ +ltm/bn_mp_unsigned_bin_size.o ltm/bn_mp_xor.o ltm/bn_mp_zero.o ltm/bn_prime_tab.o \ +ltm/bn_reverse.o ltm/bn_s_mp_add.o ltm/bn_s_mp_exptmod.o ltm/bn_s_mp_mul_digs.o ltm/bn_s_mp_mul_high_digs.o \ +ltm/bn_s_mp_sqr.o ltm/bn_s_mp_sub.o LIB_EXT =.a OBJ_EXT =.o diff --git a/src/Makefile.nmake b/src/Makefile.nmake index 41f054c0..20d75856 100644 --- a/src/Makefile.nmake +++ b/src/Makefile.nmake @@ -141,45 +141,41 @@ ltc/stream/salsa20/salsa20_crypt.obj ltc/stream/salsa20/salsa20_done.obj ltc/str ltc/stream/salsa20/salsa20_keystream.obj ltc/stream/salsa20/salsa20_memory.obj ltc/stream/salsa20/salsa20_setup.obj \ ltc/stream/salsa20/xsalsa20_memory.obj ltc/stream/salsa20/xsalsa20_setup.obj ltc/stream/sober128/sober128_stream.obj \ ltc/stream/sober128/sober128_stream_memory.obj ltc/stream/sosemanuk/sosemanuk.obj \ -ltc/stream/sosemanuk/sosemanuk_memory.obj ltm/bn_cutoffs.obj ltm/bn_deprecated.obj \ -ltm/bn_mp_2expt.obj ltm/bn_mp_abs.obj ltm/bn_mp_add.obj ltm/bn_mp_addmod.obj ltm/bn_mp_add_d.obj \ -ltm/bn_mp_and.obj ltm/bn_mp_clamp.obj ltm/bn_mp_clear.obj ltm/bn_mp_clear_multi.obj \ -ltm/bn_mp_cmp.obj ltm/bn_mp_cmp_d.obj ltm/bn_mp_cmp_mag.obj ltm/bn_mp_cnt_lsb.obj \ -ltm/bn_mp_complement.obj ltm/bn_mp_copy.obj ltm/bn_mp_count_bits.obj ltm/bn_mp_decr.obj \ +ltc/stream/sosemanuk/sosemanuk_memory.obj ltm/bncore.obj ltm/bn_error.obj ltm/bn_fast_mp_invmod.obj \ +ltm/bn_fast_mp_montgomery_reduce.obj ltm/bn_fast_s_mp_mul_digs.obj ltm/bn_fast_s_mp_mul_high_digs.obj \ +ltm/bn_fast_s_mp_sqr.obj ltm/bn_mp_2expt.obj ltm/bn_mp_abs.obj ltm/bn_mp_add.obj \ +ltm/bn_mp_addmod.obj ltm/bn_mp_add_d.obj ltm/bn_mp_and.obj ltm/bn_mp_clamp.obj ltm/bn_mp_clear.obj \ +ltm/bn_mp_clear_multi.obj ltm/bn_mp_cmp.obj ltm/bn_mp_cmp_d.obj ltm/bn_mp_cmp_mag.obj \ +ltm/bn_mp_cnt_lsb.obj ltm/bn_mp_complement.obj ltm/bn_mp_copy.obj ltm/bn_mp_count_bits.obj \ ltm/bn_mp_div.obj ltm/bn_mp_div_2.obj ltm/bn_mp_div_2d.obj ltm/bn_mp_div_3.obj ltm/bn_mp_div_d.obj \ -ltm/bn_mp_dr_is_modulus.obj ltm/bn_mp_dr_reduce.obj ltm/bn_mp_dr_setup.obj ltm/bn_mp_error_to_string.obj \ -ltm/bn_mp_exch.obj ltm/bn_mp_export.obj ltm/bn_mp_exptmod.obj ltm/bn_mp_expt_d.obj \ -ltm/bn_mp_exteuclid.obj ltm/bn_mp_fread.obj ltm/bn_mp_fwrite.obj ltm/bn_mp_gcd.obj \ -ltm/bn_mp_get_i32.obj ltm/bn_mp_get_i64.obj ltm/bn_mp_get_mag32.obj ltm/bn_mp_get_mag64.obj \ -ltm/bn_mp_grow.obj ltm/bn_mp_ilogb.obj ltm/bn_mp_import.obj ltm/bn_mp_incr.obj ltm/bn_mp_init.obj \ -ltm/bn_mp_init_copy.obj ltm/bn_mp_init_i32.obj ltm/bn_mp_init_i64.obj ltm/bn_mp_init_multi.obj \ -ltm/bn_mp_init_set.obj ltm/bn_mp_init_size.obj ltm/bn_mp_init_u32.obj ltm/bn_mp_init_u64.obj \ -ltm/bn_mp_invmod.obj ltm/bn_mp_iseven.obj ltm/bn_mp_isodd.obj ltm/bn_mp_is_square.obj \ -ltm/bn_mp_kronecker.obj ltm/bn_mp_lcm.obj ltm/bn_mp_lshd.obj ltm/bn_mp_mod.obj ltm/bn_mp_mod_2d.obj \ -ltm/bn_mp_mod_d.obj ltm/bn_mp_montgomery_calc_normalization.obj ltm/bn_mp_montgomery_reduce.obj \ -ltm/bn_mp_montgomery_setup.obj ltm/bn_mp_mul.obj ltm/bn_mp_mulmod.obj ltm/bn_mp_mul_2.obj \ -ltm/bn_mp_mul_2d.obj ltm/bn_mp_mul_d.obj ltm/bn_mp_neg.obj ltm/bn_mp_n_root.obj ltm/bn_mp_or.obj \ -ltm/bn_mp_prime_fermat.obj ltm/bn_mp_prime_frobenius_underwood.obj ltm/bn_mp_prime_is_prime.obj \ +ltm/bn_mp_dr_is_modulus.obj ltm/bn_mp_dr_reduce.obj ltm/bn_mp_dr_setup.obj ltm/bn_mp_exch.obj \ +ltm/bn_mp_export.obj ltm/bn_mp_exptmod.obj ltm/bn_mp_exptmod_fast.obj ltm/bn_mp_expt_d.obj \ +ltm/bn_mp_expt_d_ex.obj ltm/bn_mp_exteuclid.obj ltm/bn_mp_fread.obj ltm/bn_mp_fwrite.obj \ +ltm/bn_mp_gcd.obj ltm/bn_mp_get_bit.obj ltm/bn_mp_get_int.obj ltm/bn_mp_get_long.obj \ +ltm/bn_mp_grow.obj ltm/bn_mp_import.obj ltm/bn_mp_init.obj ltm/bn_mp_init_copy.obj \ +ltm/bn_mp_init_multi.obj ltm/bn_mp_init_set.obj ltm/bn_mp_init_set_int.obj ltm/bn_mp_init_size.obj \ +ltm/bn_mp_invmod.obj ltm/bn_mp_invmod_slow.obj ltm/bn_mp_is_square.obj ltm/bn_mp_jacobi.obj \ +ltm/bn_mp_karatsuba_mul.obj ltm/bn_mp_karatsuba_sqr.obj ltm/bn_mp_kronecker.obj ltm/bn_mp_lcm.obj \ +ltm/bn_mp_lshd.obj ltm/bn_mp_mod.obj ltm/bn_mp_mod_2d.obj ltm/bn_mp_mod_d.obj ltm/bn_mp_montgomery_calc_normalization.obj \ +ltm/bn_mp_montgomery_reduce.obj ltm/bn_mp_montgomery_setup.obj ltm/bn_mp_mul.obj \ +ltm/bn_mp_mulmod.obj ltm/bn_mp_mul_2.obj ltm/bn_mp_mul_2d.obj ltm/bn_mp_mul_d.obj \ +ltm/bn_mp_neg.obj ltm/bn_mp_n_root.obj ltm/bn_mp_n_root_ex.obj ltm/bn_mp_or.obj ltm/bn_mp_prime_fermat.obj \ +ltm/bn_mp_prime_frobenius_underwood.obj ltm/bn_mp_prime_is_divisible.obj ltm/bn_mp_prime_is_prime.obj \ ltm/bn_mp_prime_miller_rabin.obj ltm/bn_mp_prime_next_prime.obj ltm/bn_mp_prime_rabin_miller_trials.obj \ -ltm/bn_mp_prime_rand.obj ltm/bn_mp_prime_strong_lucas_selfridge.obj ltm/bn_mp_radix_size.obj \ +ltm/bn_mp_prime_random_ex.obj ltm/bn_mp_prime_strong_lucas_selfridge.obj ltm/bn_mp_radix_size.obj \ ltm/bn_mp_radix_smap.obj ltm/bn_mp_rand.obj ltm/bn_mp_read_radix.obj ltm/bn_mp_read_signed_bin.obj \ ltm/bn_mp_read_unsigned_bin.obj ltm/bn_mp_reduce.obj ltm/bn_mp_reduce_2k.obj ltm/bn_mp_reduce_2k_l.obj \ ltm/bn_mp_reduce_2k_setup.obj ltm/bn_mp_reduce_2k_setup_l.obj ltm/bn_mp_reduce_is_2k.obj \ ltm/bn_mp_reduce_is_2k_l.obj ltm/bn_mp_reduce_setup.obj ltm/bn_mp_rshd.obj ltm/bn_mp_set.obj \ -ltm/bn_mp_set_i32.obj ltm/bn_mp_set_i64.obj ltm/bn_mp_set_u32.obj ltm/bn_mp_set_u64.obj \ -ltm/bn_mp_shrink.obj ltm/bn_mp_signed_bin_size.obj ltm/bn_mp_signed_rsh.obj ltm/bn_mp_sqr.obj \ -ltm/bn_mp_sqrmod.obj ltm/bn_mp_sqrt.obj ltm/bn_mp_sqrtmod_prime.obj ltm/bn_mp_sub.obj \ -ltm/bn_mp_submod.obj ltm/bn_mp_sub_d.obj ltm/bn_mp_toradix.obj ltm/bn_mp_toradix_n.obj \ -ltm/bn_mp_to_signed_bin.obj ltm/bn_mp_to_signed_bin_n.obj ltm/bn_mp_to_unsigned_bin.obj \ -ltm/bn_mp_to_unsigned_bin_n.obj ltm/bn_mp_unsigned_bin_size.obj ltm/bn_mp_xor.obj \ -ltm/bn_mp_zero.obj ltm/bn_prime_tab.obj ltm/bn_s_mp_add.obj ltm/bn_s_mp_balance_mul.obj \ -ltm/bn_s_mp_exptmod.obj ltm/bn_s_mp_exptmod_fast.obj ltm/bn_s_mp_get_bit.obj ltm/bn_s_mp_invmod_fast.obj \ -ltm/bn_s_mp_invmod_slow.obj ltm/bn_s_mp_karatsuba_mul.obj ltm/bn_s_mp_karatsuba_sqr.obj \ -ltm/bn_s_mp_montgomery_reduce_fast.obj ltm/bn_s_mp_mul_digs.obj ltm/bn_s_mp_mul_digs_fast.obj \ -ltm/bn_s_mp_mul_high_digs.obj ltm/bn_s_mp_mul_high_digs_fast.obj ltm/bn_s_mp_prime_is_divisible.obj \ -ltm/bn_s_mp_rand_jenkins.obj ltm/bn_s_mp_rand_platform.obj ltm/bn_s_mp_reverse.obj \ -ltm/bn_s_mp_sqr.obj ltm/bn_s_mp_sqr_fast.obj ltm/bn_s_mp_sub.obj ltm/bn_s_mp_toom_mul.obj \ -ltm/bn_s_mp_toom_sqr.obj +ltm/bn_mp_set_int.obj ltm/bn_mp_set_long.obj ltm/bn_mp_shrink.obj ltm/bn_mp_signed_bin_size.obj \ +ltm/bn_mp_sqr.obj ltm/bn_mp_sqrmod.obj ltm/bn_mp_sqrt.obj ltm/bn_mp_sqrtmod_prime.obj \ +ltm/bn_mp_sub.obj ltm/bn_mp_submod.obj ltm/bn_mp_sub_d.obj ltm/bn_mp_tc_and.obj ltm/bn_mp_tc_div_2d.obj \ +ltm/bn_mp_tc_or.obj ltm/bn_mp_tc_xor.obj ltm/bn_mp_toom_mul.obj ltm/bn_mp_toom_sqr.obj \ +ltm/bn_mp_toradix.obj ltm/bn_mp_toradix_n.obj ltm/bn_mp_to_signed_bin.obj ltm/bn_mp_to_signed_bin_n.obj \ +ltm/bn_mp_to_unsigned_bin.obj ltm/bn_mp_to_unsigned_bin_n.obj ltm/bn_mp_unsigned_bin_size.obj \ +ltm/bn_mp_xor.obj ltm/bn_mp_zero.obj ltm/bn_prime_tab.obj ltm/bn_reverse.obj ltm/bn_s_mp_add.obj \ +ltm/bn_s_mp_exptmod.obj ltm/bn_s_mp_mul_digs.obj ltm/bn_s_mp_mul_high_digs.obj ltm/bn_s_mp_sqr.obj \ +ltm/bn_s_mp_sub.obj PERL =perl RM_F =$(PERL) -MExtUtils::Command -e rm_f -- diff --git a/src/ltm/bn_cutoffs.c b/src/ltm/bn_cutoffs.c deleted file mode 100644 index b02ab716..00000000 --- a/src/ltm/bn_cutoffs.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_CUTOFFS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -#ifndef MP_FIXED_CUTOFFS -#include "tommath_cutoffs.h" -int KARATSUBA_MUL_CUTOFF = MP_DEFAULT_KARATSUBA_MUL_CUTOFF, - KARATSUBA_SQR_CUTOFF = MP_DEFAULT_KARATSUBA_SQR_CUTOFF, - TOOM_MUL_CUTOFF = MP_DEFAULT_TOOM_MUL_CUTOFF, - TOOM_SQR_CUTOFF = MP_DEFAULT_TOOM_SQR_CUTOFF; -#endif - -#endif diff --git a/src/ltm/bn_deprecated.c b/src/ltm/bn_deprecated.c deleted file mode 100644 index 26cea0fd..00000000 --- a/src/ltm/bn_deprecated.c +++ /dev/null @@ -1,208 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_DEPRECATED_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -#ifdef BN_MP_GET_BIT_C -int mp_get_bit(const mp_int *a, int b) -{ - if (b < 0) { - return MP_VAL; - } - return (s_mp_get_bit(a, (unsigned int)b) == MP_YES) ? MP_YES : MP_NO; -} -#endif -#ifdef BN_MP_JACOBI_C -mp_err mp_jacobi(const mp_int *a, const mp_int *n, int *c) -{ - if (a->sign == MP_NEG) { - return MP_VAL; - } - if (mp_cmp_d(n, 0uL) != MP_GT) { - return MP_VAL; - } - return mp_kronecker(a, n, c); -} -#endif -#ifdef BN_MP_PRIME_RANDOM_EX_C -mp_err mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat) -{ - return s_mp_prime_random_ex(a, t, size, flags, cb, dat); -} -#endif -#ifdef BN_MP_RAND_DIGIT_C -mp_err mp_rand_digit(mp_digit *r) -{ - mp_err err = s_mp_rand_source(r, sizeof(mp_digit)); - *r &= MP_MASK; - return err; -} -#endif -#ifdef BN_FAST_MP_INVMOD_C -mp_err fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) -{ - return s_mp_invmod_fast(a, b, c); -} -#endif -#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C -mp_err fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) -{ - return s_mp_montgomery_reduce_fast(x, n, rho); -} -#endif -#ifdef BN_FAST_S_MP_MUL_DIGS_C -mp_err fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) -{ - return s_mp_mul_digs_fast(a, b, c, digs); -} -#endif -#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C -mp_err fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) -{ - return s_mp_mul_high_digs_fast(a, b, c, digs); -} -#endif -#ifdef BN_FAST_S_MP_SQR_C -mp_err fast_s_mp_sqr(const mp_int *a, mp_int *b) -{ - return s_mp_sqr_fast(a, b); -} -#endif -#ifdef BN_MP_BALANCE_MUL_C -mp_err mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c) -{ - return s_mp_balance_mul(a, b, c); -} -#endif -#ifdef BN_MP_EXPTMOD_FAST_C -mp_err mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) -{ - return s_mp_exptmod_fast(G, X, P, Y, redmode); -} -#endif -#ifdef BN_MP_INVMOD_SLOW_C -mp_err mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) -{ - return s_mp_invmod_slow(a, b, c); -} -#endif -#ifdef BN_MP_KARATSUBA_MUL_C -mp_err mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c) -{ - return s_mp_karatsuba_mul(a, b, c); -} -#endif -#ifdef BN_MP_KARATSUBA_SQR_C -mp_err mp_karatsuba_sqr(const mp_int *a, mp_int *b) -{ - return s_mp_karatsuba_sqr(a, b); -} -#endif -#ifdef BN_MP_TOOM_MUL_C -mp_err mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c) -{ - return s_mp_toom_mul(a, b, c); -} -#endif -#ifdef BN_MP_TOOM_SQR_C -mp_err mp_toom_sqr(const mp_int *a, mp_int *b) -{ - return s_mp_toom_sqr(a, b); -} -#endif -#ifdef S_MP_REVERSE_C -void bn_reverse(unsigned char *s, int len) -{ - s_mp_reverse(s, len); -} -#endif -#ifdef BN_MP_TC_AND_C -mp_err mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c) -{ - return mp_and(a, b, c); -} -#endif -#ifdef BN_MP_TC_OR_C -mp_err mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c) -{ - return mp_or(a, b, c); -} -#endif -#ifdef BN_MP_TC_XOR_C -mp_err mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c) -{ - return mp_xor(a, b, c); -} -#endif -#ifdef BN_MP_TC_DIV_2D_C -mp_err mp_tc_div_2d(const mp_int *a, int b, mp_int *c) -{ - return mp_signed_rsh(a, b, c); -} -#endif -#ifdef BN_MP_INIT_SET_INT_C -mp_err mp_init_set_int(mp_int *a, unsigned long b) -{ - return mp_init_u32(a, (unsigned int)b); -} -#endif -#ifdef BN_MP_SET_INT_C -mp_err mp_set_int(mp_int *a, unsigned long b) -{ - mp_set_u32(a, (unsigned int)b); - return MP_OKAY; -} -#endif -#ifdef BN_MP_SET_LONG_C -mp_err mp_set_long(mp_int *a, unsigned long b) -{ - mp_set_u64(a, b); - return MP_OKAY; -} -#endif -#ifdef BN_MP_SET_LONG_LONG_C -mp_err mp_set_long_long(mp_int *a, unsigned long long b) -{ - mp_set_u64(a, b); - return MP_OKAY; -} -#endif -#ifdef BN_MP_GET_INT_C -unsigned long mp_get_int(const mp_int *a) -{ - return mp_get_mag32(a); -} -#endif -#ifdef BN_MP_GET_LONG_C -unsigned long mp_get_long(const mp_int *a) -{ - return (sizeof(long) > sizeof(int)) ? (unsigned long)mp_get_mag64(a) : (unsigned long)mp_get_mag32(a); -} -#endif -#ifdef BN_MP_GET_LONG_LONG_C -unsigned long long mp_get_long_long(const mp_int *a) -{ - return (unsigned long long)mp_get_mag64(a); -} -#endif -#ifdef BN_MP_PRIME_IS_DIVISIBLE_C -mp_err mp_prime_is_divisible(const mp_int *a, mp_bool *result) -{ - return s_mp_prime_is_divisible(a, result); -} -#endif -#ifdef BN_MP_EXPT_D_EX_C -mp_err mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) -{ - (void)fast; - return mp_expt_d(a, b, c); -} -#endif -#ifdef BN_MP_N_ROOT_EX_C -mp_err mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) -{ - (void)fast; - return mp_n_root(a, b, c); -} -#endif -#endif diff --git a/src/ltm/bn_error.c b/src/ltm/bn_error.c new file mode 100644 index 00000000..697875f9 --- /dev/null +++ b/src/ltm/bn_error.c @@ -0,0 +1,44 @@ +#include "tommath_private.h" +#ifdef BN_ERROR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +static const struct { + int code; + const char *msg; +} msgs[] = { + { MP_OKAY, "Successful" }, + { MP_MEM, "Out of heap" }, + { MP_VAL, "Value out of range" } +}; + +/* return a char * string for a given code */ +const char *mp_error_to_string(int code) +{ + size_t x; + + /* scan the lookup table for the given message */ + for (x = 0; x < (sizeof(msgs) / sizeof(msgs[0])); x++) { + if (msgs[x].code == code) { + return msgs[x].msg; + } + } + + /* generic reply for invalid code */ + return "Invalid error code"; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_invmod_fast.c b/src/ltm/bn_fast_mp_invmod.c index be7813c9..3c8088ff 100644 --- a/src/ltm/bn_s_mp_invmod_fast.c +++ b/src/ltm/bn_fast_mp_invmod.c @@ -1,7 +1,16 @@ #include "tommath_private.h" -#ifdef BN_S_MP_INVMOD_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_FAST_MP_INVMOD_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* computes the modular inverse via binary extended euclidean algorithm, * that is c = 1/a mod b @@ -9,81 +18,80 @@ * Based on slow invmod except this is optimized for the case where b is * odd as per HAC Note 14.64 on pp. 610 */ -mp_err s_mp_invmod_fast(const mp_int *a, const mp_int *b, mp_int *c) +int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) { mp_int x, y, u, v, B, D; - mp_sign neg; - mp_err err; + int res, neg; /* 2. [modified] b must be odd */ - if (MP_IS_EVEN(b)) { + if (mp_iseven(b) == MP_YES) { return MP_VAL; } /* init all our temps */ - if ((err = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { - return err; + if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) { + return res; } /* x == modulus, y == value to invert */ - if ((err = mp_copy(b, &x)) != MP_OKAY) { + if ((res = mp_copy(b, &x)) != MP_OKAY) { goto LBL_ERR; } /* we need y = |a| */ - if ((err = mp_mod(a, b, &y)) != MP_OKAY) { + if ((res = mp_mod(a, b, &y)) != MP_OKAY) { goto LBL_ERR; } /* if one of x,y is zero return an error! */ - if (MP_IS_ZERO(&x) || MP_IS_ZERO(&y)) { - err = MP_VAL; + if ((mp_iszero(&x) == MP_YES) || (mp_iszero(&y) == MP_YES)) { + res = MP_VAL; goto LBL_ERR; } /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((err = mp_copy(&x, &u)) != MP_OKAY) { + if ((res = mp_copy(&x, &u)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&y, &v)) != MP_OKAY) { + if ((res = mp_copy(&y, &v)) != MP_OKAY) { goto LBL_ERR; } mp_set(&D, 1uL); top: /* 4. while u is even do */ - while (MP_IS_EVEN(&u)) { + while (mp_iseven(&u) == MP_YES) { /* 4.1 u = u/2 */ - if ((err = mp_div_2(&u, &u)) != MP_OKAY) { + if ((res = mp_div_2(&u, &u)) != MP_OKAY) { goto LBL_ERR; } /* 4.2 if B is odd then */ - if (MP_IS_ODD(&B)) { - if ((err = mp_sub(&B, &x, &B)) != MP_OKAY) { + if (mp_isodd(&B) == MP_YES) { + if ((res = mp_sub(&B, &x, &B)) != MP_OKAY) { goto LBL_ERR; } } /* B = B/2 */ - if ((err = mp_div_2(&B, &B)) != MP_OKAY) { + if ((res = mp_div_2(&B, &B)) != MP_OKAY) { goto LBL_ERR; } } /* 5. while v is even do */ - while (MP_IS_EVEN(&v)) { + while (mp_iseven(&v) == MP_YES) { /* 5.1 v = v/2 */ - if ((err = mp_div_2(&v, &v)) != MP_OKAY) { + if ((res = mp_div_2(&v, &v)) != MP_OKAY) { goto LBL_ERR; } /* 5.2 if D is odd then */ - if (MP_IS_ODD(&D)) { + if (mp_isodd(&D) == MP_YES) { /* D = (D-x)/2 */ - if ((err = mp_sub(&D, &x, &D)) != MP_OKAY) { + if ((res = mp_sub(&D, &x, &D)) != MP_OKAY) { goto LBL_ERR; } } /* D = D/2 */ - if ((err = mp_div_2(&D, &D)) != MP_OKAY) { + if ((res = mp_div_2(&D, &D)) != MP_OKAY) { goto LBL_ERR; } } @@ -91,26 +99,26 @@ top: /* 6. if u >= v then */ if (mp_cmp(&u, &v) != MP_LT) { /* u = u - v, B = B - D */ - if ((err = mp_sub(&u, &v, &u)) != MP_OKAY) { + if ((res = mp_sub(&u, &v, &u)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&B, &D, &B)) != MP_OKAY) { + if ((res = mp_sub(&B, &D, &B)) != MP_OKAY) { goto LBL_ERR; } } else { /* v - v - u, D = D - B */ - if ((err = mp_sub(&v, &u, &v)) != MP_OKAY) { + if ((res = mp_sub(&v, &u, &v)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&D, &B, &D)) != MP_OKAY) { + if ((res = mp_sub(&D, &B, &D)) != MP_OKAY) { goto LBL_ERR; } } /* if not zero goto step 4 */ - if (!MP_IS_ZERO(&u)) { + if (mp_iszero(&u) == MP_NO) { goto top; } @@ -118,31 +126,35 @@ top: /* if v != 1 then there is no inverse */ if (mp_cmp_d(&v, 1uL) != MP_EQ) { - err = MP_VAL; + res = MP_VAL; goto LBL_ERR; } /* b is now the inverse */ neg = a->sign; while (D.sign == MP_NEG) { - if ((err = mp_add(&D, b, &D)) != MP_OKAY) { + if ((res = mp_add(&D, b, &D)) != MP_OKAY) { goto LBL_ERR; } } /* too big */ while (mp_cmp_mag(&D, b) != MP_LT) { - if ((err = mp_sub(&D, b, &D)) != MP_OKAY) { + if ((res = mp_sub(&D, b, &D)) != MP_OKAY) { goto LBL_ERR; } } mp_exch(&D, c); c->sign = neg; - err = MP_OKAY; + res = MP_OKAY; LBL_ERR: mp_clear_multi(&x, &y, &u, &v, &B, &D, NULL); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_montgomery_reduce_fast.c b/src/ltm/bn_fast_mp_montgomery_reduce.c index 843ad124..eb5d90b3 100644 --- a/src/ltm/bn_s_mp_montgomery_reduce_fast.c +++ b/src/ltm/bn_fast_mp_montgomery_reduce.c @@ -1,7 +1,16 @@ #include "tommath_private.h" -#ifdef BN_S_MP_MONTGOMERY_REDUCE_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* computes xR**-1 == x (mod N) via Montgomery Reduction * @@ -11,13 +20,12 @@ * * Based on Algorithm 14.32 on pp.601 of HAC. */ -mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) +int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) { - int ix, olduse; - mp_err err; + int ix, res, olduse; mp_word W[MP_WARRAY]; - if (x->used > MP_WARRAY) { + if (x->used > (int)MP_WARRAY) { return MP_VAL; } @@ -26,8 +34,8 @@ mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) /* grow a as required */ if (x->alloc < (n->used + 1)) { - if ((err = mp_grow(x, n->used + 1)) != MP_OKAY) { - return err; + if ((res = mp_grow(x, n->used + 1)) != MP_OKAY) { + return res; } } @@ -50,8 +58,8 @@ mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) } /* zero the high words of W[a->used..m->used*2] */ - if (ix < ((n->used * 2) + 1)) { - MP_ZERO_BUFFER(_W, sizeof(mp_word) * (size_t)(((n->used * 2) + 1) - ix)); + for (; ix < ((n->used * 2) + 1); ix++) { + *_W++ = 0; } } @@ -100,7 +108,7 @@ mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) } /* now fix carry for next digit, W[ix+1] */ - W[ix + 1] += W[ix] >> (mp_word)MP_DIGIT_BIT; + W[ix + 1] += W[ix] >> (mp_word)DIGIT_BIT; } /* now we have to propagate the carries and @@ -120,7 +128,7 @@ mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) _W = W + ++ix; for (; ix <= ((n->used * 2) + 1); ix++) { - *_W++ += *_W1++ >> (mp_word)MP_DIGIT_BIT; + *_W++ += *_W1++ >> (mp_word)DIGIT_BIT; } /* copy out, A = A/b**n @@ -143,7 +151,9 @@ mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) /* zero oldused digits, if the input a was larger than * m->used+1 we'll have to clear the digits */ - MP_ZERO_DIGITS(tmpx, olduse - ix); + for (; ix < olduse; ix++) { + *tmpx++ = 0; + } } /* set the max used and clamp */ @@ -157,3 +167,7 @@ mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_mul_digs_fast.c b/src/ltm/bn_fast_s_mp_mul_digs.c index b2a287b0..4736799b 100644 --- a/src/ltm/bn_s_mp_mul_digs_fast.c +++ b/src/ltm/bn_fast_s_mp_mul_digs.c @@ -1,7 +1,16 @@ #include "tommath_private.h" -#ifdef BN_S_MP_MUL_DIGS_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_FAST_S_MP_MUL_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* Fast (comba) multiplier * @@ -19,22 +28,21 @@ * Based on Algorithm 14.12 on pp.595 of HAC. * */ -mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) +int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) { - int olduse, pa, ix, iz; - mp_err err; + int olduse, res, pa, ix, iz; mp_digit W[MP_WARRAY]; mp_word _W; /* grow the destination as required */ if (c->alloc < digs) { - if ((err = mp_grow(c, digs)) != MP_OKAY) { - return err; + if ((res = mp_grow(c, digs)) != MP_OKAY) { + return res; } } /* number of output digits to produce */ - pa = MP_MIN(digs, a->used + b->used); + pa = MIN(digs, a->used + b->used); /* clear the carry */ _W = 0; @@ -44,7 +52,7 @@ mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) mp_digit *tmpx, *tmpy; /* get offsets into the two bignums */ - ty = MP_MIN(b->used-1, ix); + ty = MIN(b->used-1, ix); tx = ix - ty; /* setup temp aliases */ @@ -54,7 +62,7 @@ mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) /* this is the number of times the loop will iterrate, essentially while (tx++ < a->used && ty-- >= 0) { ... } */ - iy = MP_MIN(a->used-tx, ty+1); + iy = MIN(a->used-tx, ty+1); /* execute loop */ for (iz = 0; iz < iy; ++iz) { @@ -66,7 +74,7 @@ mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) W[ix] = (mp_digit)_W & MP_MASK; /* make next carry */ - _W = _W >> (mp_word)MP_DIGIT_BIT; + _W = _W >> (mp_word)DIGIT_BIT; } /* setup dest */ @@ -82,9 +90,15 @@ mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) } /* clear unused digits [that existed in the old copy of c] */ - MP_ZERO_DIGITS(tmpc, olduse - ix); + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } } mp_clamp(c); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_mul_high_digs_fast.c b/src/ltm/bn_fast_s_mp_mul_high_digs.c index a2c4fb69..06c076ca 100644 --- a/src/ltm/bn_s_mp_mul_high_digs_fast.c +++ b/src/ltm/bn_fast_s_mp_mul_high_digs.c @@ -1,7 +1,16 @@ #include "tommath_private.h" -#ifdef BN_S_MP_MUL_HIGH_DIGS_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* this is a modified version of fast_s_mul_digs that only produces * output digits *above* digs. See the comments for fast_s_mul_digs @@ -12,18 +21,17 @@ * * Based on Algorithm 14.12 on pp.595 of HAC. */ -mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) +int fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) { - int olduse, pa, ix, iz; - mp_err err; + int olduse, res, pa, ix, iz; mp_digit W[MP_WARRAY]; mp_word _W; /* grow the destination as required */ pa = a->used + b->used; if (c->alloc < pa) { - if ((err = mp_grow(c, pa)) != MP_OKAY) { - return err; + if ((res = mp_grow(c, pa)) != MP_OKAY) { + return res; } } @@ -35,7 +43,7 @@ mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int mp_digit *tmpx, *tmpy; /* get offsets into the two bignums */ - ty = MP_MIN(b->used-1, ix); + ty = MIN(b->used-1, ix); tx = ix - ty; /* setup temp aliases */ @@ -45,7 +53,7 @@ mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int /* this is the number of times the loop will iterrate, essentially its while (tx++ < a->used && ty-- >= 0) { ... } */ - iy = MP_MIN(a->used-tx, ty+1); + iy = MIN(a->used-tx, ty+1); /* execute loop */ for (iz = 0; iz < iy; iz++) { @@ -56,7 +64,7 @@ mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int W[ix] = (mp_digit)_W & MP_MASK; /* make next carry */ - _W = _W >> (mp_word)MP_DIGIT_BIT; + _W = _W >> (mp_word)DIGIT_BIT; } /* setup dest */ @@ -73,9 +81,15 @@ mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int } /* clear unused digits [that existed in the old copy of c] */ - MP_ZERO_DIGITS(tmpc, olduse - ix); + for (; ix < olduse; ix++) { + *tmpc++ = 0; + } } mp_clamp(c); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_sqr_fast.c b/src/ltm/bn_fast_s_mp_sqr.c index 4a8a8912..5be8e9db 100644 --- a/src/ltm/bn_s_mp_sqr_fast.c +++ b/src/ltm/bn_fast_s_mp_sqr.c @@ -1,7 +1,16 @@ #include "tommath_private.h" -#ifdef BN_S_MP_SQR_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_FAST_S_MP_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* the jist of squaring... * you do like mult except the offset of the tmpx [one that @@ -13,18 +22,17 @@ After that loop you do the squares and add them in. */ -mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b) +int fast_s_mp_sqr(const mp_int *a, mp_int *b) { - int olduse, pa, ix, iz; - mp_digit W[MP_WARRAY], *tmpx; + int olduse, res, pa, ix, iz; + mp_digit W[MP_WARRAY], *tmpx; mp_word W1; - mp_err err; /* grow the destination as required */ pa = a->used + a->used; if (b->alloc < pa) { - if ((err = mp_grow(b, pa)) != MP_OKAY) { - return err; + if ((res = mp_grow(b, pa)) != MP_OKAY) { + return res; } } @@ -39,7 +47,7 @@ mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b) _W = 0; /* get offsets into the two bignums */ - ty = MP_MIN(a->used-1, ix); + ty = MIN(a->used-1, ix); tx = ix - ty; /* setup temp aliases */ @@ -49,13 +57,13 @@ mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b) /* this is the number of times the loop will iterrate, essentially while (tx++ < a->used && ty-- >= 0) { ... } */ - iy = MP_MIN(a->used-tx, ty+1); + iy = MIN(a->used-tx, ty+1); /* now for squaring tx can never equal ty * we halve the distance since they approach at a rate of 2x * and we have to round because odd cases need to be executed */ - iy = MP_MIN(iy, ((ty-tx)+1)>>1); + iy = MIN(iy, ((ty-tx)+1)>>1); /* execute loop */ for (iz = 0; iz < iy; iz++) { @@ -71,10 +79,10 @@ mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b) } /* store it */ - W[ix] = (mp_digit)_W & MP_MASK; + W[ix] = _W & MP_MASK; /* make next carry */ - W1 = _W >> (mp_word)MP_DIGIT_BIT; + W1 = _W >> (mp_word)DIGIT_BIT; } /* setup dest */ @@ -89,9 +97,15 @@ mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b) } /* clear unused digits [that existed in the old copy of c] */ - MP_ZERO_DIGITS(tmpb, olduse - ix); + for (; ix < olduse; ix++) { + *tmpb++ = 0; + } } mp_clamp(b); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_2expt.c b/src/ltm/bn_mp_2expt.c index 0ae3df1b..42f57467 100644 --- a/src/ltm/bn_mp_2expt.c +++ b/src/ltm/bn_mp_2expt.c @@ -1,31 +1,44 @@ #include "tommath_private.h" #ifdef BN_MP_2EXPT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* computes a = 2**b * * Simple algorithm which zeroes the int, grows it then just sets one bit * as required. */ -mp_err mp_2expt(mp_int *a, int b) +int mp_2expt(mp_int *a, int b) { - mp_err err; + int res; /* zero a as per default */ mp_zero(a); /* grow a to accomodate the single bit */ - if ((err = mp_grow(a, (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) { - return err; + if ((res = mp_grow(a, (b / DIGIT_BIT) + 1)) != MP_OKAY) { + return res; } /* set the used count of where the bit will go */ - a->used = (b / MP_DIGIT_BIT) + 1; + a->used = (b / DIGIT_BIT) + 1; /* put the single bit in its place */ - a->dp[b / MP_DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT); + a->dp[b / DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % DIGIT_BIT); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_abs.c b/src/ltm/bn_mp_abs.c index 00900bbd..f12d261a 100644 --- a/src/ltm/bn_mp_abs.c +++ b/src/ltm/bn_mp_abs.c @@ -1,20 +1,29 @@ #include "tommath_private.h" #ifdef BN_MP_ABS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* b = |a| * * Simple function copies the input and fixes the sign to positive */ -mp_err mp_abs(const mp_int *a, mp_int *b) +int mp_abs(const mp_int *a, mp_int *b) { - mp_err err; + int res; /* copy a to b */ if (a != b) { - if ((err = mp_copy(a, b)) != MP_OKAY) { - return err; + if ((res = mp_copy(a, b)) != MP_OKAY) { + return res; } } @@ -24,3 +33,7 @@ mp_err mp_abs(const mp_int *a, mp_int *b) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_add.c b/src/ltm/bn_mp_add.c index dfa78de5..f04388af 100644 --- a/src/ltm/bn_mp_add.c +++ b/src/ltm/bn_mp_add.c @@ -1,13 +1,21 @@ #include "tommath_private.h" #ifdef BN_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* high level addition (handles signs) */ -mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c) +int mp_add(const mp_int *a, const mp_int *b, mp_int *c) { - mp_sign sa, sb; - mp_err err; + int sa, sb, res; /* get sign of both inputs */ sa = a->sign; @@ -18,7 +26,7 @@ mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c) /* both positive or both negative */ /* add their magnitudes, copy the sign */ c->sign = sa; - err = s_mp_add(a, b, c); + res = s_mp_add(a, b, c); } else { /* one positive, the other negative */ /* subtract the one with the greater magnitude from */ @@ -26,13 +34,17 @@ mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c) /* the sign of the one with the greater magnitude. */ if (mp_cmp_mag(a, b) == MP_LT) { c->sign = sb; - err = s_mp_sub(b, a, c); + res = s_mp_sub(b, a, c); } else { c->sign = sa; - err = s_mp_sub(a, b, c); + res = s_mp_sub(a, b, c); } } - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_add_d.c b/src/ltm/bn_mp_add_d.c index f3015756..ecdb7913 100644 --- a/src/ltm/bn_mp_add_d.c +++ b/src/ltm/bn_mp_add_d.c @@ -1,19 +1,27 @@ #include "tommath_private.h" #ifdef BN_MP_ADD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* single digit addition */ -mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) +int mp_add_d(const mp_int *a, mp_digit b, mp_int *c) { - mp_err err; - int ix, oldused; - mp_digit *tmpa, *tmpc; + int res, ix, oldused; + mp_digit *tmpa, *tmpc, mu; /* grow c as required */ if (c->alloc < (a->used + 1)) { - if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { - return err; + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; } } @@ -24,7 +32,7 @@ mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) a_.sign = MP_ZPOS; /* c = |a| - b */ - err = mp_sub_d(&a_, b, c); + res = mp_sub_d(&a_, b, c); /* fix sign */ c->sign = MP_NEG; @@ -32,7 +40,7 @@ mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) /* clamp */ mp_clamp(c); - return err; + return res; } /* old number of used digits in c */ @@ -46,11 +54,17 @@ mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) /* if a is positive */ if (a->sign == MP_ZPOS) { - /* add digits, mu is carry */ - mp_digit mu = b; - for (ix = 0; ix < a->used; ix++) { + /* add digit, after this we're propagating + * the carry. + */ + *tmpc = *tmpa++ + b; + mu = *tmpc >> DIGIT_BIT; + *tmpc++ &= MP_MASK; + + /* now handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { *tmpc = *tmpa++ + mu; - mu = *tmpc >> MP_DIGIT_BIT; + mu = *tmpc >> DIGIT_BIT; *tmpc++ &= MP_MASK; } /* set final carry */ @@ -80,10 +94,16 @@ mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) c->sign = MP_ZPOS; /* now zero to oldused */ - MP_ZERO_DIGITS(tmpc, oldused - ix); + while (ix++ < oldused) { + *tmpc++ = 0; + } mp_clamp(c); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_addmod.c b/src/ltm/bn_mp_addmod.c index 2636e2a6..f8e4ddac 100644 --- a/src/ltm/bn_mp_addmod.c +++ b/src/ltm/bn_mp_addmod.c @@ -1,24 +1,37 @@ #include "tommath_private.h" #ifdef BN_MP_ADDMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* d = a + b (mod c) */ -mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) +int mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) { - mp_err err; + int res; mp_int t; - if ((err = mp_init(&t)) != MP_OKAY) { - return err; + if ((res = mp_init(&t)) != MP_OKAY) { + return res; } - if ((err = mp_add(a, b, &t)) != MP_OKAY) { + if ((res = mp_add(a, b, &t)) != MP_OKAY) { mp_clear(&t); - return err; + return res; } - err = mp_mod(&t, c, d); + res = mp_mod(&t, c, d); mp_clear(&t); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_and.c b/src/ltm/bn_mp_and.c index c259f8de..789bb58f 100644 --- a/src/ltm/bn_mp_and.c +++ b/src/ltm/bn_mp_and.c @@ -1,56 +1,54 @@ #include "tommath_private.h" #ifdef BN_MP_AND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* two complement and */ -mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c) +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* AND two ints together */ +int mp_and(const mp_int *a, const mp_int *b, mp_int *c) { - int used = MP_MAX(a->used, b->used) + 1, i; - mp_err err; - mp_digit ac = 1, bc = 1, cc = 1; - mp_sign csign = ((a->sign == MP_NEG) && (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS; - - if (c->alloc < used) { - if ((err = mp_grow(c, used)) != MP_OKAY) { - return err; - } - } - - for (i = 0; i < used; i++) { - mp_digit x, y; + int res, ix, px; + mp_int t; + const mp_int *x; - /* convert to two complement if negative */ - if (a->sign == MP_NEG) { - ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK); - x = ac & MP_MASK; - ac >>= MP_DIGIT_BIT; - } else { - x = (i >= a->used) ? 0uL : a->dp[i]; + if (a->used > b->used) { + if ((res = mp_init_copy(&t, a)) != MP_OKAY) { + return res; } - - /* convert to two complement if negative */ - if (b->sign == MP_NEG) { - bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK); - y = bc & MP_MASK; - bc >>= MP_DIGIT_BIT; - } else { - y = (i >= b->used) ? 0uL : b->dp[i]; + px = b->used; + x = b; + } else { + if ((res = mp_init_copy(&t, b)) != MP_OKAY) { + return res; } + px = a->used; + x = a; + } - c->dp[i] = x & y; + for (ix = 0; ix < px; ix++) { + t.dp[ix] &= x->dp[ix]; + } - /* convert to to sign-magnitude if negative */ - if (csign == MP_NEG) { - cc += ~c->dp[i] & MP_MASK; - c->dp[i] = cc & MP_MASK; - cc >>= MP_DIGIT_BIT; - } + /* zero digits above the last from the smallest mp_int */ + for (; ix < t.used; ix++) { + t.dp[ix] = 0; } - c->used = used; - c->sign = csign; - mp_clamp(c); + mp_clamp(&t); + mp_exch(c, &t); + mp_clear(&t); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_clamp.c b/src/ltm/bn_mp_clamp.c index ac23bfd3..0953f4b2 100644 --- a/src/ltm/bn_mp_clamp.c +++ b/src/ltm/bn_mp_clamp.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_CLAMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* trim unused digits * @@ -25,3 +34,7 @@ void mp_clamp(mp_int *a) } } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_clear.c b/src/ltm/bn_mp_clear.c index ff78324d..1f360b27 100644 --- a/src/ltm/bn_mp_clear.c +++ b/src/ltm/bn_mp_clear.c @@ -1,15 +1,31 @@ #include "tommath_private.h" #ifdef BN_MP_CLEAR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* clear one (frees) */ void mp_clear(mp_int *a) { + int i; + /* only do anything if a hasn't been freed previously */ if (a->dp != NULL) { + /* first zero the digits */ + for (i = 0; i < a->used; i++) { + a->dp[i] = 0; + } + /* free ram */ - MP_FREE_DIGITS(a->dp, a->alloc); + XFREE(a->dp); /* reset members to make debugging easier */ a->dp = NULL; @@ -18,3 +34,7 @@ void mp_clear(mp_int *a) } } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_clear_multi.c b/src/ltm/bn_mp_clear_multi.c index 794e45fa..c96b4ac4 100644 --- a/src/ltm/bn_mp_clear_multi.c +++ b/src/ltm/bn_mp_clear_multi.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_CLEAR_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ #include <stdarg.h> @@ -17,3 +26,7 @@ void mp_clear_multi(mp_int *mp, ...) va_end(args); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_cmp.c b/src/ltm/bn_mp_cmp.c index ced48409..fdcb8d54 100644 --- a/src/ltm/bn_mp_cmp.c +++ b/src/ltm/bn_mp_cmp.c @@ -1,10 +1,19 @@ #include "tommath_private.h" #ifdef BN_MP_CMP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* compare two ints (signed)*/ -mp_ord mp_cmp(const mp_int *a, const mp_int *b) +int mp_cmp(const mp_int *a, const mp_int *b) { /* compare based on sign */ if (a->sign != b->sign) { @@ -24,3 +33,7 @@ mp_ord mp_cmp(const mp_int *a, const mp_int *b) } } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_cmp_d.c b/src/ltm/bn_mp_cmp_d.c index 5a8337b5..643cac6e 100644 --- a/src/ltm/bn_mp_cmp_d.c +++ b/src/ltm/bn_mp_cmp_d.c @@ -1,10 +1,19 @@ #include "tommath_private.h" #ifdef BN_MP_CMP_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* compare a digit */ -mp_ord mp_cmp_d(const mp_int *a, mp_digit b) +int mp_cmp_d(const mp_int *a, mp_digit b) { /* compare based on sign */ if (a->sign == MP_NEG) { @@ -26,3 +35,7 @@ mp_ord mp_cmp_d(const mp_int *a, mp_digit b) } } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_cmp_mag.c b/src/ltm/bn_mp_cmp_mag.c index f144ea9e..7f6ce279 100644 --- a/src/ltm/bn_mp_cmp_mag.c +++ b/src/ltm/bn_mp_cmp_mag.c @@ -1,13 +1,22 @@ #include "tommath_private.h" #ifdef BN_MP_CMP_MAG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* compare maginitude of two ints (unsigned) */ -mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b) +int mp_cmp_mag(const mp_int *a, const mp_int *b) { int n; - const mp_digit *tmpa, *tmpb; + mp_digit *tmpa, *tmpb; /* compare based on # of non-zero digits */ if (a->used > b->used) { @@ -37,3 +46,7 @@ mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b) return MP_EQ; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_cnt_lsb.c b/src/ltm/bn_mp_cnt_lsb.c index 4b2d206e..5d9b327f 100644 --- a/src/ltm/bn_mp_cnt_lsb.c +++ b/src/ltm/bn_mp_cnt_lsb.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_CNT_LSB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ static const int lnz[16] = { 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 @@ -14,14 +23,14 @@ int mp_cnt_lsb(const mp_int *a) mp_digit q, qq; /* easy out */ - if (MP_IS_ZERO(a)) { + if (mp_iszero(a) == MP_YES) { return 0; } /* scan lower digits until non-zero */ for (x = 0; (x < a->used) && (a->dp[x] == 0u); x++) {} q = a->dp[x]; - x *= MP_DIGIT_BIT; + x *= DIGIT_BIT; /* now scan this digit until a 1 is found */ if ((q & 1u) == 0u) { @@ -35,3 +44,7 @@ int mp_cnt_lsb(const mp_int *a) } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_complement.c b/src/ltm/bn_mp_complement.c index fef1423c..5a5a9693 100644 --- a/src/ltm/bn_mp_complement.c +++ b/src/ltm/bn_mp_complement.c @@ -1,12 +1,25 @@ #include "tommath_private.h" #ifdef BN_MP_COMPLEMENT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* b = ~a */ -mp_err mp_complement(const mp_int *a, mp_int *b) +int mp_complement(const mp_int *a, mp_int *b) { - mp_err err = mp_neg(a, b); - return (err == MP_OKAY) ? mp_sub_d(b, 1uL, b) : err; + int res = mp_neg(a, b); + return (res == MP_OKAY) ? mp_sub_d(b, 1uL, b) : res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_copy.c b/src/ltm/bn_mp_copy.c index 141dd0e0..51e02390 100644 --- a/src/ltm/bn_mp_copy.c +++ b/src/ltm/bn_mp_copy.c @@ -1,13 +1,21 @@ #include "tommath_private.h" #ifdef BN_MP_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* copy, b = a */ -mp_err mp_copy(const mp_int *a, mp_int *b) +int mp_copy(const mp_int *a, mp_int *b) { - int n; - mp_err err; + int res, n; /* if dst == src do nothing */ if (a == b) { @@ -16,8 +24,8 @@ mp_err mp_copy(const mp_int *a, mp_int *b) /* grow dest */ if (b->alloc < a->used) { - if ((err = mp_grow(b, a->used)) != MP_OKAY) { - return err; + if ((res = mp_grow(b, a->used)) != MP_OKAY) { + return res; } } @@ -39,7 +47,9 @@ mp_err mp_copy(const mp_int *a, mp_int *b) } /* clear high digits */ - MP_ZERO_DIGITS(tmpb, b->used - n); + for (; n < b->used; n++) { + *tmpb++ = 0; + } } /* copy used count and sign */ @@ -48,3 +58,7 @@ mp_err mp_copy(const mp_int *a, mp_int *b) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_count_bits.c b/src/ltm/bn_mp_count_bits.c index b7c2cad1..f7a05df1 100644 --- a/src/ltm/bn_mp_count_bits.c +++ b/src/ltm/bn_mp_count_bits.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_COUNT_BITS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* returns the number of bits in an int */ int mp_count_bits(const mp_int *a) @@ -10,19 +19,23 @@ int mp_count_bits(const mp_int *a) mp_digit q; /* shortcut */ - if (MP_IS_ZERO(a)) { + if (a->used == 0) { return 0; } /* get number of digits and add that */ - r = (a->used - 1) * MP_DIGIT_BIT; + r = (a->used - 1) * DIGIT_BIT; /* take the last digit and count the bits in it */ q = a->dp[a->used - 1]; - while (q > 0u) { + while (q > (mp_digit)0) { ++r; - q >>= 1u; + q >>= (mp_digit)1; } return r; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_decr.c b/src/ltm/bn_mp_decr.c deleted file mode 100644 index c6a1572c..00000000 --- a/src/ltm/bn_mp_decr.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_DECR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* Decrement "a" by one like "a--". Changes input! */ -mp_err mp_decr(mp_int *a) -{ - if (MP_IS_ZERO(a)) { - mp_set(a,1uL); - a->sign = MP_NEG; - return MP_OKAY; - } else if (a->sign == MP_NEG) { - mp_err err; - a->sign = MP_ZPOS; - if ((err = mp_incr(a)) != MP_OKAY) { - return err; - } - /* There is no -0 in LTM */ - if (!MP_IS_ZERO(a)) { - a->sign = MP_NEG; - } - return MP_OKAY; - } else if (a->dp[0] > 1uL) { - a->dp[0]--; - if (a->dp[0] == 0u) { - mp_zero(a); - } - return MP_OKAY; - } else { - return mp_sub_d(a, 1uL,a); - } -} -#endif diff --git a/src/ltm/bn_mp_div.c b/src/ltm/bn_mp_div.c index fad3d2ad..44e3cb95 100644 --- a/src/ltm/bn_mp_div.c +++ b/src/ltm/bn_mp_div.c @@ -1,59 +1,67 @@ #include "tommath_private.h" #ifdef BN_MP_DIV_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ #ifdef BN_MP_DIV_SMALL /* slower bit-bang division... also smaller */ -mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) +int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) { mp_int ta, tb, tq, q; - int n, n2; - mp_err err; + int res, n, n2; /* is divisor zero ? */ - if (MP_IS_ZERO(b)) { + if (mp_iszero(b) == MP_YES) { return MP_VAL; } /* if a < b then q=0, r = a */ if (mp_cmp_mag(a, b) == MP_LT) { if (d != NULL) { - err = mp_copy(a, d); + res = mp_copy(a, d); } else { - err = MP_OKAY; + res = MP_OKAY; } if (c != NULL) { mp_zero(c); } - return err; + return res; } /* init our temps */ - if ((err = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { - return err; + if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL)) != MP_OKAY) { + return res; } mp_set(&tq, 1uL); n = mp_count_bits(a) - mp_count_bits(b); - if (((err = mp_abs(a, &ta)) != MP_OKAY) || - ((err = mp_abs(b, &tb)) != MP_OKAY) || - ((err = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || - ((err = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { + if (((res = mp_abs(a, &ta)) != MP_OKAY) || + ((res = mp_abs(b, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) || + ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) { goto LBL_ERR; } while (n-- >= 0) { if (mp_cmp(&tb, &ta) != MP_GT) { - if (((err = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || - ((err = mp_add(&q, &tq, &q)) != MP_OKAY)) { + if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) || + ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) { goto LBL_ERR; } } - if (((err = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || - ((err = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { + if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) || + ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) { goto LBL_ERR; } } @@ -63,15 +71,15 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) n2 = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; if (c != NULL) { mp_exch(c, &q); - c->sign = MP_IS_ZERO(c) ? MP_ZPOS : n2; + c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2; } if (d != NULL) { mp_exch(d, &ta); - d->sign = MP_IS_ZERO(d) ? MP_ZPOS : n; + d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n; } LBL_ERR: mp_clear_multi(&ta, &tb, &tq, &q, NULL); - return err; + return res; } #else @@ -89,49 +97,47 @@ LBL_ERR: * The overall algorithm is as described as * 14.20 from HAC but fixed to treat these cases. */ -mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) +int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) { mp_int q, x, y, t1, t2; - int n, t, i, norm; - mp_sign neg; - mp_err err; + int res, n, t, i, norm, neg; /* is divisor zero ? */ - if (MP_IS_ZERO(b)) { + if (mp_iszero(b) == MP_YES) { return MP_VAL; } /* if a < b then q=0, r = a */ if (mp_cmp_mag(a, b) == MP_LT) { if (d != NULL) { - err = mp_copy(a, d); + res = mp_copy(a, d); } else { - err = MP_OKAY; + res = MP_OKAY; } if (c != NULL) { mp_zero(c); } - return err; + return res; } - if ((err = mp_init_size(&q, a->used + 2)) != MP_OKAY) { - return err; + if ((res = mp_init_size(&q, a->used + 2)) != MP_OKAY) { + return res; } q.used = a->used + 2; - if ((err = mp_init(&t1)) != MP_OKAY) { + if ((res = mp_init(&t1)) != MP_OKAY) { goto LBL_Q; } - if ((err = mp_init(&t2)) != MP_OKAY) { + if ((res = mp_init(&t2)) != MP_OKAY) { goto LBL_T1; } - if ((err = mp_init_copy(&x, a)) != MP_OKAY) { + if ((res = mp_init_copy(&x, a)) != MP_OKAY) { goto LBL_T2; } - if ((err = mp_init_copy(&y, b)) != MP_OKAY) { + if ((res = mp_init_copy(&y, b)) != MP_OKAY) { goto LBL_X; } @@ -139,14 +145,14 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; x.sign = y.sign = MP_ZPOS; - /* normalize both x and y, ensure that y >= b/2, [b == 2**MP_DIGIT_BIT] */ - norm = mp_count_bits(&y) % MP_DIGIT_BIT; - if (norm < (MP_DIGIT_BIT - 1)) { - norm = (MP_DIGIT_BIT - 1) - norm; - if ((err = mp_mul_2d(&x, norm, &x)) != MP_OKAY) { + /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ + norm = mp_count_bits(&y) % DIGIT_BIT; + if (norm < (DIGIT_BIT - 1)) { + norm = (DIGIT_BIT - 1) - norm; + if ((res = mp_mul_2d(&x, norm, &x)) != MP_OKAY) { goto LBL_Y; } - if ((err = mp_mul_2d(&y, norm, &y)) != MP_OKAY) { + if ((res = mp_mul_2d(&y, norm, &y)) != MP_OKAY) { goto LBL_Y; } } else { @@ -158,13 +164,13 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) t = y.used - 1; /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ - if ((err = mp_lshd(&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ + if ((res = mp_lshd(&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */ goto LBL_Y; } while (mp_cmp(&x, &y) != MP_LT) { ++(q.dp[n - t]); - if ((err = mp_sub(&x, &y, &x)) != MP_OKAY) { + if ((res = mp_sub(&x, &y, &x)) != MP_OKAY) { goto LBL_Y; } } @@ -181,10 +187,10 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) /* step 3.1 if xi == yt then set q{i-t-1} to b-1, * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ if (x.dp[i] == y.dp[t]) { - q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)MP_DIGIT_BIT) - (mp_digit)1; + q.dp[(i - t) - 1] = ((mp_digit)1 << (mp_digit)DIGIT_BIT) - (mp_digit)1; } else { mp_word tmp; - tmp = (mp_word)x.dp[i] << (mp_word)MP_DIGIT_BIT; + tmp = (mp_word)x.dp[i] << (mp_word)DIGIT_BIT; tmp |= (mp_word)x.dp[i - 1]; tmp /= (mp_word)y.dp[t]; if (tmp > (mp_word)MP_MASK) { @@ -207,39 +213,39 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) t1.dp[0] = ((t - 1) < 0) ? 0u : y.dp[t - 1]; t1.dp[1] = y.dp[t]; t1.used = 2; - if ((err = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { + if ((res = mp_mul_d(&t1, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { goto LBL_Y; } /* find right hand */ t2.dp[0] = ((i - 2) < 0) ? 0u : x.dp[i - 2]; - t2.dp[1] = x.dp[i - 1]; /* i >= 1 always holds */ + t2.dp[1] = ((i - 1) < 0) ? 0u : x.dp[i - 1]; t2.dp[2] = x.dp[i]; t2.used = 3; } while (mp_cmp_mag(&t1, &t2) == MP_GT); /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ - if ((err = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { + if ((res = mp_mul_d(&y, q.dp[(i - t) - 1], &t1)) != MP_OKAY) { goto LBL_Y; } - if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) { + if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) { goto LBL_Y; } - if ((err = mp_sub(&x, &t1, &x)) != MP_OKAY) { + if ((res = mp_sub(&x, &t1, &x)) != MP_OKAY) { goto LBL_Y; } /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ if (x.sign == MP_NEG) { - if ((err = mp_copy(&y, &t1)) != MP_OKAY) { + if ((res = mp_copy(&y, &t1)) != MP_OKAY) { goto LBL_Y; } - if ((err = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) { + if ((res = mp_lshd(&t1, (i - t) - 1)) != MP_OKAY) { goto LBL_Y; } - if ((err = mp_add(&x, &t1, &x)) != MP_OKAY) { + if ((res = mp_add(&x, &t1, &x)) != MP_OKAY) { goto LBL_Y; } @@ -261,13 +267,13 @@ mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) } if (d != NULL) { - if ((err = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) { + if ((res = mp_div_2d(&x, norm, &x, NULL)) != MP_OKAY) { goto LBL_Y; } mp_exch(&x, d); } - err = MP_OKAY; + res = MP_OKAY; LBL_Y: mp_clear(&y); @@ -279,9 +285,13 @@ LBL_T1: mp_clear(&t1); LBL_Q: mp_clear(&q); - return err; + return res; } #endif #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_div_2.c b/src/ltm/bn_mp_div_2.c index 2561e5aa..e679d00a 100644 --- a/src/ltm/bn_mp_div_2.c +++ b/src/ltm/bn_mp_div_2.c @@ -1,18 +1,26 @@ #include "tommath_private.h" #ifdef BN_MP_DIV_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* b = a/2 */ -mp_err mp_div_2(const mp_int *a, mp_int *b) +int mp_div_2(const mp_int *a, mp_int *b) { - int x, oldused; - mp_err err; + int x, res, oldused; /* copy */ if (b->alloc < a->used) { - if ((err = mp_grow(b, a->used)) != MP_OKAY) { - return err; + if ((res = mp_grow(b, a->used)) != MP_OKAY) { + return res; } } @@ -34,17 +42,24 @@ mp_err mp_div_2(const mp_int *a, mp_int *b) rr = *tmpa & 1u; /* shift the current digit, add in carry and store */ - *tmpb-- = (*tmpa-- >> 1) | (r << (MP_DIGIT_BIT - 1)); + *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); /* forward carry to next iteration */ r = rr; } /* zero excess digits */ - MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used); + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } } b->sign = a->sign; mp_clamp(b); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_div_2d.c b/src/ltm/bn_mp_div_2d.c index c47d5ce3..912faaf7 100644 --- a/src/ltm/bn_mp_div_2d.c +++ b/src/ltm/bn_mp_div_2d.c @@ -1,44 +1,52 @@ #include "tommath_private.h" #ifdef BN_MP_DIV_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* shift right by a certain bit count (store quotient in c, optional remainder in d) */ -mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) +int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) { mp_digit D, r, rr; - int x; - mp_err err; + int x, res; /* if the shift count is <= 0 then we do no work */ if (b <= 0) { - err = mp_copy(a, c); + res = mp_copy(a, c); if (d != NULL) { mp_zero(d); } - return err; + return res; } /* copy */ - if ((err = mp_copy(a, c)) != MP_OKAY) { - return err; + if ((res = mp_copy(a, c)) != MP_OKAY) { + return res; } /* 'a' should not be used after here - it might be the same as d */ /* get the remainder */ if (d != NULL) { - if ((err = mp_mod_2d(a, b, d)) != MP_OKAY) { - return err; + if ((res = mp_mod_2d(a, b, d)) != MP_OKAY) { + return res; } } /* shift by as many digits in the bit count */ - if (b >= MP_DIGIT_BIT) { - mp_rshd(c, b / MP_DIGIT_BIT); + if (b >= DIGIT_BIT) { + mp_rshd(c, b / DIGIT_BIT); } - /* shift any bit count < MP_DIGIT_BIT */ - D = (mp_digit)(b % MP_DIGIT_BIT); + /* shift any bit count < DIGIT_BIT */ + D = (mp_digit)(b % DIGIT_BIT); if (D != 0u) { mp_digit *tmpc, mask, shift; @@ -46,7 +54,7 @@ mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) mask = ((mp_digit)1 << D) - 1uL; /* shift for lsb */ - shift = (mp_digit)MP_DIGIT_BIT - D; + shift = (mp_digit)DIGIT_BIT - D; /* alias */ tmpc = c->dp + (c->used - 1); @@ -69,3 +77,7 @@ mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_div_3.c b/src/ltm/bn_mp_div_3.c index 3a23fdff..33a34322 100644 --- a/src/ltm/bn_mp_div_3.c +++ b/src/ltm/bn_mp_div_3.c @@ -1,33 +1,41 @@ #include "tommath_private.h" #ifdef BN_MP_DIV_3_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* divide by three (based on routine from MPI and the GMP manual) */ -mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) +int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) { mp_int q; mp_word w, t; mp_digit b; - mp_err err; - int ix; + int res, ix; - /* b = 2**MP_DIGIT_BIT / 3 */ - b = ((mp_word)1 << (mp_word)MP_DIGIT_BIT) / (mp_word)3; + /* b = 2**DIGIT_BIT / 3 */ + b = ((mp_word)1 << (mp_word)DIGIT_BIT) / (mp_word)3; - if ((err = mp_init_size(&q, a->used)) != MP_OKAY) { - return err; + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; } q.used = a->used; q.sign = a->sign; w = 0; for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix]; + w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix]; if (w >= 3u) { /* multiply w by [1/3] */ - t = (w * (mp_word)b) >> (mp_word)MP_DIGIT_BIT; + t = (w * (mp_word)b) >> (mp_word)DIGIT_BIT; /* now subtract 3 * [w/3] from w, to get the remainder */ w -= t+t+t; @@ -57,7 +65,11 @@ mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) } mp_clear(&q); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_div_d.c b/src/ltm/bn_mp_div_d.c index 569f5940..d30ce33a 100644 --- a/src/ltm/bn_mp_div_d.c +++ b/src/ltm/bn_mp_div_d.c @@ -1,16 +1,42 @@ #include "tommath_private.h" #ifdef BN_MP_DIV_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +static int s_is_power_of_two(mp_digit b, int *p) +{ + int x; + + /* fast return if no power of two */ + if ((b == 0u) || ((b & (b-1u)) != 0u)) { + return 0; + } + + for (x = 0; x < DIGIT_BIT; x++) { + if (b == ((mp_digit)1<<(mp_digit)x)) { + *p = x; + return 1; + } + } + return 0; +} /* single digit division (based on routine from MPI) */ -mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) +int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) { mp_int q; mp_word w; mp_digit t; - mp_err err; - int ix; + int res, ix; /* cannot divide by zero */ if (b == 0u) { @@ -18,7 +44,7 @@ mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) } /* quick outs */ - if ((b == 1u) || MP_IS_ZERO(a)) { + if ((b == 1u) || (mp_iszero(a) == MP_YES)) { if (d != NULL) { *d = 0; } @@ -29,11 +55,7 @@ mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) } /* power of two ? */ - if ((b & (b-1)) == 0u) { - ix = 1; - while ((ix < MP_DIGIT_BIT) && (b != (((mp_digit)1)<<ix))) { - ix++; - } + if (s_is_power_of_two(b, &ix) == 1) { if (d != NULL) { *d = a->dp[0] & (((mp_digit)1<<(mp_digit)ix) - 1uL); } @@ -51,15 +73,15 @@ mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) #endif /* no easy answer [c'est la vie]. Just division */ - if ((err = mp_init_size(&q, a->used)) != MP_OKAY) { - return err; + if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { + return res; } q.used = a->used; q.sign = a->sign; w = 0; for (ix = a->used - 1; ix >= 0; ix--) { - w = (w << (mp_word)MP_DIGIT_BIT) | (mp_word)a->dp[ix]; + w = (w << (mp_word)DIGIT_BIT) | (mp_word)a->dp[ix]; if (w >= b) { t = (mp_digit)(w / b); @@ -80,7 +102,11 @@ mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) } mp_clear(&q); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_dr_is_modulus.c b/src/ltm/bn_mp_dr_is_modulus.c index 83760eac..4d0c8ce2 100644 --- a/src/ltm/bn_mp_dr_is_modulus.c +++ b/src/ltm/bn_mp_dr_is_modulus.c @@ -1,16 +1,25 @@ #include "tommath_private.h" #ifdef BN_MP_DR_IS_MODULUS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* determines if a number is a valid DR modulus */ -mp_bool mp_dr_is_modulus(const mp_int *a) +int mp_dr_is_modulus(const mp_int *a) { int ix; /* must be at least two digits */ if (a->used < 2) { - return MP_NO; + return 0; } /* must be of the form b**k - a [a <= b] so all @@ -18,10 +27,14 @@ mp_bool mp_dr_is_modulus(const mp_int *a) */ for (ix = 1; ix < a->used; ix++) { if (a->dp[ix] != MP_MASK) { - return MP_NO; + return 0; } } - return MP_YES; + return 1; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_dr_reduce.c b/src/ltm/bn_mp_dr_reduce.c index ffc33a6b..da24d17a 100644 --- a/src/ltm/bn_mp_dr_reduce.c +++ b/src/ltm/bn_mp_dr_reduce.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_DR_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* reduce "x" in place modulo "n" using the Diminished Radix algorithm. * @@ -17,10 +26,9 @@ * * Input x must be in the range 0 <= x <= (n-1)**2 */ -mp_err mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k) +int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k) { - mp_err err; - int i, m; + int err, i, m; mp_word r; mp_digit mu, *tmpx1, *tmpx2; @@ -52,14 +60,16 @@ top: for (i = 0; i < m; i++) { r = ((mp_word)*tmpx2++ * (mp_word)k) + *tmpx1 + mu; *tmpx1++ = (mp_digit)(r & MP_MASK); - mu = (mp_digit)(r >> ((mp_word)MP_DIGIT_BIT)); + mu = (mp_digit)(r >> ((mp_word)DIGIT_BIT)); } /* set final carry */ *tmpx1++ = mu; /* zero words above m */ - MP_ZERO_DIGITS(tmpx1, (x->used - m) - 1); + for (i = m + 1; i < x->used; i++) { + *tmpx1++ = 0; + } /* clamp, sub and return */ mp_clamp(x); @@ -76,3 +86,7 @@ top: return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_dr_setup.c b/src/ltm/bn_mp_dr_setup.c index 32d5f389..f8c7e7e3 100644 --- a/src/ltm/bn_mp_dr_setup.c +++ b/src/ltm/bn_mp_dr_setup.c @@ -1,15 +1,28 @@ #include "tommath_private.h" #ifdef BN_MP_DR_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* determines the setup value */ void mp_dr_setup(const mp_int *a, mp_digit *d) { - /* the casts are required if MP_DIGIT_BIT is one less than - * the number of bits in a mp_digit [e.g. MP_DIGIT_BIT==31] + /* the casts are required if DIGIT_BIT is one less than + * the number of bits in a mp_digit [e.g. DIGIT_BIT==31] */ - *d = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - (mp_word)a->dp[0]); + *d = (mp_digit)(((mp_word)1 << (mp_word)DIGIT_BIT) - (mp_word)a->dp[0]); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_error_to_string.c b/src/ltm/bn_mp_error_to_string.c deleted file mode 100644 index e936ec17..00000000 --- a/src/ltm/bn_mp_error_to_string.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_ERROR_TO_STRING_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* return a char * string for a given code */ -const char *mp_error_to_string(mp_err code) -{ - switch (code) { - case MP_OKAY: - return "Successful"; - case MP_ERR: - return "Unknown error"; - case MP_MEM: - return "Out of heap"; - case MP_VAL: - return "Value out of range"; - case MP_ITER: - return "Max. iterations reached"; - default: - return "Invalid error code"; - } -} - -#endif diff --git a/src/ltm/bn_mp_exch.c b/src/ltm/bn_mp_exch.c index 552094c6..2f338774 100644 --- a/src/ltm/bn_mp_exch.c +++ b/src/ltm/bn_mp_exch.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_EXCH_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* swap the elements of two integers, for cases where you can't simply swap the * mp_int pointers around @@ -15,3 +24,7 @@ void mp_exch(mp_int *a, mp_int *b) *b = t; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_export.c b/src/ltm/bn_mp_export.c index c9de48b8..ea48e909 100644 --- a/src/ltm/bn_mp_export.c +++ b/src/ltm/bn_mp_export.c @@ -1,22 +1,31 @@ #include "tommath_private.h" #ifdef BN_MP_EXPORT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * 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) +int mp_export(void *rop, size_t *countp, int order, size_t size, + int endian, size_t nails, const mp_int *op) { - mp_err err; + int result; size_t odd_nails, nail_bytes, i, j, bits, count; unsigned char odd_nail_mask; mp_int t; - if ((err = mp_init_copy(&t, op)) != MP_OKAY) { - return err; + if ((result = mp_init_copy(&t, op)) != MP_OKAY) { + return result; } if (endian == 0) { @@ -52,9 +61,9 @@ mp_err mp_export(void *rop, size_t *countp, int order, size_t size, *byte = (unsigned char)((j == ((size - nail_bytes) - 1u)) ? (t.dp[0] & odd_nail_mask) : (t.dp[0] & 0xFFuL)); - if ((err = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) { + if ((result = mp_div_2d(&t, (j == ((size - nail_bytes) - 1u)) ? (int)(8u - odd_nails) : 8, &t, NULL)) != MP_OKAY) { mp_clear(&t); - return err; + return result; } } } @@ -69,3 +78,7 @@ mp_err mp_export(void *rop, size_t *countp, int order, size_t size, } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_expt_d.c b/src/ltm/bn_mp_expt_d.c index ce471f18..e0df09c8 100644 --- a/src/ltm/bn_mp_expt_d.c +++ b/src/ltm/bn_mp_expt_d.c @@ -1,45 +1,25 @@ #include "tommath_private.h" #ifdef BN_MP_EXPT_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* calculate c = a**b using a square-multiply algorithm */ -mp_err mp_expt_d(const mp_int *a, mp_digit b, mp_int *c) +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* wrapper function for mp_expt_d_ex() */ +int mp_expt_d(const mp_int *a, mp_digit b, mp_int *c) { - mp_err err; - - mp_int g; - - if ((err = mp_init_copy(&g, a)) != MP_OKAY) { - return err; - } - - /* set initial result */ - mp_set(c, 1uL); - - while (b > 0u) { - /* if the bit is set multiply */ - if ((b & 1u) != 0u) { - if ((err = mp_mul(c, &g, c)) != MP_OKAY) { - mp_clear(&g); - return err; - } - } - - /* square */ - if (b > 1u) { - if ((err = mp_sqr(&g, &g)) != MP_OKAY) { - mp_clear(&g); - return err; - } - } - - /* shift to next bit */ - b >>= 1; - } - - mp_clear(&g); - return MP_OKAY; + return mp_expt_d_ex(a, b, c, 0); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_expt_d_ex.c b/src/ltm/bn_mp_expt_d_ex.c new file mode 100644 index 00000000..5a6f7b2f --- /dev/null +++ b/src/ltm/bn_mp_expt_d_ex.c @@ -0,0 +1,79 @@ +#include "tommath_private.h" +#ifdef BN_MP_EXPT_D_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* calculate c = a**b using a square-multiply algorithm */ +int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) +{ + int res; + unsigned int x; + + mp_int g; + + if ((res = mp_init_copy(&g, a)) != MP_OKAY) { + return res; + } + + /* set initial result */ + mp_set(c, 1uL); + + if (fast != 0) { + while (b > 0u) { + /* if the bit is set multiply */ + if ((b & 1u) != 0u) { + if ((res = mp_mul(c, &g, c)) != MP_OKAY) { + mp_clear(&g); + return res; + } + } + + /* square */ + if (b > 1u) { + if ((res = mp_sqr(&g, &g)) != MP_OKAY) { + mp_clear(&g); + return res; + } + } + + /* shift to next bit */ + b >>= 1; + } + } else { + for (x = 0; x < (unsigned)DIGIT_BIT; x++) { + /* square */ + if ((res = mp_sqr(c, c)) != MP_OKAY) { + mp_clear(&g); + return res; + } + + /* if the bit is set multiply */ + if ((b & ((mp_digit)1 << (DIGIT_BIT - 1))) != 0u) { + if ((res = mp_mul(c, &g, c)) != MP_OKAY) { + mp_clear(&g); + return res; + } + } + + /* shift to next bit */ + b <<= 1; + } + } /* if ... else */ + + mp_clear(&g); + return MP_OKAY; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_exptmod.c b/src/ltm/bn_mp_exptmod.c index 95a1dcb6..c400b7eb 100644 --- a/src/ltm/bn_mp_exptmod.c +++ b/src/ltm/bn_mp_exptmod.c @@ -1,14 +1,24 @@ #include "tommath_private.h" #ifdef BN_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + /* this is a shell function that calls either the normal or Montgomery * exptmod functions. Originally the call to the montgomery code was * embedded in the normal function but that wasted alot of stack space * for nothing (since 99% of the time the Montgomery code would be called) */ -mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) +int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) { int dr; @@ -21,7 +31,7 @@ mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) if (X->sign == MP_NEG) { #ifdef BN_MP_INVMOD_C mp_int tmpG, tmpX; - mp_err err; + int err; /* first compute 1/G mod P */ if ((err = mp_init(&tmpG)) != MP_OKAY) { @@ -61,7 +71,7 @@ mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) #ifdef BN_MP_DR_IS_MODULUS_C /* is it a DR modulus? */ - dr = (mp_dr_is_modulus(P) == MP_YES) ? 1 : 0; + dr = mp_dr_is_modulus(P); #else /* default to no */ dr = 0; @@ -70,14 +80,14 @@ mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) #ifdef BN_MP_REDUCE_IS_2K_C /* if not, is it a unrestricted DR modulus? */ if (dr == 0) { - dr = (mp_reduce_is_2k(P) == MP_YES) ? 2 : 0; + dr = mp_reduce_is_2k(P) << 1; } #endif /* if the modulus is odd or dr != 0 use the montgomery method */ -#ifdef BN_S_MP_EXPTMOD_FAST_C - if (MP_IS_ODD(P) || (dr != 0)) { - return s_mp_exptmod_fast(G, X, P, Y, dr); +#ifdef BN_MP_EXPTMOD_FAST_C + if ((mp_isodd(P) == MP_YES) || (dr != 0)) { + return mp_exptmod_fast(G, X, P, Y, dr); } else { #endif #ifdef BN_S_MP_EXPTMOD_C @@ -87,9 +97,13 @@ mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) /* no exptmod for evens */ return MP_VAL; #endif -#ifdef BN_S_MP_EXPTMOD_FAST_C +#ifdef BN_MP_EXPTMOD_FAST_C } #endif } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_exptmod_fast.c b/src/ltm/bn_mp_exptmod_fast.c index 43a2ba11..4de9c5fa 100644 --- a/src/ltm/bn_s_mp_exptmod_fast.c +++ b/src/ltm/bn_mp_exptmod_fast.c @@ -1,7 +1,16 @@ #include "tommath_private.h" -#ifdef BN_S_MP_EXPTMOD_FAST_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_MP_EXPTMOD_FAST_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 * @@ -17,18 +26,17 @@ # define TAB_SIZE 256 #endif -mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) +int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) { mp_int M[TAB_SIZE], res; mp_digit buf, mp; - int bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - mp_err err; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; /* use a pointer to the reduction algorithm. This allows us to use * one of many reduction algorithms without modding the guts of * the code with if statements everywhere. */ - mp_err(*redux)(mp_int *x, const mp_int *n, mp_digit rho); + int (*redux)(mp_int *x, const mp_int *n, mp_digit rho); /* find window size */ x = mp_count_bits(X); @@ -84,10 +92,10 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i #endif /* automatically pick the comba one if available (saves quite a few calls/ifs) */ -#ifdef BN_S_MP_MONTGOMERY_REDUCE_FAST_C - if ((((P->used * 2) + 1) < MP_WARRAY) && - (P->used < MP_MAXFAST)) { - redux = s_mp_montgomery_reduce_fast; +#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C + if ((((P->used * 2) + 1) < (int)MP_WARRAY) && + (P->used < (1 << ((CHAR_BIT * sizeof(mp_word)) - (2 * DIGIT_BIT))))) { + redux = fast_mp_montgomery_reduce; } else #endif { @@ -196,11 +204,11 @@ mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_i } /* read next digit and reset bitcnt */ buf = X->dp[digidx--]; - bitcnt = (int)MP_DIGIT_BIT; + bitcnt = (int)DIGIT_BIT; } /* grab the next msb from the exponent */ - y = (mp_digit)(buf >> (MP_DIGIT_BIT - 1)) & 1uL; + y = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1; buf <<= (mp_digit)1; /* if the bit is zero and mode == 0 then we ignore it @@ -304,3 +312,8 @@ LBL_M: return err; } #endif + + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_exteuclid.c b/src/ltm/bn_mp_exteuclid.c index 3af7467c..c23a6c15 100644 --- a/src/ltm/bn_mp_exteuclid.c +++ b/src/ltm/bn_mp_exteuclid.c @@ -1,15 +1,24 @@ #include "tommath_private.h" #ifdef BN_MP_EXTEUCLID_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* Extended euclidean algorithm of (a, b) produces a*u1 + b*u2 = u3 */ -mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) +int mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) { mp_int u1, u2, u3, v1, v2, v3, t1, t2, t3, q, tmp; - mp_err err; + int err; if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { return err; @@ -28,7 +37,7 @@ mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp } /* loop while v3 != 0 */ - while (!MP_IS_ZERO(&v3)) { + while (mp_iszero(&v3) == MP_NO) { /* q = u3/v3 */ if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto LBL_ERR; @@ -107,3 +116,7 @@ LBL_ERR: return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_fread.c b/src/ltm/bn_mp_fread.c index 52ea773e..9c935cb8 100644 --- a/src/ltm/bn_mp_fread.c +++ b/src/ltm/bn_mp_fread.c @@ -1,17 +1,29 @@ #include "tommath_private.h" #ifdef BN_MP_FREAD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ -#ifndef MP_NO_FILE +#ifndef LTM_NO_FILE /* read a bigint from a file stream in ASCII */ -mp_err mp_fread(mp_int *a, int radix, FILE *stream) +int mp_fread(mp_int *a, int radix, FILE *stream) { - mp_err err; - mp_sign neg; + int err, ch, neg, y; + unsigned pos; + + /* clear a */ + mp_zero(a); /* if first digit is - then set negative */ - int ch = fgetc(stream); + ch = fgetc(stream); if (ch == (int)'-') { neg = MP_NEG; ch = fgetc(stream); @@ -19,17 +31,8 @@ mp_err mp_fread(mp_int *a, int radix, FILE *stream) neg = MP_ZPOS; } - /* no digits, return error */ - if (ch == EOF) { - return MP_ERR; - } - - /* clear a */ - mp_zero(a); - - do { - int y; - unsigned pos = (unsigned)(ch - (int)'('); + for (;;) { + pos = (unsigned)(ch - (int)'('); if (mp_s_rmap_reverse_sz < pos) { break; } @@ -47,9 +50,10 @@ mp_err mp_fread(mp_int *a, int radix, FILE *stream) if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { return err; } - } while ((ch = fgetc(stream)) != EOF); - if (a->used != 0) { + ch = fgetc(stream); + } + if (mp_cmp_d(a, 0uL) != MP_EQ) { a->sign = neg; } @@ -58,3 +62,7 @@ mp_err mp_fread(mp_int *a, int radix, FILE *stream) #endif #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_fwrite.c b/src/ltm/bn_mp_fwrite.c index 2a597555..9f0c3dfa 100644 --- a/src/ltm/bn_mp_fwrite.c +++ b/src/ltm/bn_mp_fwrite.c @@ -1,37 +1,51 @@ #include "tommath_private.h" #ifdef BN_MP_FWRITE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ -#ifndef MP_NO_FILE -mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) +#ifndef LTM_NO_FILE +int mp_fwrite(const mp_int *a, int radix, FILE *stream) { char *buf; - mp_err err; - int len; + int err, len, x; if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) { return err; } - buf = (char *) MP_MALLOC((size_t)len); + buf = OPT_CAST(char) XMALLOC((size_t)len); if (buf == NULL) { return MP_MEM; } if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) { - MP_FREE_BUFFER(buf, (size_t)len); + XFREE(buf); return err; } - if (fwrite(buf, (size_t)len, 1uL, stream) != 1uL) { - MP_FREE_BUFFER(buf, (size_t)len); - return MP_ERR; + for (x = 0; x < len; x++) { + if (fputc((int)buf[x], stream) == EOF) { + XFREE(buf); + return MP_VAL; + } } - MP_FREE_BUFFER(buf, (size_t)len); + XFREE(buf); return MP_OKAY; } #endif #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_gcd.c b/src/ltm/bn_mp_gcd.c index 53029baf..05030c2d 100644 --- a/src/ltm/bn_mp_gcd.c +++ b/src/ltm/bn_mp_gcd.c @@ -1,29 +1,37 @@ #include "tommath_private.h" #ifdef BN_MP_GCD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* Greatest Common Divisor using the binary method */ -mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c) +int mp_gcd(const mp_int *a, const mp_int *b, mp_int *c) { mp_int u, v; - int k, u_lsb, v_lsb; - mp_err err; + int k, u_lsb, v_lsb, res; /* either zero than gcd is the largest */ - if (MP_IS_ZERO(a)) { + if (mp_iszero(a) == MP_YES) { return mp_abs(b, c); } - if (MP_IS_ZERO(b)) { + if (mp_iszero(b) == MP_YES) { return mp_abs(a, c); } /* get copies of a and b we can modify */ - if ((err = mp_init_copy(&u, a)) != MP_OKAY) { - return err; + if ((res = mp_init_copy(&u, a)) != MP_OKAY) { + return res; } - if ((err = mp_init_copy(&v, b)) != MP_OKAY) { + if ((res = mp_init_copy(&v, b)) != MP_OKAY) { goto LBL_U; } @@ -33,33 +41,33 @@ mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c) /* B1. Find the common power of two for u and v */ u_lsb = mp_cnt_lsb(&u); v_lsb = mp_cnt_lsb(&v); - k = MP_MIN(u_lsb, v_lsb); + k = MIN(u_lsb, v_lsb); if (k > 0) { /* divide the power of two out */ - if ((err = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { + if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) { goto LBL_V; } - if ((err = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { + if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) { goto LBL_V; } } /* divide any remaining factors of two out */ if (u_lsb != k) { - if ((err = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { + if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) { goto LBL_V; } } if (v_lsb != k) { - if ((err = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { + if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) { goto LBL_V; } } - while (!MP_IS_ZERO(&v)) { + while (mp_iszero(&v) == MP_NO) { /* make sure v is the largest */ if (mp_cmp_mag(&u, &v) == MP_GT) { /* swap u and v to make sure v is >= u */ @@ -67,26 +75,30 @@ mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c) } /* subtract smallest from largest */ - if ((err = s_mp_sub(&v, &u, &v)) != MP_OKAY) { + if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) { goto LBL_V; } /* Divide out all factors of two */ - if ((err = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { + if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) { goto LBL_V; } } /* multiply by 2**k which we divided out at the beginning */ - if ((err = mp_mul_2d(&u, k, c)) != MP_OKAY) { + if ((res = mp_mul_2d(&u, k, c)) != MP_OKAY) { goto LBL_V; } c->sign = MP_ZPOS; - err = MP_OKAY; + res = MP_OKAY; LBL_V: mp_clear(&u); LBL_U: mp_clear(&v); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_get_bit.c b/src/ltm/bn_mp_get_bit.c new file mode 100644 index 00000000..ab732c43 --- /dev/null +++ b/src/ltm/bn_mp_get_bit.c @@ -0,0 +1,54 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_BIT_C + +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* Checks the bit at position b and returns MP_YES + if the bit is 1, MP_NO if it is 0 and MP_VAL + in case of error */ +int mp_get_bit(const mp_int *a, int b) +{ + int limb; + mp_digit bit, isset; + + if (b < 0) { + return MP_VAL; + } + + limb = b / DIGIT_BIT; + + /* + * Zero is a special value with the member "used" set to zero. + * Needs to be tested before the check for the upper boundary + * otherwise (limb >= a->used) would be true for a = 0 + */ + + if (mp_iszero(a) != MP_NO) { + return MP_NO; + } + + if (limb >= a->used) { + return MP_VAL; + } + + bit = (mp_digit)(1) << (b % DIGIT_BIT); + + isset = a->dp[limb] & bit; + return (isset != 0u) ? MP_YES : MP_NO; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_get_i32.c b/src/ltm/bn_mp_get_i32.c deleted file mode 100644 index d5adee24..00000000 --- a/src/ltm/bn_mp_get_i32.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_GET_I32_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_GET_SIGNED(int, mp_get_i32, mp_get_mag32) -#endif diff --git a/src/ltm/bn_mp_get_i64.c b/src/ltm/bn_mp_get_i64.c deleted file mode 100644 index aa9fc8f4..00000000 --- a/src/ltm/bn_mp_get_i64.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_GET_I64_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_GET_SIGNED(long long, mp_get_i64, mp_get_mag64) -#endif diff --git a/src/ltm/bn_mp_get_int.c b/src/ltm/bn_mp_get_int.c new file mode 100644 index 00000000..13eddbf6 --- /dev/null +++ b/src/ltm/bn_mp_get_int.c @@ -0,0 +1,42 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* get the lower 32-bits of an mp_int */ +unsigned long mp_get_int(const mp_int *a) +{ + int i; + mp_min_u32 res; + + if (a->used == 0) { + return 0; + } + + /* get number of digits of the lsb we have to read */ + i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; + + /* get most significant digit of result */ + res = DIGIT(a, i); + + while (--i >= 0) { + res = (res << DIGIT_BIT) | DIGIT(a, i); + } + + /* force result to 32-bits always so it is consistent on non 32-bit platforms */ + return res & 0xFFFFFFFFUL; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_get_long.c b/src/ltm/bn_mp_get_long.c new file mode 100644 index 00000000..a4d05d61 --- /dev/null +++ b/src/ltm/bn_mp_get_long.c @@ -0,0 +1,42 @@ +#include "tommath_private.h" +#ifdef BN_MP_GET_LONG_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* get the lower unsigned long of an mp_int, platform dependent */ +unsigned long mp_get_long(const mp_int *a) +{ + int i; + unsigned long res; + + if (a->used == 0) { + return 0; + } + + /* get number of digits of the lsb we have to read */ + i = MIN(a->used, ((((int)sizeof(unsigned long) * CHAR_BIT) + DIGIT_BIT - 1) / DIGIT_BIT)) - 1; + + /* get most significant digit of result */ + res = DIGIT(a, i); + +#if (ULONG_MAX != 0xffffffffuL) || (DIGIT_BIT < 32) + while (--i >= 0) { + res = (res << DIGIT_BIT) | DIGIT(a, i); + } +#endif + return res; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_get_mag32.c b/src/ltm/bn_mp_get_mag32.c deleted file mode 100644 index 91140821..00000000 --- a/src/ltm/bn_mp_get_mag32.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_GET_MAG32_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_GET_MAG(unsigned int, mp_get_mag32) -#endif diff --git a/src/ltm/bn_mp_get_mag64.c b/src/ltm/bn_mp_get_mag64.c deleted file mode 100644 index 8cb6a672..00000000 --- a/src/ltm/bn_mp_get_mag64.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_GET_MAG64_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_GET_MAG(unsigned long long, mp_get_mag64) -#endif diff --git a/src/ltm/bn_mp_grow.c b/src/ltm/bn_mp_grow.c index 9e904c54..1d92b297 100644 --- a/src/ltm/bn_mp_grow.c +++ b/src/ltm/bn_mp_grow.c @@ -1,25 +1,35 @@ #include "tommath_private.h" #ifdef BN_MP_GROW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* grow as required */ -mp_err mp_grow(mp_int *a, int size) +int mp_grow(mp_int *a, int size) { int i; mp_digit *tmp; /* if the alloc size is smaller alloc more ram */ if (a->alloc < size) { + /* ensure there are always at least MP_PREC digits extra on top */ + size += (MP_PREC * 2) - (size % MP_PREC); + /* reallocate the array a->dp * * We store the return in a temporary variable * in case the operation failed we don't want * to overwrite the dp member of a. */ - tmp = (mp_digit *) MP_REALLOC(a->dp, - (size_t)a->alloc * sizeof(mp_digit), - (size_t)size * sizeof(mp_digit)); + tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof(mp_digit) * (size_t)size); if (tmp == NULL) { /* reallocation failed but "a" is still valid [can be freed] */ return MP_MEM; @@ -31,8 +41,14 @@ mp_err mp_grow(mp_int *a, int size) /* zero excess digits */ i = a->alloc; a->alloc = size; - MP_ZERO_DIGITS(a->dp + i, a->alloc - i); + for (; i < a->alloc; i++) { + a->dp[i] = 0; + } } return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_ilogb.c b/src/ltm/bn_mp_ilogb.c deleted file mode 100644 index 9ce1eec8..00000000 --- a/src/ltm/bn_mp_ilogb.c +++ /dev/null @@ -1,183 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_ILOGB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* Compute log_{base}(a) */ -static mp_word s_pow(mp_word base, mp_word exponent) -{ - mp_word result = 1uLL; - while (exponent != 0u) { - if ((exponent & 1u) == 1u) { - result *= base; - } - exponent >>= 1; - base *= base; - } - - return result; -} - -static mp_digit s_digit_ilogb(mp_digit base, mp_digit n) -{ - mp_word bracket_low = 1uLL, bracket_mid, bracket_high, N; - mp_digit ret, high = 1uL, low = 0uL, mid; - - if (n < base) { - return 0uL; - } - if (n == base) { - return 1uL; - } - - bracket_high = (mp_word) base ; - N = (mp_word) n; - - while (bracket_high < N) { - low = high; - bracket_low = bracket_high; - high <<= 1; - bracket_high *= bracket_high; - } - - while (((mp_digit)(high - low)) > 1uL) { - mid = (low + high) >> 1; - bracket_mid = bracket_low * s_pow(base, (mp_word)(mid - low)); - - if (N < bracket_mid) { - high = mid ; - bracket_high = bracket_mid ; - } - if (N > bracket_mid) { - low = mid ; - bracket_low = bracket_mid ; - } - if (N == bracket_mid) { - return (mp_digit) mid; - } - } - - if (bracket_high == N) { - ret = high; - } else { - ret = low; - } - - return ret; -} - -/* TODO: output could be "int" because the output of mp_radix_size is int, too, - as is the output of mp_bitcount. - With the same problem: max size is INT_MAX * MP_DIGIT not INT_MAX only! -*/ -mp_err mp_ilogb(const mp_int *a, mp_digit base, mp_int *c) -{ - mp_err err; - mp_ord cmp; - unsigned int high, low, mid; - mp_int bracket_low, bracket_high, bracket_mid, t, bi_base; - - err = MP_OKAY; - if (a->sign == MP_NEG) { - return MP_VAL; - } - if (MP_IS_ZERO(a)) { - return MP_VAL; - } - - if (base < 2u) { - return MP_VAL; - } - if (base == 2u) { - mp_set_u32(c, (unsigned int)(mp_count_bits(a) - 1)); - return err; - } - if (a->used == 1) { - mp_set(c, s_digit_ilogb(base, a->dp[0])); - return err; - } - - cmp = mp_cmp_d(a, base); - - if (cmp == MP_LT) { - mp_zero(c); - return err; - } - if (cmp == MP_EQ) { - mp_set(c, 1uL); - return err; - } - - if ((err = - mp_init_multi(&bracket_low, &bracket_high, - &bracket_mid, &t, &bi_base, NULL)) != MP_OKAY) { - return err; - } - - low = 0u; - mp_set(&bracket_low, 1uL); - high = 1u; - - mp_set(&bracket_high, base); - - /* - A kind of Giant-step/baby-step algorithm. - Idea shamelessly stolen from https://programmingpraxis.com/2010/05/07/integer-logarithms/2/ - The effect is asymptotic, hence needs benchmarks to test if the Giant-step should be skipped - for small n. - */ - while (mp_cmp(&bracket_high, a) == MP_LT) { - low = high; - if ((err = mp_copy(&bracket_high, &bracket_low)) != MP_OKAY) { - goto LBL_ERR; - } - high <<= 1; - if ((err = mp_sqr(&bracket_high, &bracket_high)) != MP_OKAY) { - goto LBL_ERR; - } - } - mp_set(&bi_base, base); - - while ((high - low) > 1u) { - mid = (high + low) >> 1; - /* Difference can be larger then the type behind mp_digit can hold */ - if ((mid - low) > (unsigned int)(MP_MASK)) { - err = MP_VAL; - goto LBL_ERR; - } - if ((err = mp_expt_d(&bi_base, (mp_digit)(mid - low), &t)) != MP_OKAY) { - goto LBL_ERR; - } - if ((err = mp_mul(&bracket_low, &t, &bracket_mid)) != MP_OKAY) { - goto LBL_ERR; - } - cmp = mp_cmp(a, &bracket_mid); - if (cmp == MP_LT) { - high = mid; - mp_exch(&bracket_mid, &bracket_high); - } - if (cmp == MP_GT) { - low = mid; - mp_exch(&bracket_mid, &bracket_low); - } - if (cmp == MP_EQ) { - mp_set_u32(c, mid); - goto LBL_END; - } - } - - if (mp_cmp(&bracket_high, a) == MP_EQ) { - mp_set_u32(c, high); - } else { - mp_set_u32(c, low); - } - -LBL_END: -LBL_ERR: - mp_clear_multi(&bracket_low, &bracket_high, &bracket_mid, - &t, &bi_base, NULL); - return err; -} - - -#endif diff --git a/src/ltm/bn_mp_import.c b/src/ltm/bn_mp_import.c index bd83b96c..066c5b3b 100644 --- a/src/ltm/bn_mp_import.c +++ b/src/ltm/bn_mp_import.c @@ -1,15 +1,24 @@ #include "tommath_private.h" #ifdef BN_MP_IMPORT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * 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) +int mp_import(mp_int *rop, size_t count, int order, size_t size, + int endian, size_t nails, const void *op) { - mp_err err; + int result; size_t odd_nails, nail_bytes, i, j; unsigned char odd_nail_mask; @@ -34,12 +43,12 @@ 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 + + unsigned char byte = *((unsigned char *)op + (((order == 1) ? i : ((count - 1u) - i)) * size) + ((endian == 1) ? (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; + if ((result = mp_mul_2d(rop, (j == 0u) ? (int)(8u - odd_nails) : 8, rop)) != MP_OKAY) { + return result; } rop->dp[0] |= (j == 0u) ? (mp_digit)(byte & odd_nail_mask) : (mp_digit)byte; @@ -53,3 +62,7 @@ mp_err mp_import(mp_int *rop, size_t count, int order, size_t size, } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_incr.c b/src/ltm/bn_mp_incr.c deleted file mode 100644 index 5d0039e0..00000000 --- a/src/ltm/bn_mp_incr.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_INCR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* Increment "a" by one like "a++". Changes input! */ -mp_err mp_incr(mp_int *a) -{ - if (MP_IS_ZERO(a)) { - mp_set(a,1uL); - return MP_OKAY; - } else if (a->sign == MP_NEG) { - mp_err err; - a->sign = MP_ZPOS; - if ((err = mp_decr(a)) != MP_OKAY) { - return err; - } - /* There is no -0 in LTM */ - if (!MP_IS_ZERO(a)) { - a->sign = MP_NEG; - } - return MP_OKAY; - } else if (a->dp[0] < MP_MASK) { - a->dp[0]++; - return MP_OKAY; - } else { - return mp_add_d(a, 1uL,a); - } -} -#endif diff --git a/src/ltm/bn_mp_init.c b/src/ltm/bn_mp_init.c index 2eb79240..75200893 100644 --- a/src/ltm/bn_mp_init.c +++ b/src/ltm/bn_mp_init.c @@ -1,17 +1,33 @@ #include "tommath_private.h" #ifdef BN_MP_INIT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* init a new mp_int */ -mp_err mp_init(mp_int *a) +int mp_init(mp_int *a) { + int i; + /* allocate memory required and clear it */ - a->dp = (mp_digit *) MP_CALLOC((size_t)MP_PREC, sizeof(mp_digit)); + a->dp = OPT_CAST(mp_digit) XMALLOC(sizeof(mp_digit) * (size_t)MP_PREC); if (a->dp == NULL) { return MP_MEM; } + /* set the digits to zero */ + for (i = 0; i < MP_PREC; i++) { + a->dp[i] = 0; + } + /* set the used to zero, allocated digits to the default precision * and sign to positive */ a->used = 0; @@ -21,3 +37,7 @@ mp_err mp_init(mp_int *a) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_init_copy.c b/src/ltm/bn_mp_init_copy.c index 1888203d..4739a981 100644 --- a/src/ltm/bn_mp_init_copy.c +++ b/src/ltm/bn_mp_init_copy.c @@ -1,21 +1,34 @@ #include "tommath_private.h" #ifdef BN_MP_INIT_COPY_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* creates "a" then copies b into it */ -mp_err mp_init_copy(mp_int *a, const mp_int *b) +int mp_init_copy(mp_int *a, const mp_int *b) { - mp_err err; + int res; - if ((err = mp_init_size(a, b->used)) != MP_OKAY) { - return err; + if ((res = mp_init_size(a, b->used)) != MP_OKAY) { + return res; } - if ((err = mp_copy(b, a)) != MP_OKAY) { + if ((res = mp_copy(b, a)) != MP_OKAY) { mp_clear(a); } - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_init_i32.c b/src/ltm/bn_mp_init_i32.c deleted file mode 100644 index 9c67003c..00000000 --- a/src/ltm/bn_mp_init_i32.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_INIT_I32_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_INIT_INT(mp_init_i32, mp_set_i32, int) -#endif diff --git a/src/ltm/bn_mp_init_i64.c b/src/ltm/bn_mp_init_i64.c deleted file mode 100644 index e1a10e99..00000000 --- a/src/ltm/bn_mp_init_i64.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_INIT_I64_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_INIT_INT(mp_init_i64, mp_set_i64, long long) -#endif diff --git a/src/ltm/bn_mp_init_multi.c b/src/ltm/bn_mp_init_multi.c index d8390b5a..7f8bd040 100644 --- a/src/ltm/bn_mp_init_multi.c +++ b/src/ltm/bn_mp_init_multi.c @@ -1,13 +1,22 @@ #include "tommath_private.h" #ifdef BN_MP_INIT_MULTI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ #include <stdarg.h> -mp_err mp_init_multi(mp_int *mp, ...) +int mp_init_multi(mp_int *mp, ...) { - mp_err err = MP_OKAY; /* Assume ok until proven otherwise */ + mp_err res = MP_OKAY; /* Assume ok until proven otherwise */ int n = 0; /* Number of ok inits */ mp_int *cur_arg = mp; va_list args; @@ -28,14 +37,18 @@ mp_err mp_init_multi(mp_int *mp, ...) cur_arg = va_arg(clean_args, mp_int *); } va_end(clean_args); - err = MP_MEM; + res = MP_MEM; break; } n++; cur_arg = va_arg(args, mp_int *); } va_end(args); - return err; /* Assumed ok, if error flagged above. */ + return res; /* Assumed ok, if error flagged above. */ } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_init_set.c b/src/ltm/bn_mp_init_set.c index 5068f2bf..36606af8 100644 --- a/src/ltm/bn_mp_init_set.c +++ b/src/ltm/bn_mp_init_set.c @@ -1,12 +1,21 @@ #include "tommath_private.h" #ifdef BN_MP_INIT_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* initialize and set a digit */ -mp_err mp_init_set(mp_int *a, mp_digit b) +int mp_init_set(mp_int *a, mp_digit b) { - mp_err err; + int err; if ((err = mp_init(a)) != MP_OKAY) { return err; } @@ -14,3 +23,7 @@ mp_err mp_init_set(mp_int *a, mp_digit b) return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_init_set_int.c b/src/ltm/bn_mp_init_set_int.c new file mode 100644 index 00000000..7d818119 --- /dev/null +++ b/src/ltm/bn_mp_init_set_int.c @@ -0,0 +1,28 @@ +#include "tommath_private.h" +#ifdef BN_MP_INIT_SET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* initialize and set a digit */ +int mp_init_set_int(mp_int *a, unsigned long b) +{ + int err; + if ((err = mp_init(a)) != MP_OKAY) { + return err; + } + return mp_set_int(a, b); +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_init_size.c b/src/ltm/bn_mp_init_size.c index d6226872..9b933fbd 100644 --- a/src/ltm/bn_mp_init_size.c +++ b/src/ltm/bn_mp_init_size.c @@ -1,15 +1,27 @@ #include "tommath_private.h" #ifdef BN_MP_INIT_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* init an mp_init for a given size */ -mp_err mp_init_size(mp_int *a, int size) +int mp_init_size(mp_int *a, int size) { - size = MP_MAX(MP_MIN_PREC, size); + int x; + + /* pad size so there are always extra digits */ + size += (MP_PREC * 2) - (size % MP_PREC); /* alloc mem */ - a->dp = (mp_digit *) MP_CALLOC((size_t)size, sizeof(mp_digit)); + a->dp = OPT_CAST(mp_digit) XMALLOC(sizeof(mp_digit) * (size_t)size); if (a->dp == NULL) { return MP_MEM; } @@ -19,6 +31,15 @@ mp_err mp_init_size(mp_int *a, int size) a->alloc = size; a->sign = MP_ZPOS; + /* zero the digits */ + for (x = 0; x < size; x++) { + a->dp[x] = 0; + } + return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_init_u32.c b/src/ltm/bn_mp_init_u32.c deleted file mode 100644 index 17ae536e..00000000 --- a/src/ltm/bn_mp_init_u32.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_INIT_U32_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_INIT_INT(mp_init_u32, mp_set_u32, unsigned int) -#endif diff --git a/src/ltm/bn_mp_init_u64.c b/src/ltm/bn_mp_init_u64.c deleted file mode 100644 index 8c758103..00000000 --- a/src/ltm/bn_mp_init_u64.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_INIT_U64_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_INIT_INT(mp_init_u64, mp_set_u64, unsigned long long) -#endif diff --git a/src/ltm/bn_mp_invmod.c b/src/ltm/bn_mp_invmod.c index d5d6bbc0..f1a482da 100644 --- a/src/ltm/bn_mp_invmod.c +++ b/src/ltm/bn_mp_invmod.c @@ -1,27 +1,40 @@ #include "tommath_private.h" #ifdef BN_MP_INVMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* hac 14.61, pp608 */ -mp_err mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) +int mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) { /* b cannot be negative and has to be >1 */ if ((b->sign == MP_NEG) || (mp_cmp_d(b, 1uL) != MP_GT)) { return MP_VAL; } -#ifdef BN_S_MP_INVMOD_FAST_C +#ifdef BN_FAST_MP_INVMOD_C /* if the modulus is odd we can use a faster routine instead */ - if (MP_IS_ODD(b)) { - return s_mp_invmod_fast(a, b, c); + if ((mp_isodd(b) == MP_YES)) { + return fast_mp_invmod(a, b, c); } #endif -#ifdef BN_S_MP_INVMOD_SLOW_C - return s_mp_invmod_slow(a, b, c); +#ifdef BN_MP_INVMOD_SLOW_C + return mp_invmod_slow(a, b, c); #else return MP_VAL; #endif } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_invmod_slow.c b/src/ltm/bn_mp_invmod_slow.c index faf62213..e60cf04a 100644 --- a/src/ltm/bn_s_mp_invmod_slow.c +++ b/src/ltm/bn_mp_invmod_slow.c @@ -1,44 +1,53 @@ #include "tommath_private.h" -#ifdef BN_S_MP_INVMOD_SLOW_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_MP_INVMOD_SLOW_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* hac 14.61, pp608 */ -mp_err s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) +int mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) { mp_int x, y, u, v, A, B, C, D; - mp_err err; + int res; /* b cannot be negative */ - if ((b->sign == MP_NEG) || MP_IS_ZERO(b)) { + if ((b->sign == MP_NEG) || (mp_iszero(b) == MP_YES)) { return MP_VAL; } /* init temps */ - if ((err = mp_init_multi(&x, &y, &u, &v, + if ((res = mp_init_multi(&x, &y, &u, &v, &A, &B, &C, &D, NULL)) != MP_OKAY) { - return err; + return res; } /* x = a, y = b */ - if ((err = mp_mod(a, b, &x)) != MP_OKAY) { + if ((res = mp_mod(a, b, &x)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(b, &y)) != MP_OKAY) { + if ((res = mp_copy(b, &y)) != MP_OKAY) { goto LBL_ERR; } /* 2. [modified] if x,y are both even then return an error! */ - if (MP_IS_EVEN(&x) && MP_IS_EVEN(&y)) { - err = MP_VAL; + if ((mp_iseven(&x) == MP_YES) && (mp_iseven(&y) == MP_YES)) { + res = MP_VAL; goto LBL_ERR; } /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ - if ((err = mp_copy(&x, &u)) != MP_OKAY) { + if ((res = mp_copy(&x, &u)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_copy(&y, &v)) != MP_OKAY) { + if ((res = mp_copy(&y, &v)) != MP_OKAY) { goto LBL_ERR; } mp_set(&A, 1uL); @@ -46,51 +55,51 @@ mp_err s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) top: /* 4. while u is even do */ - while (MP_IS_EVEN(&u)) { + while (mp_iseven(&u) == MP_YES) { /* 4.1 u = u/2 */ - if ((err = mp_div_2(&u, &u)) != MP_OKAY) { + if ((res = mp_div_2(&u, &u)) != MP_OKAY) { goto LBL_ERR; } /* 4.2 if A or B is odd then */ - if (MP_IS_ODD(&A) || MP_IS_ODD(&B)) { + if ((mp_isodd(&A) == MP_YES) || (mp_isodd(&B) == MP_YES)) { /* A = (A+y)/2, B = (B-x)/2 */ - if ((err = mp_add(&A, &y, &A)) != MP_OKAY) { + if ((res = mp_add(&A, &y, &A)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&B, &x, &B)) != MP_OKAY) { + if ((res = mp_sub(&B, &x, &B)) != MP_OKAY) { goto LBL_ERR; } } /* A = A/2, B = B/2 */ - if ((err = mp_div_2(&A, &A)) != MP_OKAY) { + if ((res = mp_div_2(&A, &A)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_div_2(&B, &B)) != MP_OKAY) { + if ((res = mp_div_2(&B, &B)) != MP_OKAY) { goto LBL_ERR; } } /* 5. while v is even do */ - while (MP_IS_EVEN(&v)) { + while (mp_iseven(&v) == MP_YES) { /* 5.1 v = v/2 */ - if ((err = mp_div_2(&v, &v)) != MP_OKAY) { + if ((res = mp_div_2(&v, &v)) != MP_OKAY) { goto LBL_ERR; } /* 5.2 if C or D is odd then */ - if (MP_IS_ODD(&C) || MP_IS_ODD(&D)) { + if ((mp_isodd(&C) == MP_YES) || (mp_isodd(&D) == MP_YES)) { /* C = (C+y)/2, D = (D-x)/2 */ - if ((err = mp_add(&C, &y, &C)) != MP_OKAY) { + if ((res = mp_add(&C, &y, &C)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&D, &x, &D)) != MP_OKAY) { + if ((res = mp_sub(&D, &x, &D)) != MP_OKAY) { goto LBL_ERR; } } /* C = C/2, D = D/2 */ - if ((err = mp_div_2(&C, &C)) != MP_OKAY) { + if ((res = mp_div_2(&C, &C)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_div_2(&D, &D)) != MP_OKAY) { + if ((res = mp_div_2(&D, &D)) != MP_OKAY) { goto LBL_ERR; } } @@ -98,63 +107,67 @@ top: /* 6. if u >= v then */ if (mp_cmp(&u, &v) != MP_LT) { /* u = u - v, A = A - C, B = B - D */ - if ((err = mp_sub(&u, &v, &u)) != MP_OKAY) { + if ((res = mp_sub(&u, &v, &u)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&A, &C, &A)) != MP_OKAY) { + if ((res = mp_sub(&A, &C, &A)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&B, &D, &B)) != MP_OKAY) { + if ((res = mp_sub(&B, &D, &B)) != MP_OKAY) { goto LBL_ERR; } } else { /* v - v - u, C = C - A, D = D - B */ - if ((err = mp_sub(&v, &u, &v)) != MP_OKAY) { + if ((res = mp_sub(&v, &u, &v)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&C, &A, &C)) != MP_OKAY) { + if ((res = mp_sub(&C, &A, &C)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sub(&D, &B, &D)) != MP_OKAY) { + if ((res = mp_sub(&D, &B, &D)) != MP_OKAY) { goto LBL_ERR; } } /* if not zero goto step 4 */ - if (!MP_IS_ZERO(&u)) + if (mp_iszero(&u) == MP_NO) goto top; /* now a = C, b = D, gcd == g*v */ /* if v != 1 then there is no inverse */ if (mp_cmp_d(&v, 1uL) != MP_EQ) { - err = MP_VAL; + res = MP_VAL; goto LBL_ERR; } /* if its too low */ while (mp_cmp_d(&C, 0uL) == MP_LT) { - if ((err = mp_add(&C, b, &C)) != MP_OKAY) { + if ((res = mp_add(&C, b, &C)) != MP_OKAY) { goto LBL_ERR; } } /* too big */ while (mp_cmp_mag(&C, b) != MP_LT) { - if ((err = mp_sub(&C, b, &C)) != MP_OKAY) { + if ((res = mp_sub(&C, b, &C)) != MP_OKAY) { goto LBL_ERR; } } /* C is now the inverse */ mp_exch(&C, c); - err = MP_OKAY; + res = MP_OKAY; LBL_ERR: mp_clear_multi(&x, &y, &u, &v, &A, &B, &C, &D, NULL); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_is_square.c b/src/ltm/bn_mp_is_square.c index 69e77a21..5363a47d 100644 --- a/src/ltm/bn_mp_is_square.c +++ b/src/ltm/bn_mp_is_square.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_IS_SQUARE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* Check if remainders are possible squares - fast exclude non-squares */ static const char rem_128[128] = { @@ -26,9 +35,9 @@ static const char rem_105[105] = { }; /* Store non-zero to ret if arg is square, and zero if not */ -mp_err mp_is_square(const mp_int *arg, mp_bool *ret) +int mp_is_square(const mp_int *arg, int *ret) { - mp_err err; + int res; mp_digit c; mp_int t; unsigned long r; @@ -40,33 +49,34 @@ mp_err mp_is_square(const mp_int *arg, mp_bool *ret) return MP_VAL; } - if (MP_IS_ZERO(arg)) { + /* digits used? (TSD) */ + if (arg->used == 0) { return MP_OKAY; } - /* First check mod 128 (suppose that MP_DIGIT_BIT is at least 7) */ - if (rem_128[127u & arg->dp[0]] == (char)1) { + /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */ + if (rem_128[127u & DIGIT(arg, 0)] == (char)1) { return MP_OKAY; } /* Next check mod 105 (3*5*7) */ - if ((err = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) { - return err; + if ((res = mp_mod_d(arg, 105uL, &c)) != MP_OKAY) { + return res; } if (rem_105[c] == (char)1) { return MP_OKAY; } - if ((err = mp_init_u32(&t, 11u*13u*17u*19u*23u*29u*31u)) != MP_OKAY) { - return err; + if ((res = mp_init_set_int(&t, 11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) { + return res; } - if ((err = mp_mod(arg, &t, &t)) != MP_OKAY) { + if ((res = mp_mod(arg, &t, &t)) != MP_OKAY) { goto LBL_ERR; } - r = mp_get_u32(&t); + r = mp_get_int(&t); /* Check for other prime modules, note it's not an ERROR but we must - * free "t" so the easiest way is to goto LBL_ERR. We know that err + * free "t" so the easiest way is to goto LBL_ERR. We know that res * is already equal to MP_OKAY from the mp_mod call */ if (((1uL<<(r%11uL)) & 0x5C4uL) != 0uL) goto LBL_ERR; @@ -78,16 +88,20 @@ mp_err mp_is_square(const mp_int *arg, mp_bool *ret) if (((1uL<<(r%31uL)) & 0x6DE2B848uL) != 0uL) goto LBL_ERR; /* Final check - is sqr(sqrt(arg)) == arg ? */ - if ((err = mp_sqrt(arg, &t)) != MP_OKAY) { + if ((res = mp_sqrt(arg, &t)) != MP_OKAY) { goto LBL_ERR; } - if ((err = mp_sqr(&t, &t)) != MP_OKAY) { + if ((res = mp_sqr(&t, &t)) != MP_OKAY) { goto LBL_ERR; } *ret = (mp_cmp_mag(&t, arg) == MP_EQ) ? MP_YES : MP_NO; LBL_ERR: mp_clear(&t); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_iseven.c b/src/ltm/bn_mp_iseven.c deleted file mode 100644 index 5cb96228..00000000 --- a/src/ltm/bn_mp_iseven.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_ISEVEN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -mp_bool mp_iseven(const mp_int *a) -{ - return MP_IS_EVEN(a) ? MP_YES : MP_NO; -} -#endif diff --git a/src/ltm/bn_mp_isodd.c b/src/ltm/bn_mp_isodd.c deleted file mode 100644 index bf17646d..00000000 --- a/src/ltm/bn_mp_isodd.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_ISODD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -mp_bool mp_isodd(const mp_int *a) -{ - return MP_IS_ODD(a) ? MP_YES : MP_NO; -} -#endif diff --git a/src/ltm/bn_mp_jacobi.c b/src/ltm/bn_mp_jacobi.c new file mode 100644 index 00000000..1eb3dd4b --- /dev/null +++ b/src/ltm/bn_mp_jacobi.c @@ -0,0 +1,36 @@ +#include "tommath_private.h" +#ifdef BN_MP_JACOBI_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* computes the jacobi c = (a | n) (or Legendre if n is prime) + * Kept for legacy reasons, please use mp_kronecker() instead + */ +int mp_jacobi(const mp_int *a, const mp_int *n, int *c) +{ + /* if a < 0 return MP_VAL */ + if (mp_isneg(a) == MP_YES) { + return MP_VAL; + } + + /* if n <= 0 return MP_VAL */ + if (mp_cmp_d(n, 0uL) != MP_GT) { + return MP_VAL; + } + + return mp_kronecker(a, n, c); +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_karatsuba_mul.c b/src/ltm/bn_mp_karatsuba_mul.c index 6ef96c77..cb75bcaf 100644 --- a/src/ltm/bn_s_mp_karatsuba_mul.c +++ b/src/ltm/bn_mp_karatsuba_mul.c @@ -1,12 +1,21 @@ #include "tommath_private.h" -#ifdef BN_S_MP_KARATSUBA_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_MP_KARATSUBA_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* c = |a| * |b| using Karatsuba Multiplication using * three half size multiplications * - * Let B represent the radix [e.g. 2**MP_DIGIT_BIT] and + * Let B represent the radix [e.g. 2**DIGIT_BIT] and * let n represent half of the number of digits in * the min(a,b) * @@ -32,14 +41,16 @@ * Generally though the overhead of this method doesn't pay off * until a certain size (N ~ 80) is reached. */ -mp_err s_mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c) +int mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c) { mp_int x0, x1, y0, y1, t1, x0y0, x1y1; - int B; - mp_err err = MP_MEM; /* default the return code to an error */ + int B, err; + + /* default the return code to an error */ + err = MP_MEM; /* min # of digits */ - B = MP_MIN(a->used, b->used); + B = MIN(a->used, b->used); /* now divide in two */ B = B >> 1; @@ -154,3 +165,7 @@ LBL_ERR: return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_karatsuba_sqr.c b/src/ltm/bn_mp_karatsuba_sqr.c index f132d071..c219a377 100644 --- a/src/ltm/bn_s_mp_karatsuba_sqr.c +++ b/src/ltm/bn_mp_karatsuba_sqr.c @@ -1,7 +1,16 @@ #include "tommath_private.h" -#ifdef BN_S_MP_KARATSUBA_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_MP_KARATSUBA_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* Karatsuba squaring, computes b = a*a using three * half size squarings @@ -10,11 +19,12 @@ * is essentially the same algorithm but merely * tuned to perform recursive squarings. */ -mp_err s_mp_karatsuba_sqr(const mp_int *a, mp_int *b) +int mp_karatsuba_sqr(const mp_int *a, mp_int *b) { mp_int x0, x1, t1, t2, x0x0, x1x1; - int B; - mp_err err = MP_MEM; + int B, err; + + err = MP_MEM; /* min # of digits */ B = a->used; @@ -108,3 +118,7 @@ LBL_ERR: return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_kronecker.c b/src/ltm/bn_mp_kronecker.c index 525a8203..a20fa742 100644 --- a/src/ltm/bn_mp_kronecker.c +++ b/src/ltm/bn_mp_kronecker.c @@ -1,8 +1,17 @@ #include "tommath_private.h" #ifdef BN_MP_KRONECKER_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* Kronecker symbol (a|p) @@ -17,41 +26,43 @@ publisher={Springer Science \& Business Media} } */ -mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) +int mp_kronecker(const mp_int *a, const mp_int *p, int *c) { mp_int a1, p1, r; - mp_err err; + + int e = MP_OKAY; int v, k; static const int table[8] = {0, 1, 0, -1, 0, -1, 0, 1}; - if (MP_IS_ZERO(p)) { + if (mp_iszero(p) != MP_NO) { if ((a->used == 1) && (a->dp[0] == 1u)) { *c = 1; + return e; } else { *c = 0; + return e; } - return MP_OKAY; } - if (MP_IS_EVEN(a) && MP_IS_EVEN(p)) { + if ((mp_iseven(a) != MP_NO) && (mp_iseven(p) != MP_NO)) { *c = 0; - return MP_OKAY; + return e; } - if ((err = mp_init_copy(&a1, a)) != MP_OKAY) { - return err; + if ((e = mp_init_copy(&a1, a)) != MP_OKAY) { + return e; } - if ((err = mp_init_copy(&p1, p)) != MP_OKAY) { + if ((e = mp_init_copy(&p1, p)) != MP_OKAY) { goto LBL_KRON_0; } v = mp_cnt_lsb(&p1); - if ((err = mp_div_2d(&p1, v, &p1, NULL)) != MP_OKAY) { + if ((e = mp_div_2d(&p1, v, &p1, NULL)) != MP_OKAY) { goto LBL_KRON_1; } - if ((v & 1) == 0) { + if ((v & 0x1) == 0) { k = 1; } else { k = table[a->dp[0] & 7u]; @@ -64,12 +75,12 @@ mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) } } - if ((err = mp_init(&r)) != MP_OKAY) { + if ((e = mp_init(&r)) != MP_OKAY) { goto LBL_KRON_1; } for (;;) { - if (MP_IS_ZERO(&a1)) { + if (mp_iszero(&a1) != MP_NO) { if (mp_cmp_d(&p1, 1uL) == MP_EQ) { *c = k; goto LBL_KRON; @@ -80,11 +91,11 @@ mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) } v = mp_cnt_lsb(&a1); - if ((err = mp_div_2d(&a1, v, &a1, NULL)) != MP_OKAY) { + if ((e = mp_div_2d(&a1, v, &a1, NULL)) != MP_OKAY) { goto LBL_KRON; } - if ((v & 1) == 1) { + if ((v & 0x1) == 1) { k = k * table[p1.dp[0] & 7u]; } @@ -104,14 +115,14 @@ mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) } } - if ((err = mp_copy(&a1, &r)) != MP_OKAY) { + if ((e = mp_copy(&a1, &r)) != MP_OKAY) { goto LBL_KRON; } r.sign = MP_ZPOS; - if ((err = mp_mod(&p1, &r, &a1)) != MP_OKAY) { + if ((e = mp_mod(&p1, &r, &a1)) != MP_OKAY) { goto LBL_KRON; } - if ((err = mp_copy(&r, &p1)) != MP_OKAY) { + if ((e = mp_copy(&r, &p1)) != MP_OKAY) { goto LBL_KRON; } } @@ -123,7 +134,11 @@ LBL_KRON_1: LBL_KRON_0: mp_clear(&a1); - return err; + return e; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_lcm.c b/src/ltm/bn_mp_lcm.c index c32b269e..cb9fa3d9 100644 --- a/src/ltm/bn_mp_lcm.c +++ b/src/ltm/bn_mp_lcm.c @@ -1,37 +1,46 @@ #include "tommath_private.h" #ifdef BN_MP_LCM_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* computes least common multiple as |a*b|/(a, b) */ -mp_err mp_lcm(const mp_int *a, const mp_int *b, mp_int *c) +int mp_lcm(const mp_int *a, const mp_int *b, mp_int *c) { - mp_err err; + int res; mp_int t1, t2; - if ((err = mp_init_multi(&t1, &t2, NULL)) != MP_OKAY) { - return err; + if ((res = mp_init_multi(&t1, &t2, NULL)) != MP_OKAY) { + return res; } /* t1 = get the GCD of the two inputs */ - if ((err = mp_gcd(a, b, &t1)) != MP_OKAY) { + if ((res = mp_gcd(a, b, &t1)) != MP_OKAY) { goto LBL_T; } /* divide the smallest by the GCD */ if (mp_cmp_mag(a, b) == MP_LT) { /* store quotient in t2 such that t2 * b is the LCM */ - if ((err = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { + if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) { goto LBL_T; } - err = mp_mul(b, &t2, c); + res = mp_mul(b, &t2, c); } else { /* store quotient in t2 such that t2 * a is the LCM */ - if ((err = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { + if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) { goto LBL_T; } - err = mp_mul(a, &t2, c); + res = mp_mul(a, &t2, c); } /* fix the sign to positive */ @@ -39,6 +48,10 @@ mp_err mp_lcm(const mp_int *a, const mp_int *b, mp_int *c) LBL_T: mp_clear_multi(&t1, &t2, NULL); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_lshd.c b/src/ltm/bn_mp_lshd.c index 82345809..6762a10a 100644 --- a/src/ltm/bn_mp_lshd.c +++ b/src/ltm/bn_mp_lshd.c @@ -1,51 +1,68 @@ #include "tommath_private.h" #ifdef BN_MP_LSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* shift left a certain amount of digits */ -mp_err mp_lshd(mp_int *a, int b) +int mp_lshd(mp_int *a, int b) { - int x; - mp_err err; - mp_digit *top, *bottom; + int x, res; /* if its less than zero return */ if (b <= 0) { return MP_OKAY; } /* no need to shift 0 around */ - if (MP_IS_ZERO(a)) { + if (mp_iszero(a) == MP_YES) { return MP_OKAY; } /* grow to fit the new digits */ if (a->alloc < (a->used + b)) { - if ((err = mp_grow(a, a->used + b)) != MP_OKAY) { - return err; + if ((res = mp_grow(a, a->used + b)) != MP_OKAY) { + return res; } } - /* increment the used by the shift amount then copy upwards */ - a->used += b; + { + mp_digit *top, *bottom; - /* top */ - top = a->dp + a->used - 1; + /* increment the used by the shift amount then copy upwards */ + a->used += b; - /* base */ - bottom = (a->dp + a->used - 1) - b; + /* top */ + top = a->dp + a->used - 1; - /* much like mp_rshd this is implemented using a sliding window - * except the window goes the otherway around. Copying from - * the bottom to the top. see bn_mp_rshd.c for more info. - */ - for (x = a->used - 1; x >= b; x--) { - *top-- = *bottom--; - } + /* base */ + bottom = (a->dp + a->used - 1) - b; - /* zero the lower digits */ - MP_ZERO_DIGITS(a->dp, b); + /* much like mp_rshd this is implemented using a sliding window + * except the window goes the otherway around. Copying from + * the bottom to the top. see bn_mp_rshd.c for more info. + */ + for (x = a->used - 1; x >= b; x--) { + *top-- = *bottom--; + } + /* zero the lower digits */ + top = a->dp; + for (x = 0; x < b; x++) { + *top++ = 0; + } + } return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_mod.c b/src/ltm/bn_mp_mod.c index 18b4e6ba..fa022a79 100644 --- a/src/ltm/bn_mp_mod.c +++ b/src/ltm/bn_mp_mod.c @@ -1,31 +1,44 @@ #include "tommath_private.h" #ifdef BN_MP_MOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* c = a mod b, 0 <= c < b if b > 0, b < c <= 0 if b < 0 */ -mp_err mp_mod(const mp_int *a, const mp_int *b, mp_int *c) +int mp_mod(const mp_int *a, const mp_int *b, mp_int *c) { mp_int t; - mp_err err; + int res; - if ((err = mp_init_size(&t, b->used)) != MP_OKAY) { - return err; + if ((res = mp_init_size(&t, b->used)) != MP_OKAY) { + return res; } - if ((err = mp_div(a, b, NULL, &t)) != MP_OKAY) { + if ((res = mp_div(a, b, NULL, &t)) != MP_OKAY) { mp_clear(&t); - return err; + return res; } - if (MP_IS_ZERO(&t) || (t.sign == b->sign)) { - err = MP_OKAY; + if ((mp_iszero(&t) != MP_NO) || (t.sign == b->sign)) { + res = MP_OKAY; mp_exch(&t, c); } else { - err = mp_add(b, &t, c); + res = mp_add(b, &t, c); } mp_clear(&t); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_mod_2d.c b/src/ltm/bn_mp_mod_2d.c index 5bf57a1a..759198ba 100644 --- a/src/ltm/bn_mp_mod_2d.c +++ b/src/ltm/bn_mp_mod_2d.c @@ -1,13 +1,21 @@ #include "tommath_private.h" #ifdef BN_MP_MOD_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* calc a value mod 2**b */ -mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c) +int mp_mod_2d(const mp_int *a, int b, mp_int *c) { - int x; - mp_err err; + int x, res; /* if b is <= 0 then zero the int */ if (b <= 0) { @@ -16,23 +24,28 @@ mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c) } /* if the modulus is larger than the value than return */ - if (b >= (a->used * MP_DIGIT_BIT)) { - return mp_copy(a, c); + if (b >= (a->used * DIGIT_BIT)) { + res = mp_copy(a, c); + return res; } /* copy */ - if ((err = mp_copy(a, c)) != MP_OKAY) { - return err; + if ((res = mp_copy(a, c)) != MP_OKAY) { + return res; } /* zero digits above the last digit of the modulus */ - x = (b / MP_DIGIT_BIT) + (((b % MP_DIGIT_BIT) == 0) ? 0 : 1); - MP_ZERO_DIGITS(c->dp + x, c->used - x); - + for (x = (b / DIGIT_BIT) + (((b % DIGIT_BIT) == 0) ? 0 : 1); x < c->used; x++) { + c->dp[x] = 0; + } /* clear the digit that is not completely outside/inside the modulus */ - c->dp[b / MP_DIGIT_BIT] &= - ((mp_digit)1 << (mp_digit)(b % MP_DIGIT_BIT)) - (mp_digit)1; + c->dp[b / DIGIT_BIT] &= + ((mp_digit)1 << (mp_digit)(b % DIGIT_BIT)) - (mp_digit)1; mp_clamp(c); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_mod_d.c b/src/ltm/bn_mp_mod_d.c index 0b6c12a9..f58b6b5a 100644 --- a/src/ltm/bn_mp_mod_d.c +++ b/src/ltm/bn_mp_mod_d.c @@ -1,10 +1,23 @@ #include "tommath_private.h" #ifdef BN_MP_MOD_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ -mp_err mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c) +int mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c) { return mp_div_d(a, b, NULL, c); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_montgomery_calc_normalization.c b/src/ltm/bn_mp_montgomery_calc_normalization.c index 83797892..848378c4 100644 --- a/src/ltm/bn_mp_montgomery_calc_normalization.c +++ b/src/ltm/bn_mp_montgomery_calc_normalization.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* * shifts with subtractions when the result is greater than b. @@ -9,17 +18,16 @@ * The method is slightly modified to shift B unconditionally upto just under * the leading bit of b. This saves alot of multiple precision shifting. */ -mp_err mp_montgomery_calc_normalization(mp_int *a, const mp_int *b) +int mp_montgomery_calc_normalization(mp_int *a, const mp_int *b) { - int x, bits; - mp_err err; + int x, bits, res; /* how many bits of last digit does b use */ - bits = mp_count_bits(b) % MP_DIGIT_BIT; + bits = mp_count_bits(b) % DIGIT_BIT; if (b->used > 1) { - if ((err = mp_2expt(a, ((b->used - 1) * MP_DIGIT_BIT) + bits - 1)) != MP_OKAY) { - return err; + if ((res = mp_2expt(a, ((b->used - 1) * DIGIT_BIT) + bits - 1)) != MP_OKAY) { + return res; } } else { mp_set(a, 1uL); @@ -28,13 +36,13 @@ mp_err mp_montgomery_calc_normalization(mp_int *a, const mp_int *b) /* now compute C = A * B mod b */ - for (x = bits - 1; x < (int)MP_DIGIT_BIT; x++) { - if ((err = mp_mul_2(a, a)) != MP_OKAY) { - return err; + for (x = bits - 1; x < (int)DIGIT_BIT; x++) { + if ((res = mp_mul_2(a, a)) != MP_OKAY) { + return res; } if (mp_cmp_mag(a, b) != MP_LT) { - if ((err = s_mp_sub(a, b, a)) != MP_OKAY) { - return err; + if ((res = s_mp_sub(a, b, a)) != MP_OKAY) { + return res; } } } @@ -42,3 +50,7 @@ mp_err mp_montgomery_calc_normalization(mp_int *a, const mp_int *b) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_montgomery_reduce.c b/src/ltm/bn_mp_montgomery_reduce.c index ffe8341e..382c7cc7 100644 --- a/src/ltm/bn_mp_montgomery_reduce.c +++ b/src/ltm/bn_mp_montgomery_reduce.c @@ -1,13 +1,21 @@ #include "tommath_private.h" #ifdef BN_MP_MONTGOMERY_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* computes xR**-1 == x (mod N) via Montgomery Reduction */ -mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) +int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) { - int ix, digs; - mp_err err; + int ix, res, digs; mp_digit mu; /* can the fast reduction [comba] method be used? @@ -17,16 +25,17 @@ mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) * are fixed up in the inner loop. */ digs = (n->used * 2) + 1; - if ((digs < MP_WARRAY) && - (x->used <= MP_WARRAY) && - (n->used < MP_MAXFAST)) { - return s_mp_montgomery_reduce_fast(x, n, rho); + if ((digs < (int)MP_WARRAY) && + (x->used <= (int)MP_WARRAY) && + (n->used < + (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { + return fast_mp_montgomery_reduce(x, n, rho); } /* grow the input as required */ if (x->alloc < digs) { - if ((err = mp_grow(x, digs)) != MP_OKAY) { - return err; + if ((res = mp_grow(x, digs)) != MP_OKAY) { + return res; } } x->used = digs; @@ -64,7 +73,7 @@ mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) (mp_word)u + (mp_word)*tmpx; /* get carry */ - u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); /* fix digit */ *tmpx++ = (mp_digit)(r & (mp_word)MP_MASK); @@ -75,7 +84,7 @@ mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) /* propagate carries upwards as required*/ while (u != 0u) { *tmpx += u; - u = *tmpx >> MP_DIGIT_BIT; + u = *tmpx >> DIGIT_BIT; *tmpx++ &= MP_MASK; } } @@ -100,3 +109,7 @@ mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_montgomery_setup.c b/src/ltm/bn_mp_montgomery_setup.c index 39f6e9d2..26c632a2 100644 --- a/src/ltm/bn_mp_montgomery_setup.c +++ b/src/ltm/bn_mp_montgomery_setup.c @@ -1,10 +1,19 @@ #include "tommath_private.h" #ifdef BN_MP_MONTGOMERY_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* setups the montgomery reduction stuff */ -mp_err mp_montgomery_setup(const mp_int *n, mp_digit *rho) +int mp_montgomery_setup(const mp_int *n, mp_digit *rho) { mp_digit x, b; @@ -35,8 +44,12 @@ mp_err mp_montgomery_setup(const mp_int *n, mp_digit *rho) #endif /* rho = -1/m mod b */ - *rho = (mp_digit)(((mp_word)1 << (mp_word)MP_DIGIT_BIT) - x) & MP_MASK; + *rho = (mp_digit)(((mp_word)1 << (mp_word)DIGIT_BIT) - x) & MP_MASK; return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_mul.c b/src/ltm/bn_mp_mul.c index f0ca04af..f83b1b75 100644 --- a/src/ltm/bn_mp_mul.c +++ b/src/ltm/bn_mp_mul.c @@ -1,59 +1,33 @@ #include "tommath_private.h" #ifdef BN_MP_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* high level multiplication (handles sign) */ -mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c) +int mp_mul(const mp_int *a, const mp_int *b, mp_int *c) { - mp_err err; - mp_sign neg; -#ifdef BN_S_MP_BALANCE_MUL_C - int len_b, len_a; -#endif + int res, neg; neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; -#ifdef BN_S_MP_BALANCE_MUL_C - len_a = a->used; - len_b = b->used; - - if (len_a == len_b) { - goto GO_ON; - } - /* - * Check sizes. The smaller one needs to be larger than the Karatsuba cut-off. - * The bigger one needs to be at least about one KARATSUBA_MUL_CUTOFF bigger - * to make some sense, but it depends on architecture, OS, position of the - * stars... so YMMV. - * Using it to cut the input into slices small enough for fast_s_mp_mul_digs - * was actually slower on the author's machine, but YMMV. - */ - if ((MP_MIN(len_a, len_b) < MP_KARATSUBA_MUL_CUTOFF) - || ((MP_MAX(len_a, len_b) / 2) < MP_KARATSUBA_MUL_CUTOFF)) { - goto GO_ON; - } - /* - * Not much effect was observed below a ratio of 1:2, but again: YMMV. - */ - if ((MP_MAX(len_a, len_b) / MP_MIN(len_a, len_b)) < 2) { - goto GO_ON; - } - - err = s_mp_balance_mul(a,b,c); - goto END; - -GO_ON: -#endif /* use Toom-Cook? */ -#ifdef BN_S_MP_TOOM_MUL_C - if (MP_MIN(a->used, b->used) >= MP_TOOM_MUL_CUTOFF) { - err = s_mp_toom_mul(a, b, c); +#ifdef BN_MP_TOOM_MUL_C + if (MIN(a->used, b->used) >= TOOM_MUL_CUTOFF) { + res = mp_toom_mul(a, b, c); } else #endif -#ifdef BN_S_MP_KARATSUBA_MUL_C +#ifdef BN_MP_KARATSUBA_MUL_C /* use Karatsuba? */ - if (MP_MIN(a->used, b->used) >= MP_KARATSUBA_MUL_CUTOFF) { - err = s_mp_karatsuba_mul(a, b, c); + if (MIN(a->used, b->used) >= KARATSUBA_MUL_CUTOFF) { + res = mp_karatsuba_mul(a, b, c); } else #endif { @@ -65,22 +39,26 @@ GO_ON: */ int digs = a->used + b->used + 1; -#ifdef BN_S_MP_MUL_DIGS_FAST_C - if ((digs < MP_WARRAY) && - (MP_MIN(a->used, b->used) <= MP_MAXFAST)) { - err = s_mp_mul_digs_fast(a, b, c, digs); +#ifdef BN_FAST_S_MP_MUL_DIGS_C + if ((digs < (int)MP_WARRAY) && + (MIN(a->used, b->used) <= + (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { + res = fast_s_mp_mul_digs(a, b, c, digs); } else #endif { #ifdef BN_S_MP_MUL_DIGS_C - err = s_mp_mul_digs(a, b, c, a->used + b->used + 1); + res = s_mp_mul(a, b, c); /* uses s_mp_mul_digs */ #else - err = MP_VAL; + res = MP_VAL; #endif } } -END: c->sign = (c->used > 0) ? neg : MP_ZPOS; - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_mul_2.c b/src/ltm/bn_mp_mul_2.c index bc0691a0..2ed5516d 100644 --- a/src/ltm/bn_mp_mul_2.c +++ b/src/ltm/bn_mp_mul_2.c @@ -1,18 +1,26 @@ #include "tommath_private.h" #ifdef BN_MP_MUL_2_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* b = a*2 */ -mp_err mp_mul_2(const mp_int *a, mp_int *b) +int mp_mul_2(const mp_int *a, mp_int *b) { - int x, oldused; - mp_err err; + int x, res, oldused; /* grow to accomodate result */ if (b->alloc < (a->used + 1)) { - if ((err = mp_grow(b, a->used + 1)) != MP_OKAY) { - return err; + if ((res = mp_grow(b, a->used + 1)) != MP_OKAY) { + return res; } } @@ -35,7 +43,7 @@ mp_err mp_mul_2(const mp_int *a, mp_int *b) /* get what will be the *next* carry bit from the * MSB of the current digit */ - rr = *tmpa >> (mp_digit)(MP_DIGIT_BIT - 1); + rr = *tmpa >> (mp_digit)(DIGIT_BIT - 1); /* now shift up this digit, add in the carry [from the previous] */ *tmpb++ = ((*tmpa++ << 1uL) | r) & MP_MASK; @@ -56,9 +64,16 @@ mp_err mp_mul_2(const mp_int *a, mp_int *b) /* now zero any excess digits on the destination * that we didn't write to */ - MP_ZERO_DIGITS(b->dp + b->used, oldused - b->used); + tmpb = b->dp + b->used; + for (x = b->used; x < oldused; x++) { + *tmpb++ = 0; + } } b->sign = a->sign; return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_mul_2d.c b/src/ltm/bn_mp_mul_2d.c index 87354de2..9ea548d9 100644 --- a/src/ltm/bn_mp_mul_2d.c +++ b/src/ltm/bn_mp_mul_2d.c @@ -1,36 +1,45 @@ #include "tommath_private.h" #ifdef BN_MP_MUL_2D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* shift left by a certain bit count */ -mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) +int mp_mul_2d(const mp_int *a, int b, mp_int *c) { mp_digit d; - mp_err err; + int res; /* copy */ if (a != c) { - if ((err = mp_copy(a, c)) != MP_OKAY) { - return err; + if ((res = mp_copy(a, c)) != MP_OKAY) { + return res; } } - if (c->alloc < (c->used + (b / MP_DIGIT_BIT) + 1)) { - if ((err = mp_grow(c, c->used + (b / MP_DIGIT_BIT) + 1)) != MP_OKAY) { - return err; + if (c->alloc < (c->used + (b / DIGIT_BIT) + 1)) { + if ((res = mp_grow(c, c->used + (b / DIGIT_BIT) + 1)) != MP_OKAY) { + return res; } } /* shift by as many digits in the bit count */ - if (b >= MP_DIGIT_BIT) { - if ((err = mp_lshd(c, b / MP_DIGIT_BIT)) != MP_OKAY) { - return err; + if (b >= DIGIT_BIT) { + if ((res = mp_lshd(c, b / DIGIT_BIT)) != MP_OKAY) { + return res; } } - /* shift any bit count < MP_DIGIT_BIT */ - d = (mp_digit)(b % MP_DIGIT_BIT); + /* shift any bit count < DIGIT_BIT */ + d = (mp_digit)(b % DIGIT_BIT); if (d != 0u) { mp_digit *tmpc, shift, mask, r, rr; int x; @@ -39,7 +48,7 @@ mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) mask = ((mp_digit)1 << d) - (mp_digit)1; /* shift for msbs */ - shift = (mp_digit)MP_DIGIT_BIT - d; + shift = (mp_digit)DIGIT_BIT - d; /* alias */ tmpc = c->dp; @@ -67,3 +76,7 @@ mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_mul_d.c b/src/ltm/bn_mp_mul_d.c index b56dfa3c..936e1338 100644 --- a/src/ltm/bn_mp_mul_d.c +++ b/src/ltm/bn_mp_mul_d.c @@ -1,20 +1,28 @@ #include "tommath_private.h" #ifdef BN_MP_MUL_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* multiply by a digit */ -mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) +int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) { mp_digit u, *tmpa, *tmpc; mp_word r; - mp_err err; - int ix, olduse; + int ix, res, olduse; /* make sure c is big enough to hold a*b */ if (c->alloc < (a->used + 1)) { - if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { - return err; + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; } } @@ -42,7 +50,7 @@ mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) *tmpc++ = (mp_digit)(r & (mp_word)MP_MASK); /* send carry into next iteration */ - u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } /* store final carry [if any] and increment ix offset */ @@ -50,7 +58,9 @@ mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) ++ix; /* now zero digits above the top */ - MP_ZERO_DIGITS(tmpc, olduse - ix); + while (ix++ < olduse) { + *tmpc++ = 0; + } /* set used count */ c->used = a->used + 1; @@ -59,3 +69,7 @@ mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_mulmod.c b/src/ltm/bn_mp_mulmod.c index 763f923b..4192452d 100644 --- a/src/ltm/bn_mp_mulmod.c +++ b/src/ltm/bn_mp_mulmod.c @@ -1,24 +1,37 @@ #include "tommath_private.h" #ifdef BN_MP_MULMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* d = a * b (mod c) */ -mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) +int mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) { - mp_err err; - mp_int t; + int res; + mp_int t; - if ((err = mp_init_size(&t, c->used)) != MP_OKAY) { - return err; + if ((res = mp_init_size(&t, c->used)) != MP_OKAY) { + return res; } - if ((err = mp_mul(a, b, &t)) != MP_OKAY) { + if ((res = mp_mul(a, b, &t)) != MP_OKAY) { mp_clear(&t); - return err; + return res; } - err = mp_mod(&t, c, d); + res = mp_mod(&t, c, d); mp_clear(&t); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_n_root.c b/src/ltm/bn_mp_n_root.c index 3f959f1d..c14771fb 100644 --- a/src/ltm/bn_mp_n_root.c +++ b/src/ltm/bn_mp_n_root.c @@ -1,170 +1,27 @@ #include "tommath_private.h" #ifdef BN_MP_N_ROOT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* find the n'th root of an integer +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. * - * Result found such that (c)**b <= a and (c+1)**b > a + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. * - * This algorithm uses Newton's approximation - * x[i+1] = x[i] - f(x[i])/f'(x[i]) - * which will find the root in log(N) time where - * each step involves a fair bit. + * SPDX-License-Identifier: Unlicense */ -mp_err mp_n_root(const mp_int *a, mp_digit b, mp_int *c) -{ - mp_int t1, t2, t3, a_; - mp_ord cmp; - int ilog2; - mp_err err; - - /* input must be positive if b is even */ - if (((b & 1u) == 0u) && (a->sign == MP_NEG)) { - return MP_VAL; - } - - if ((err = mp_init_multi(&t1, &t2, &t3, NULL)) != MP_OKAY) { - return err; - } - - /* if a is negative fudge the sign but keep track */ - a_ = *a; - a_.sign = MP_ZPOS; - - /* Compute seed: 2^(log_2(n)/b + 2)*/ - ilog2 = mp_count_bits(a); - - /* - GCC and clang do not understand the sizeof tests and complain, - icc (the Intel compiler) seems to understand, at least it doesn't complain. - 2 of 3 say these macros are necessary, so there they are. - */ -#if ( !(defined MP_8BIT) && !(defined MP_16BIT) ) - /* - The type of mp_digit might be larger than an int. - If "b" is larger than INT_MAX it is also larger than - log_2(n) because the bit-length of the "n" is measured - with an int and hence the root is always < 2 (two). - */ - if (sizeof(mp_digit) >= sizeof(int)) { - if (b > (mp_digit)(INT_MAX/2)) { - mp_set(c, 1uL); - c->sign = a->sign; - err = MP_OKAY; - goto LBL_ERR; - } - } -#endif - /* "b" is smaller than INT_MAX, we can cast safely */ - if (ilog2 < (int)b) { - mp_set(c, 1uL); - c->sign = a->sign; - err = MP_OKAY; - goto LBL_ERR; - } - ilog2 = ilog2 / ((int)b); - if (ilog2 == 0) { - mp_set(c, 1uL); - c->sign = a->sign; - err = MP_OKAY; - goto LBL_ERR; - } - /* Start value must be larger than root */ - ilog2 += 2; - if ((err = mp_2expt(&t2,ilog2)) != MP_OKAY) { - goto LBL_ERR; - } - do { - /* t1 = t2 */ - if ((err = mp_copy(&t2, &t1)) != MP_OKAY) { - goto LBL_ERR; - } - - /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ - - /* t3 = t1**(b-1) */ - if ((err = mp_expt_d(&t1, b - 1u, &t3)) != MP_OKAY) { - goto LBL_ERR; - } - /* numerator */ - /* t2 = t1**b */ - if ((err = mp_mul(&t3, &t1, &t2)) != MP_OKAY) { - goto LBL_ERR; - } - /* t2 = t1**b - a */ - if ((err = mp_sub(&t2, &a_, &t2)) != MP_OKAY) { - goto LBL_ERR; - } - - /* denominator */ - /* t3 = t1**(b-1) * b */ - if ((err = mp_mul_d(&t3, b, &t3)) != MP_OKAY) { - goto LBL_ERR; - } - - /* t3 = (t1**b - a)/(b * t1**(b-1)) */ - if ((err = mp_div(&t2, &t3, &t3, NULL)) != MP_OKAY) { - goto LBL_ERR; - } - - if ((err = mp_sub(&t1, &t3, &t2)) != MP_OKAY) { - goto LBL_ERR; - } - /* - Number of rounds is at most log_2(root). If it is more it - got stuck, so break out of the loop and do the rest manually. - */ - if (ilog2-- == 0) { - break; - } - } while (mp_cmp(&t1, &t2) != MP_EQ); - - /* result can be off by a few so check */ - /* Loop beneath can overshoot by one if found root is smaller than actual root */ - for (;;) { - if ((err = mp_expt_d(&t1, b, &t2)) != MP_OKAY) { - goto LBL_ERR; - } - cmp = mp_cmp(&t2, &a_); - if (cmp == MP_EQ) { - err = MP_OKAY; - goto LBL_ERR; - } - if (cmp == MP_LT) { - if ((err = mp_add_d(&t1, 1uL, &t1)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - break; - } - } - /* correct overshoot from above or from recurrence */ - for (;;) { - if ((err = mp_expt_d(&t1, b, &t2)) != MP_OKAY) { - goto LBL_ERR; - } - if (mp_cmp(&t2, &a_) == MP_GT) { - if ((err = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) { - goto LBL_ERR; - } - } else { - break; - } - } - - /* set the result */ - mp_exch(&t1, c); - - /* set the sign of the result */ - c->sign = a->sign; - - err = MP_OKAY; - -LBL_ERR: - mp_clear_multi(&t1, &t2, &t3, NULL); - return err; +/* wrapper function for mp_n_root_ex() + * computes c = (a)**(1/b) such that (c)**b <= a and (c+1)**b > a + */ +int mp_n_root(const mp_int *a, mp_digit b, mp_int *c) +{ + return mp_n_root_ex(a, b, c, 0); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_n_root_ex.c b/src/ltm/bn_mp_n_root_ex.c new file mode 100644 index 00000000..ebc08ba5 --- /dev/null +++ b/src/ltm/bn_mp_n_root_ex.c @@ -0,0 +1,129 @@ +#include "tommath_private.h" +#ifdef BN_MP_N_ROOT_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* find the n'th root of an integer + * + * Result found such that (c)**b <= a and (c+1)**b > a + * + * This algorithm uses Newton's approximation + * x[i+1] = x[i] - f(x[i])/f'(x[i]) + * which will find the root in log(N) time where + * each step involves a fair bit. This is not meant to + * find huge roots [square and cube, etc]. + */ +int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) +{ + mp_int t1, t2, t3, a_; + int res; + + /* input must be positive if b is even */ + if (((b & 1u) == 0u) && (a->sign == MP_NEG)) { + return MP_VAL; + } + + if ((res = mp_init(&t1)) != MP_OKAY) { + return res; + } + + if ((res = mp_init(&t2)) != MP_OKAY) { + goto LBL_T1; + } + + if ((res = mp_init(&t3)) != MP_OKAY) { + goto LBL_T2; + } + + /* if a is negative fudge the sign but keep track */ + a_ = *a; + a_.sign = MP_ZPOS; + + /* t2 = 2 */ + mp_set(&t2, 2uL); + + do { + /* t1 = t2 */ + if ((res = mp_copy(&t2, &t1)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */ + + /* t3 = t1**(b-1) */ + if ((res = mp_expt_d_ex(&t1, b - 1u, &t3, fast)) != MP_OKAY) { + goto LBL_T3; + } + + /* numerator */ + /* t2 = t1**b */ + if ((res = mp_mul(&t3, &t1, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* t2 = t1**b - a */ + if ((res = mp_sub(&t2, &a_, &t2)) != MP_OKAY) { + goto LBL_T3; + } + + /* denominator */ + /* t3 = t1**(b-1) * b */ + if ((res = mp_mul_d(&t3, b, &t3)) != MP_OKAY) { + goto LBL_T3; + } + + /* t3 = (t1**b - a)/(b * t1**(b-1)) */ + if ((res = mp_div(&t2, &t3, &t3, NULL)) != MP_OKAY) { + goto LBL_T3; + } + + if ((res = mp_sub(&t1, &t3, &t2)) != MP_OKAY) { + goto LBL_T3; + } + } while (mp_cmp(&t1, &t2) != MP_EQ); + + /* result can be off by a few so check */ + for (;;) { + if ((res = mp_expt_d_ex(&t1, b, &t2, fast)) != MP_OKAY) { + goto LBL_T3; + } + + if (mp_cmp(&t2, &a_) == MP_GT) { + if ((res = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) { + goto LBL_T3; + } + } else { + break; + } + } + + /* set the result */ + mp_exch(&t1, c); + + /* set the sign of the result */ + c->sign = a->sign; + + res = MP_OKAY; + +LBL_T3: + mp_clear(&t3); +LBL_T2: + mp_clear(&t2); +LBL_T1: + mp_clear(&t1); + return res; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_neg.c b/src/ltm/bn_mp_neg.c index 264d9009..9020525f 100644 --- a/src/ltm/bn_mp_neg.c +++ b/src/ltm/bn_mp_neg.c @@ -1,19 +1,28 @@ #include "tommath_private.h" #ifdef BN_MP_NEG_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* b = -a */ -mp_err mp_neg(const mp_int *a, mp_int *b) +int mp_neg(const mp_int *a, mp_int *b) { - mp_err err; + int res; if (a != b) { - if ((err = mp_copy(a, b)) != MP_OKAY) { - return err; + if ((res = mp_copy(a, b)) != MP_OKAY) { + return res; } } - if (!MP_IS_ZERO(b)) { + if (mp_iszero(b) != MP_YES) { b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS; } else { b->sign = MP_ZPOS; @@ -22,3 +31,7 @@ mp_err mp_neg(const mp_int *a, mp_int *b) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_or.c b/src/ltm/bn_mp_or.c index cdacbfbe..a0f2711a 100644 --- a/src/ltm/bn_mp_or.c +++ b/src/ltm/bn_mp_or.c @@ -1,56 +1,48 @@ #include "tommath_private.h" #ifdef BN_MP_OR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* two complement or */ -mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c) +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* OR two ints together */ +int mp_or(const mp_int *a, const mp_int *b, mp_int *c) { - int used = MP_MAX(a->used, b->used) + 1, i; - mp_err err; - mp_digit ac = 1, bc = 1, cc = 1; - mp_sign csign = ((a->sign == MP_NEG) || (b->sign == MP_NEG)) ? MP_NEG : MP_ZPOS; - - if (c->alloc < used) { - if ((err = mp_grow(c, used)) != MP_OKAY) { - return err; - } - } - - for (i = 0; i < used; i++) { - mp_digit x, y; + int res, ix, px; + mp_int t; + const mp_int *x; - /* convert to two complement if negative */ - if (a->sign == MP_NEG) { - ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK); - x = ac & MP_MASK; - ac >>= MP_DIGIT_BIT; - } else { - x = (i >= a->used) ? 0uL : a->dp[i]; + if (a->used > b->used) { + if ((res = mp_init_copy(&t, a)) != MP_OKAY) { + return res; } - - /* convert to two complement if negative */ - if (b->sign == MP_NEG) { - bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK); - y = bc & MP_MASK; - bc >>= MP_DIGIT_BIT; - } else { - y = (i >= b->used) ? 0uL : b->dp[i]; - } - - c->dp[i] = x | y; - - /* convert to to sign-magnitude if negative */ - if (csign == MP_NEG) { - cc += ~c->dp[i] & MP_MASK; - c->dp[i] = cc & MP_MASK; - cc >>= MP_DIGIT_BIT; + px = b->used; + x = b; + } else { + if ((res = mp_init_copy(&t, b)) != MP_OKAY) { + return res; } + px = a->used; + x = a; } - c->used = used; - c->sign = csign; - mp_clamp(c); + for (ix = 0; ix < px; ix++) { + t.dp[ix] |= x->dp[ix]; + } + mp_clamp(&t); + mp_exch(c, &t); + mp_clear(&t); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_prime_fermat.c b/src/ltm/bn_mp_prime_fermat.c index af3e884b..63ced961 100644 --- a/src/ltm/bn_mp_prime_fermat.c +++ b/src/ltm/bn_mp_prime_fermat.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_PRIME_FERMAT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* performs one Fermat test. * @@ -11,10 +20,10 @@ * * Sets result to 1 if the congruence holds, or zero otherwise. */ -mp_err mp_prime_fermat(const mp_int *a, const mp_int *b, mp_bool *result) +int mp_prime_fermat(const mp_int *a, const mp_int *b, int *result) { mp_int t; - mp_err err; + int err; /* default to composite */ *result = MP_NO; @@ -45,3 +54,7 @@ LBL_T: return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_prime_frobenius_underwood.c b/src/ltm/bn_mp_prime_frobenius_underwood.c index ca8ddc67..4ceb51e0 100644 --- a/src/ltm/bn_mp_prime_frobenius_underwood.c +++ b/src/ltm/bn_mp_prime_frobenius_underwood.c @@ -1,8 +1,17 @@ #include "tommath_private.h" #ifdef BN_MP_PRIME_FROBENIUS_UNDERWOOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* * See file bn_mp_prime_is_prime.c or the documentation in doc/bn.tex for the details @@ -23,17 +32,17 @@ #else #define LTM_FROBENIUS_UNDERWOOD_A 32764 #endif -mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) +int mp_prime_frobenius_underwood(const mp_int *N, int *result) { mp_int T1z, T2z, Np1z, sz, tz; - int a, ap2, length, i, j; - mp_err err; + int a, ap2, length, i, j, isset; + int e; *result = MP_NO; - if ((err = mp_init_multi(&T1z, &T2z, &Np1z, &sz, &tz, NULL)) != MP_OKAY) { - return err; + if ((e = mp_init_multi(&T1z, &T2z, &Np1z, &sz, &tz, NULL)) != MP_OKAY) { + return e; } for (a = 0; a < LTM_FROBENIUS_UNDERWOOD_A; a++) { @@ -43,17 +52,19 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) continue; } /* (32764^2 - 4) < 2^31, no bigint for >MP_8BIT needed) */ - mp_set_u32(&T1z, (unsigned int)a); + if ((e = mp_set_long(&T1z, (unsigned long)a)) != MP_OKAY) { + goto LBL_FU_ERR; + } - if ((err = mp_sqr(&T1z, &T1z)) != MP_OKAY) { + if ((e = mp_sqr(&T1z, &T1z)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_sub_d(&T1z, 4uL, &T1z)) != MP_OKAY) { + if ((e = mp_sub_d(&T1z, 4uL, &T1z)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_kronecker(&T1z, N, &j)) != MP_OKAY) { + if ((e = mp_kronecker(&T1z, N, &j)) != MP_OKAY) { goto LBL_FU_ERR; } @@ -68,13 +79,15 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) } /* Tell it a composite and set return value accordingly */ if (a >= LTM_FROBENIUS_UNDERWOOD_A) { - err = MP_ITER; + e = MP_ITER; goto LBL_FU_ERR; } /* Composite if N and (a+4)*(2*a+5) are not coprime */ - mp_set_u32(&T1z, (unsigned int)((a+4)*((2*a)+5))); + if ((e = mp_set_long(&T1z, (unsigned long)((a+4)*((2*a)+5)))) != MP_OKAY) { + goto LBL_FU_ERR; + } - if ((err = mp_gcd(N, &T1z, &T1z)) != MP_OKAY) { + if ((e = mp_gcd(N, &T1z, &T1z)) != MP_OKAY) { goto LBL_FU_ERR; } @@ -83,7 +96,7 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) } ap2 = a + 2; - if ((err = mp_add_d(N, 1uL, &Np1z)) != MP_OKAY) { + if ((e = mp_add_d(N, 1uL, &Np1z)) != MP_OKAY) { goto LBL_FU_ERR; } @@ -97,79 +110,89 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) * tz = ((tz-sz)*(tz+sz))%N; * sz = temp; */ - if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY) { + if ((e = mp_mul_2(&tz, &T2z)) != MP_OKAY) { goto LBL_FU_ERR; } /* a = 0 at about 50% of the cases (non-square and odd input) */ if (a != 0) { - if ((err = mp_mul_d(&sz, (mp_digit)a, &T1z)) != MP_OKAY) { + if ((e = mp_mul_d(&sz, (mp_digit)a, &T1z)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_add(&T1z, &T2z, &T2z)) != MP_OKAY) { + if ((e = mp_add(&T1z, &T2z, &T2z)) != MP_OKAY) { goto LBL_FU_ERR; } } - if ((err = mp_mul(&T2z, &sz, &T1z)) != MP_OKAY) { + if ((e = mp_mul(&T2z, &sz, &T1z)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_sub(&tz, &sz, &T2z)) != MP_OKAY) { + if ((e = mp_sub(&tz, &sz, &T2z)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_add(&sz, &tz, &sz)) != MP_OKAY) { + if ((e = mp_add(&sz, &tz, &sz)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_mul(&sz, &T2z, &tz)) != MP_OKAY) { + if ((e = mp_mul(&sz, &T2z, &tz)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_mod(&tz, N, &tz)) != MP_OKAY) { + if ((e = mp_mod(&tz, N, &tz)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_mod(&T1z, N, &sz)) != MP_OKAY) { + if ((e = mp_mod(&T1z, N, &sz)) != MP_OKAY) { goto LBL_FU_ERR; } - if (s_mp_get_bit(&Np1z, (unsigned int)i) == MP_YES) { + if ((isset = mp_get_bit(&Np1z, i)) == MP_VAL) { + e = isset; + goto LBL_FU_ERR; + } + if (isset == MP_YES) { /* * temp = (a+2) * sz + tz * tz = 2 * tz - sz * sz = temp */ if (a == 0) { - if ((err = mp_mul_2(&sz, &T1z)) != MP_OKAY) { + if ((e = mp_mul_2(&sz, &T1z)) != MP_OKAY) { goto LBL_FU_ERR; } } else { - if ((err = mp_mul_d(&sz, (mp_digit)ap2, &T1z)) != MP_OKAY) { + if ((e = mp_mul_d(&sz, (mp_digit)ap2, &T1z)) != MP_OKAY) { goto LBL_FU_ERR; } } - if ((err = mp_add(&T1z, &tz, &T1z)) != MP_OKAY) { + if ((e = mp_add(&T1z, &tz, &T1z)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_mul_2(&tz, &T2z)) != MP_OKAY) { + if ((e = mp_mul_2(&tz, &T2z)) != MP_OKAY) { goto LBL_FU_ERR; } - if ((err = mp_sub(&T2z, &sz, &tz)) != MP_OKAY) { + if ((e = mp_sub(&T2z, &sz, &tz)) != MP_OKAY) { goto LBL_FU_ERR; } mp_exch(&sz, &T1z); } } - mp_set_u32(&T1z, (unsigned int)((2 * a) + 5)); - if ((err = mp_mod(&T1z, N, &T1z)) != MP_OKAY) { + if ((e = mp_set_long(&T1z, (unsigned long)((2 * a) + 5))) != MP_OKAY) { goto LBL_FU_ERR; } - if (MP_IS_ZERO(&sz) && (mp_cmp(&tz, &T1z) == MP_EQ)) { + if ((e = mp_mod(&T1z, N, &T1z)) != MP_OKAY) { + goto LBL_FU_ERR; + } + if ((mp_iszero(&sz) != MP_NO) && (mp_cmp(&tz, &T1z) == MP_EQ)) { *result = MP_YES; goto LBL_FU_ERR; } LBL_FU_ERR: mp_clear_multi(&tz, &sz, &Np1z, &T2z, &T1z, NULL); - return err; + return e; } #endif #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_prime_is_divisible.c b/src/ltm/bn_mp_prime_is_divisible.c new file mode 100644 index 00000000..0e6e2f38 --- /dev/null +++ b/src/ltm/bn_mp_prime_is_divisible.c @@ -0,0 +1,47 @@ +#include "tommath_private.h" +#ifdef BN_MP_PRIME_IS_DIVISIBLE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* determines if an integers is divisible by one + * of the first PRIME_SIZE primes or not + * + * sets result to 0 if not, 1 if yes + */ +int mp_prime_is_divisible(const mp_int *a, int *result) +{ + int err, ix; + mp_digit res; + + /* default to not */ + *result = MP_NO; + + for (ix = 0; ix < PRIME_SIZE; ix++) { + /* what is a mod LBL_prime_tab[ix] */ + if ((err = mp_mod_d(a, ltm_prime_tab[ix], &res)) != MP_OKAY) { + return err; + } + + /* is the residue zero? */ + if (res == 0u) { + *result = MP_YES; + return MP_OKAY; + } + } + + return MP_OKAY; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_prime_is_prime.c b/src/ltm/bn_mp_prime_is_prime.c index f4978221..63d3725b 100644 --- a/src/ltm/bn_mp_prime_is_prime.c +++ b/src/ltm/bn_mp_prime_is_prime.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_PRIME_IS_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* portable integer log of two with small footprint */ static unsigned int s_floor_ilog2(int value) @@ -14,58 +23,61 @@ static unsigned int s_floor_ilog2(int value) } -mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) +int mp_prime_is_prime(const mp_int *a, int t, int *result) { mp_int b; - int ix, p_max = 0, size_a, len; - mp_bool res; - mp_err err; + int ix, err, res, p_max = 0, size_a, len; unsigned int fips_rand, mask; /* default to no */ *result = MP_NO; + /* valid value of t? */ + if (t > PRIME_SIZE) { + return MP_VAL; + } + /* Some shortcuts */ /* N > 3 */ if (a->used == 1) { if ((a->dp[0] == 0u) || (a->dp[0] == 1u)) { - *result = MP_NO; + *result = 0; return MP_OKAY; } if (a->dp[0] == 2u) { - *result = MP_YES; + *result = 1; return MP_OKAY; } } /* N must be odd */ - if (MP_IS_EVEN(a)) { + if (mp_iseven(a) == MP_YES) { return MP_OKAY; } /* N is not a perfect square: floor(sqrt(N))^2 != N */ if ((err = mp_is_square(a, &res)) != MP_OKAY) { return err; } - if (res != MP_NO) { + if (res != 0) { return MP_OKAY; } /* is the input equal to one of the primes in the table? */ - for (ix = 0; ix < PRIVATE_MP_PRIME_TAB_SIZE; ix++) { - if (mp_cmp_d(a, s_mp_prime_tab[ix]) == MP_EQ) { + for (ix = 0; ix < PRIME_SIZE; ix++) { + if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) { *result = MP_YES; return MP_OKAY; } } #ifdef MP_8BIT /* The search in the loop above was exhaustive in this case */ - if ((a->used == 1) && (PRIVATE_MP_PRIME_TAB_SIZE >= 31)) { + if (a->used == 1 && PRIME_SIZE >= 31) { return MP_OKAY; } #endif /* first perform trial division */ - if ((err = s_mp_prime_is_divisible(a, &res)) != MP_OKAY) { + if ((err = mp_prime_is_divisible(a, &res)) != MP_OKAY) { return err; } @@ -114,7 +126,7 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) */ #if defined (MP_8BIT) || defined (LTM_USE_FROBENIUS_TEST) err = mp_prime_frobenius_underwood(a, &res); - if ((err != MP_OKAY) && (err != MP_ITER)) { + if (err != MP_OKAY && err != MP_ITER) { goto LBL_B; } if (res == MP_NO) { @@ -137,12 +149,41 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) } /* + abs(t) extra rounds of M-R to extend the range of primes it can find if t < 0. Only recommended if the input range is known to be < 3317044064679887385961981 - It uses the bases necessary for a deterministic M-R test if the input is - smaller than 3317044064679887385961981 + It uses the bases for a deterministic M-R test if input < 3317044064679887385961981 The caller has to check the size. - TODO: can be made a bit finer grained but comparing is not free. + + Not for cryptographic use because with known bases strong M-R pseudoprimes can + be constructed. Use at least one M-R test with a random base (t >= 1). + + The 1119 bit large number + + 80383745745363949125707961434194210813883768828755814583748891752229742737653\ + 33652186502336163960045457915042023603208766569966760987284043965408232928738\ + 79185086916685732826776177102938969773947016708230428687109997439976544144845\ + 34115587245063340927902227529622941498423068816854043264575340183297861112989\ + 60644845216191652872597534901 + + has been constructed by F. Arnault (F. Arnault, "Rabin-Miller primality test: + composite numbers which pass it.", Mathematics of Computation, 1995, 64. Jg., + Nr. 209, S. 355-361), is a semiprime with the two factors + + 40095821663949960541830645208454685300518816604113250877450620473800321707011\ + 96242716223191597219733582163165085358166969145233813917169287527980445796800\ + 452592031836601 + + 20047910831974980270915322604227342650259408302056625438725310236900160853505\ + 98121358111595798609866791081582542679083484572616906958584643763990222898400\ + 226296015918301 + + and it is a strong pseudoprime to all forty-six prime M-R bases up to 200 + + It does not fail the strong Bailley-PSP test as implemented here, it is just + given as an example, if not the reason to use the BPSW-test instead of M-R-tests + with a sequence of primes 2...n. + */ if (t < 0) { t = -t; @@ -171,9 +212,18 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) } } + /* for compatibility with the current API (well, compatible within a sign's width) */ + if (p_max < t) { + p_max = t; + } + + if (p_max > PRIME_SIZE) { + err = MP_VAL; + goto LBL_B; + } /* we did bases 2 and 3 already, skip them */ for (ix = 2; ix < p_max; ix++) { - mp_set(&b, s_mp_prime_tab[ix]); + mp_set(&b, ltm_prime_tab[ix]); if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) { goto LBL_B; } @@ -246,20 +296,17 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) * One 8-bit digit is too small, so concatenate two if the size of * unsigned int allows for it. */ - if ((MP_SIZEOF_BITS(unsigned int)/2) >= MP_SIZEOF_BITS(mp_digit)) { + if ((sizeof(unsigned int) * CHAR_BIT)/2 >= (sizeof(mp_digit) * CHAR_BIT)) { if ((err = mp_rand(&b, 1)) != MP_OKAY) { goto LBL_B; } - fips_rand <<= MP_SIZEOF_BITS(mp_digit); + fips_rand <<= sizeof(mp_digit) * CHAR_BIT; fips_rand |= (unsigned int) b.dp[0]; fips_rand &= mask; } #endif - if (fips_rand > (unsigned int)(INT_MAX - MP_DIGIT_BIT)) { - len = INT_MAX / MP_DIGIT_BIT; - } else { - len = (((int)fips_rand + MP_DIGIT_BIT) / MP_DIGIT_BIT); - } + /* Ceil, because small numbers have a right to live, too, */ + len = (((int)fips_rand + DIGIT_BIT) / DIGIT_BIT); /* Unlikely. */ if (len < 0) { ix--; @@ -282,15 +329,16 @@ mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) } /* * That number might got too big and the witness has to be - * smaller than "a" + * smaller than or equal to "a" */ len = mp_count_bits(&b); - if (len >= size_a) { - len = (len - size_a) + 1; + if (len > size_a) { + len = len - size_a; if ((err = mp_div_2d(&b, len, &b, NULL)) != MP_OKAY) { goto LBL_B; } } + /* Although the chance for b <= 3 is miniscule, try again. */ if (mp_cmp_d(&b, 3uL) != MP_GT) { ix--; @@ -313,3 +361,7 @@ LBL_B: } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_prime_miller_rabin.c b/src/ltm/bn_mp_prime_miller_rabin.c index 96470dba..a12e533c 100644 --- a/src/ltm/bn_mp_prime_miller_rabin.c +++ b/src/ltm/bn_mp_prime_miller_rabin.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_PRIME_MILLER_RABIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* Miller-Rabin test of "a" to the base of "b" as described in * HAC pp. 139 Algorithm 4.24 @@ -10,11 +19,10 @@ * Randomly the chance of error is no more than 1/4 and often * very much lower. */ -mp_err mp_prime_miller_rabin(const mp_int *a, const mp_int *b, mp_bool *result) +int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result) { mp_int n1, y, r; - mp_err err; - int s, j; + int s, j, err; /* default */ *result = MP_NO; @@ -89,3 +97,7 @@ LBL_N1: return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_prime_next_prime.c b/src/ltm/bn_mp_prime_next_prime.c index aaa821b7..28256ca8 100644 --- a/src/ltm/bn_mp_prime_next_prime.c +++ b/src/ltm/bn_mp_prime_next_prime.c @@ -1,29 +1,36 @@ #include "tommath_private.h" #ifdef BN_MP_PRIME_NEXT_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* finds the next prime after the number "a" using "t" trials * of Miller-Rabin. * * bbs_style = 1 means the prime must be congruent to 3 mod 4 */ -mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) +int mp_prime_next_prime(mp_int *a, int t, int bbs_style) { - int x, y; - mp_err err; - mp_bool res = MP_NO; - mp_digit res_tab[PRIVATE_MP_PRIME_TAB_SIZE], step, kstep; + int err, res = MP_NO, x, y; + mp_digit res_tab[PRIME_SIZE], step, kstep; mp_int b; /* force positive */ a->sign = MP_ZPOS; /* simple algo if a is less than the largest prime in the table */ - if (mp_cmp_d(a, s_mp_prime_tab[PRIVATE_MP_PRIME_TAB_SIZE-1]) == MP_LT) { + if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) { /* find which prime it is bigger than */ - for (x = PRIVATE_MP_PRIME_TAB_SIZE - 2; x >= 0; x--) { - if (mp_cmp_d(a, s_mp_prime_tab[x]) != MP_LT) { + for (x = PRIME_SIZE - 2; x >= 0; x--) { + if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) { if (bbs_style == 1) { /* ok we found a prime smaller or * equal [so the next is larger] @@ -31,17 +38,17 @@ mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) * however, the prime must be * congruent to 3 mod 4 */ - if ((s_mp_prime_tab[x + 1] & 3u) != 3u) { + if ((ltm_prime_tab[x + 1] & 3u) != 3u) { /* scan upwards for a prime congruent to 3 mod 4 */ - for (y = x + 1; y < PRIVATE_MP_PRIME_TAB_SIZE; y++) { - if ((s_mp_prime_tab[y] & 3u) == 3u) { - mp_set(a, s_mp_prime_tab[y]); + for (y = x + 1; y < PRIME_SIZE; y++) { + if ((ltm_prime_tab[y] & 3u) == 3u) { + mp_set(a, ltm_prime_tab[y]); return MP_OKAY; } } } } else { - mp_set(a, s_mp_prime_tab[x + 1]); + mp_set(a, ltm_prime_tab[x + 1]); return MP_OKAY; } } @@ -68,10 +75,10 @@ mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) if ((a->dp[0] & 3u) != 3u) { if ((err = mp_sub_d(a, (a->dp[0] & 3u) + 1u, a)) != MP_OKAY) { return err; - } + }; } } else { - if (MP_IS_EVEN(a)) { + if (mp_iseven(a) == MP_YES) { /* force odd */ if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) { return err; @@ -80,8 +87,8 @@ mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) } /* generate the restable */ - for (x = 1; x < PRIVATE_MP_PRIME_TAB_SIZE; x++) { - if ((err = mp_mod_d(a, s_mp_prime_tab[x], res_tab + x)) != MP_OKAY) { + for (x = 1; x < PRIME_SIZE; x++) { + if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) { return err; } } @@ -102,13 +109,13 @@ mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) step += kstep; /* compute the new residue without using division */ - for (x = 1; x < PRIVATE_MP_PRIME_TAB_SIZE; x++) { + for (x = 1; x < PRIME_SIZE; x++) { /* add the step to each residue */ res_tab[x] += kstep; /* subtract the modulus [instead of using division] */ - if (res_tab[x] >= s_mp_prime_tab[x]) { - res_tab[x] -= s_mp_prime_tab[x]; + if (res_tab[x] >= ltm_prime_tab[x]) { + res_tab[x] -= ltm_prime_tab[x]; } /* set flag if zero */ @@ -116,15 +123,15 @@ mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) y = 1; } } - } while ((y == 1) && (step < (((mp_digit)1 << MP_DIGIT_BIT) - kstep))); + } while ((y == 1) && (step < (((mp_digit)1 << DIGIT_BIT) - kstep))); /* add the step */ if ((err = mp_add_d(a, step, a)) != MP_OKAY) { goto LBL_ERR; } - /* if didn't pass sieve and step == MP_MAX then skip test */ - if ((y == 1) && (step >= (((mp_digit)1 << MP_DIGIT_BIT) - kstep))) { + /* if didn't pass sieve and step == MAX then skip test */ + if ((y == 1) && (step >= (((mp_digit)1 << DIGIT_BIT) - kstep))) { continue; } @@ -143,3 +150,7 @@ LBL_ERR: } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_prime_rabin_miller_trials.c b/src/ltm/bn_mp_prime_rabin_miller_trials.c index 0b3bab3f..1c0a748f 100644 --- a/src/ltm/bn_mp_prime_rabin_miller_trials.c +++ b/src/ltm/bn_mp_prime_rabin_miller_trials.c @@ -1,7 +1,17 @@ #include "tommath_private.h" #ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + static const struct { int k, t; @@ -19,7 +29,8 @@ static const struct { { 768, 5 }, { 896, 4 }, { 1024, 4 }, - { 2048, 2 } /* For bigger keysizes use always at least 2 Rounds */ + { 2048, 2 }, + { 4096, 1 }, }; /* returns # of RM trials required for a given bit size and max. error of 2^(-96)*/ @@ -34,8 +45,12 @@ int mp_prime_rabin_miller_trials(int size) return (x == 0) ? sizes[0].t : sizes[x - 1].t; } } - return sizes[x-1].t; + return sizes[x-1].t + 1; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_prime_rand.c b/src/ltm/bn_mp_prime_random_ex.c index 1cfe514d..b0b46328 100644 --- a/src/ltm/bn_mp_prime_rand.c +++ b/src/ltm/bn_mp_prime_random_ex.c @@ -1,15 +1,24 @@ #include "tommath_private.h" -#ifdef BN_MP_PRIME_RAND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +#ifdef BN_MP_PRIME_RANDOM_EX_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* makes a truly random prime of a given size (bits), * * Flags are as follows: * - * MP_PRIME_BBS - make prime congruent to 3 mod 4 - * MP_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies MP_PRIME_BBS) - * MP_PRIME_2MSB_ON - make the 2nd highest bit one + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one * * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself @@ -18,46 +27,44 @@ */ /* This is possibly the mother of all prime generation functions, muahahahahaha! */ -mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat) +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat) { unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb; - int bsize, maskOR_msb_offset; - mp_bool res; - mp_err err; + int res, err, bsize, maskOR_msb_offset; /* sanity check the input */ if ((size <= 1) || (t <= 0)) { return MP_VAL; } - /* MP_PRIME_SAFE implies MP_PRIME_BBS */ - if ((flags & MP_PRIME_SAFE) != 0) { - flags |= MP_PRIME_BBS; + /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */ + if ((flags & LTM_PRIME_SAFE) != 0) { + flags |= LTM_PRIME_BBS; } /* calc the byte size */ bsize = (size>>3) + ((size&7)?1:0); /* we need a buffer of bsize bytes */ - tmp = (unsigned char *) MP_MALLOC((size_t)bsize); + tmp = OPT_CAST(unsigned char) XMALLOC((size_t)bsize); if (tmp == NULL) { return MP_MEM; } /* calc the maskAND value for the MSbyte*/ - maskAND = ((size&7) == 0) ? 0xFFu : (unsigned char)(0xFFu >> (8 - (size & 7))); + maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7))); /* calc the maskOR_msb */ maskOR_msb = 0; maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0; - if ((flags & MP_PRIME_2MSB_ON) != 0) { - maskOR_msb |= (unsigned char)(0x80 >> ((9 - size) & 7)); + if ((flags & LTM_PRIME_2MSB_ON) != 0) { + maskOR_msb |= 0x80 >> ((9 - size) & 7); } /* get the maskOR_lsb */ - maskOR_lsb = 1u; - if ((flags & MP_PRIME_BBS) != 0) { - maskOR_lsb |= 3u; + maskOR_lsb = 1; + if ((flags & LTM_PRIME_BBS) != 0) { + maskOR_lsb |= 3; } do { @@ -69,7 +76,7 @@ mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_pr /* work over the MSbyte */ tmp[0] &= maskAND; - tmp[0] |= (unsigned char)(1 << ((size - 1) & 7)); + tmp[0] |= 1 << ((size - 1) & 7); /* mix in the maskORs */ tmp[maskOR_msb_offset] |= maskOR_msb; @@ -88,7 +95,7 @@ mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_pr continue; } - if ((flags & MP_PRIME_SAFE) != 0) { + if ((flags & LTM_PRIME_SAFE) != 0) { /* see if (a-1)/2 is prime */ if ((err = mp_sub_d(a, 1uL, a)) != MP_OKAY) { goto error; @@ -104,7 +111,7 @@ mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_pr } } while (res == MP_NO); - if ((flags & MP_PRIME_SAFE) != 0) { + if ((flags & LTM_PRIME_SAFE) != 0) { /* restore a to the original value */ if ((err = mp_mul_2(a, a)) != MP_OKAY) { goto error; @@ -116,25 +123,13 @@ mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_pr err = MP_OKAY; error: - MP_FREE_BUFFER(tmp, (size_t)bsize); + XFREE(tmp); return err; } -static int s_mp_rand_cb(unsigned char *dst, int len, void *dat) -{ - (void)dat; - if (len <= 0) { - return len; - } - if (s_mp_rand_source(dst, (size_t)len) != MP_OKAY) { - return 0; - } - return len; -} - -mp_err mp_prime_rand(mp_int *a, int t, int size, int flags) -{ - return s_mp_prime_random_ex(a, t, size, flags, s_mp_rand_cb, NULL); -} #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_prime_strong_lucas_selfridge.c b/src/ltm/bn_mp_prime_strong_lucas_selfridge.c index a8e3f671..ca15e3c7 100644 --- a/src/ltm/bn_mp_prime_strong_lucas_selfridge.c +++ b/src/ltm/bn_mp_prime_strong_lucas_selfridge.c @@ -1,8 +1,17 @@ #include "tommath_private.h" #ifdef BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* * See file bn_mp_prime_is_prime.c or the documentation in doc/bn.tex for the details @@ -19,24 +28,39 @@ * multiply bigint a with int d and put the result in c * Like mp_mul_d() but with a signed long as the small input */ -static mp_err s_mp_mul_si(const mp_int *a, int d, mp_int *c) +static int s_mp_mul_si(const mp_int *a, long d, mp_int *c) { mp_int t; - mp_err err; + int err, neg = 0; if ((err = mp_init(&t)) != MP_OKAY) { return err; } + if (d < 0) { + neg = 1; + d = -d; + } /* * mp_digit might be smaller than a long, which excludes * the use of mp_mul_d() here. */ - mp_set_i32(&t, d); - err = mp_mul(a, &t, c); + if ((err = mp_set_long(&t, (unsigned long) d)) != MP_OKAY) { + goto LBL_MPMULSI_ERR; + } + if ((err = mp_mul(a, &t, c)) != MP_OKAY) { + goto LBL_MPMULSI_ERR; + } + if (neg == 1) { + c->sign = (a->sign == MP_NEG) ? MP_ZPOS: MP_NEG; + } +LBL_MPMULSI_ERR: mp_clear(&t); return err; } + + + /* Strong Lucas-Selfridge test. returns MP_YES if it is a strong L-S prime, MP_NO if it is composite @@ -54,16 +78,17 @@ static mp_err s_mp_mul_si(const mp_int *a, int d, mp_int *c) (If that name sounds familiar, he is the guy who found the fdiv bug in the Pentium (P5x, I think) Intel processor) */ -mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) +int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result) { /* CZ TODO: choose better variable names! */ mp_int Dz, gcd, Np1, Uz, Vz, U2mz, V2mz, Qmz, Q2mz, Qkdz, T1z, T2z, T3z, T4z, Q2kdz; /* CZ TODO: Some of them need the full 32 bit, hence the (temporary) exclusion of MP_8BIT */ - int D, Ds, J, sign, P, Q, r, s, u, Nbits; - mp_err err; - mp_bool oddness; + int32_t D, Ds, J, sign, P, Q, r, s, u, Nbits; + int e; + int isset; *result = MP_NO; + /* Find the first element D in the sequence {5, -7, 9, -11, 13, ...} such that Jacobi(D,N) = -1 (Selfridge's algorithm). Theory @@ -72,9 +97,9 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) included. */ - if ((err = mp_init_multi(&Dz, &gcd, &Np1, &Uz, &Vz, &U2mz, &V2mz, &Qmz, &Q2mz, &Qkdz, &T1z, &T2z, &T3z, &T4z, &Q2kdz, - NULL)) != MP_OKAY) { - return err; + if ((e = mp_init_multi(&Dz, &gcd, &Np1, &Uz, &Vz, &U2mz, &V2mz, &Qmz, &Q2mz, &Qkdz, &T1z, &T2z, &T3z, &T4z, &Q2kdz, + NULL)) != MP_OKAY) { + return e; } D = 5; @@ -83,8 +108,10 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) for (;;) { Ds = sign * D; sign = -sign; - mp_set_u32(&Dz, (unsigned int)D); - if ((err = mp_gcd(a, &Dz, &gcd)) != MP_OKAY) { + if ((e = mp_set_long(&Dz, (unsigned long)D)) != MP_OKAY) { + goto LBL_LS_ERR; + } + if ((e = mp_gcd(a, &Dz, &gcd)) != MP_OKAY) { goto LBL_LS_ERR; } /* if 1 < GCD < N then N is composite with factor "D", and @@ -96,7 +123,7 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) if (Ds < 0) { Dz.sign = MP_NEG; } - if ((err = mp_kronecker(&Dz, a, &J)) != MP_OKAY) { + if ((e = mp_kronecker(&Dz, a, &J)) != MP_OKAY) { goto LBL_LS_ERR; } @@ -106,13 +133,11 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) D += 2; if (D > (INT_MAX - 2)) { - err = MP_VAL; + e = MP_VAL; goto LBL_LS_ERR; } } - - P = 1; /* Selfridge's choice */ Q = (1 - Ds) / 4; /* Required so D = P*P - 4*Q */ @@ -146,7 +171,7 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) Baillie-PSW test based on the strong Lucas-Selfridge test should be more reliable. */ - if ((err = mp_add_d(a, 1uL, &Np1)) != MP_OKAY) { + if ((e = mp_add_d(a, 1uL, &Np1)) != MP_OKAY) { goto LBL_LS_ERR; } s = mp_cnt_lsb(&Np1); @@ -158,7 +183,7 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) * dividing an even number by two does not produce * any leftovers. */ - if ((err = mp_div_2d(&Np1, s, &Dz, NULL)) != MP_OKAY) { + if ((e = mp_div_2d(&Np1, s, &Dz, NULL)) != MP_OKAY) { goto LBL_LS_ERR; } /* We must now compute U_d and V_d. Since d is odd, the accumulated @@ -179,27 +204,34 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) if (Q < 0) { Q = -Q; - mp_set_u32(&Qmz, (unsigned int)Q); - if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) { + if ((e = mp_set_long(&Qmz, (unsigned long)Q)) != MP_OKAY) { + goto LBL_LS_ERR; + } + if ((e = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) { goto LBL_LS_ERR; } /* Initializes calculation of Q^d */ - mp_set_u32(&Qkdz, (unsigned int)Q); + if ((e = mp_set_long(&Qkdz, (unsigned long)Q)) != MP_OKAY) { + goto LBL_LS_ERR; + } Qmz.sign = MP_NEG; Q2mz.sign = MP_NEG; Qkdz.sign = MP_NEG; Q = -Q; } else { - mp_set_u32(&Qmz, (unsigned int)Q); - if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) { + if ((e = mp_set_long(&Qmz, (unsigned long)Q)) != MP_OKAY) { + goto LBL_LS_ERR; + } + if ((e = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) { goto LBL_LS_ERR; } /* Initializes calculation of Q^d */ - mp_set_u32(&Qkdz, (unsigned int)Q); + if ((e = mp_set_long(&Qkdz, (unsigned long)Q)) != MP_OKAY) { + goto LBL_LS_ERR; + } } Nbits = mp_count_bits(&Dz); - for (u = 1; u < Nbits; u++) { /* zero bit off, already accounted for */ /* Formulas for doubling of indices (carried out mod N). Note that * the indices denoted as "2m" are actually powers of 2, specifically @@ -209,33 +241,38 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) * V_2m = V_m*V_m - 2*Q^m */ - if ((err = mp_mul(&U2mz, &V2mz, &U2mz)) != MP_OKAY) { + if ((e = mp_mul(&U2mz, &V2mz, &U2mz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mod(&U2mz, a, &U2mz)) != MP_OKAY) { + if ((e = mp_mod(&U2mz, a, &U2mz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_sqr(&V2mz, &V2mz)) != MP_OKAY) { + if ((e = mp_sqr(&V2mz, &V2mz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_sub(&V2mz, &Q2mz, &V2mz)) != MP_OKAY) { + if ((e = mp_sub(&V2mz, &Q2mz, &V2mz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mod(&V2mz, a, &V2mz)) != MP_OKAY) { + if ((e = mp_mod(&V2mz, a, &V2mz)) != MP_OKAY) { goto LBL_LS_ERR; } /* Must calculate powers of Q for use in V_2m, also for Q^d later */ - if ((err = mp_sqr(&Qmz, &Qmz)) != MP_OKAY) { + if ((e = mp_sqr(&Qmz, &Qmz)) != MP_OKAY) { goto LBL_LS_ERR; } /* prevents overflow */ /* CZ still necessary without a fixed prealloc'd mem.? */ - if ((err = mp_mod(&Qmz, a, &Qmz)) != MP_OKAY) { + if ((e = mp_mod(&Qmz, a, &Qmz)) != MP_OKAY) { + goto LBL_LS_ERR; + } + if ((e = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mul_2(&Qmz, &Q2mz)) != MP_OKAY) { + + if ((isset = mp_get_bit(&Dz, u)) == MP_VAL) { + e = isset; goto LBL_LS_ERR; } - if (s_mp_get_bit(&Dz, (unsigned int)u) == MP_YES) { + if (isset == MP_YES) { /* Formulas for addition of indices (carried out mod N); * * U_(m+n) = (U_m*V_n + U_n*V_m)/2 @@ -243,26 +280,27 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) * * Be careful with division by 2 (mod N)! */ - if ((err = mp_mul(&U2mz, &Vz, &T1z)) != MP_OKAY) { + + if ((e = mp_mul(&U2mz, &Vz, &T1z)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mul(&Uz, &V2mz, &T2z)) != MP_OKAY) { + if ((e = mp_mul(&Uz, &V2mz, &T2z)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mul(&V2mz, &Vz, &T3z)) != MP_OKAY) { + if ((e = mp_mul(&V2mz, &Vz, &T3z)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mul(&U2mz, &Uz, &T4z)) != MP_OKAY) { + if ((e = mp_mul(&U2mz, &Uz, &T4z)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = s_mp_mul_si(&T4z, Ds, &T4z)) != MP_OKAY) { + if ((e = s_mp_mul_si(&T4z, (long)Ds, &T4z)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_add(&T1z, &T2z, &Uz)) != MP_OKAY) { + if ((e = mp_add(&T1z, &T2z, &Uz)) != MP_OKAY) { goto LBL_LS_ERR; } - if (MP_IS_ODD(&Uz)) { - if ((err = mp_add(&Uz, a, &Uz)) != MP_OKAY) { + if (mp_isodd(&Uz) != MP_NO) { + if ((e = mp_add(&Uz, a, &Uz)) != MP_OKAY) { goto LBL_LS_ERR; } } @@ -271,43 +309,41 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) * Thomas R. Nicely used GMP's mpz_fdiv_q_2exp(). * But mp_div_2() does not do so, it is truncating instead. */ - oddness = MP_IS_ODD(&Uz) ? MP_YES : MP_NO; - if ((err = mp_div_2(&Uz, &Uz)) != MP_OKAY) { + if ((e = mp_div_2(&Uz, &Uz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((Uz.sign == MP_NEG) && (oddness != MP_NO)) { - if ((err = mp_sub_d(&Uz, 1uL, &Uz)) != MP_OKAY) { + if ((Uz.sign == MP_NEG) && (mp_isodd(&Uz) != MP_NO)) { + if ((e = mp_sub_d(&Uz, 1uL, &Uz)) != MP_OKAY) { goto LBL_LS_ERR; } } - if ((err = mp_add(&T3z, &T4z, &Vz)) != MP_OKAY) { + if ((e = mp_add(&T3z, &T4z, &Vz)) != MP_OKAY) { goto LBL_LS_ERR; } - if (MP_IS_ODD(&Vz)) { - if ((err = mp_add(&Vz, a, &Vz)) != MP_OKAY) { + if (mp_isodd(&Vz) != MP_NO) { + if ((e = mp_add(&Vz, a, &Vz)) != MP_OKAY) { goto LBL_LS_ERR; } } - oddness = MP_IS_ODD(&Vz) ? MP_YES : MP_NO; - if ((err = mp_div_2(&Vz, &Vz)) != MP_OKAY) { + if ((e = mp_div_2(&Vz, &Vz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((Vz.sign == MP_NEG) && (oddness != MP_NO)) { - if ((err = mp_sub_d(&Vz, 1uL, &Vz)) != MP_OKAY) { + if ((Vz.sign == MP_NEG) && (mp_isodd(&Vz) != MP_NO)) { + if ((e = mp_sub_d(&Vz, 1uL, &Vz)) != MP_OKAY) { goto LBL_LS_ERR; } } - if ((err = mp_mod(&Uz, a, &Uz)) != MP_OKAY) { + if ((e = mp_mod(&Uz, a, &Uz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY) { + if ((e = mp_mod(&Vz, a, &Vz)) != MP_OKAY) { goto LBL_LS_ERR; } /* Calculating Q^d for later use */ - if ((err = mp_mul(&Qkdz, &Qmz, &Qkdz)) != MP_OKAY) { + if ((e = mp_mul(&Qkdz, &Qmz, &Qkdz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) { + if ((e = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) { goto LBL_LS_ERR; } } @@ -315,7 +351,7 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) /* If U_d or V_d is congruent to 0 mod N, then N is a prime or a strong Lucas pseudoprime. */ - if (MP_IS_ZERO(&Uz) || MP_IS_ZERO(&Vz)) { + if ((mp_iszero(&Uz) != MP_NO) || (mp_iszero(&Vz) != MP_NO)) { *result = MP_YES; goto LBL_LS_ERR; } @@ -332,41 +368,45 @@ mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) Lucas pseudoprime. */ /* Initialize 2*Q^(d*2^r) for V_2m */ - if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) { + if ((e = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) { goto LBL_LS_ERR; } for (r = 1; r < s; r++) { - if ((err = mp_sqr(&Vz, &Vz)) != MP_OKAY) { + if ((e = mp_sqr(&Vz, &Vz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_sub(&Vz, &Q2kdz, &Vz)) != MP_OKAY) { + if ((e = mp_sub(&Vz, &Q2kdz, &Vz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mod(&Vz, a, &Vz)) != MP_OKAY) { + if ((e = mp_mod(&Vz, a, &Vz)) != MP_OKAY) { goto LBL_LS_ERR; } - if (MP_IS_ZERO(&Vz)) { + if (mp_iszero(&Vz) != MP_NO) { *result = MP_YES; goto LBL_LS_ERR; } /* Calculate Q^{d*2^r} for next r (final iteration irrelevant). */ if (r < (s - 1)) { - if ((err = mp_sqr(&Qkdz, &Qkdz)) != MP_OKAY) { + if ((e = mp_sqr(&Qkdz, &Qkdz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) { + if ((e = mp_mod(&Qkdz, a, &Qkdz)) != MP_OKAY) { goto LBL_LS_ERR; } - if ((err = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) { + if ((e = mp_mul_2(&Qkdz, &Q2kdz)) != MP_OKAY) { goto LBL_LS_ERR; } } } LBL_LS_ERR: mp_clear_multi(&Q2kdz, &T4z, &T3z, &T2z, &T1z, &Qkdz, &Q2mz, &Qmz, &V2mz, &U2mz, &Vz, &Uz, &Np1, &gcd, &Dz, NULL); - return err; + return e; } #endif #endif #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_radix_size.c b/src/ltm/bn_mp_radix_size.c index 6d7f912a..8583faa4 100644 --- a/src/ltm/bn_mp_radix_size.c +++ b/src/ltm/bn_mp_radix_size.c @@ -1,14 +1,22 @@ #include "tommath_private.h" #ifdef BN_MP_RADIX_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* returns size of ASCII reprensentation */ -mp_err mp_radix_size(const mp_int *a, int radix, int *size) +int mp_radix_size(const mp_int *a, int radix, int *size) { - mp_err err; - int digs; - mp_int t; + int res, digs; + mp_int t; mp_digit d; *size = 0; @@ -18,7 +26,7 @@ mp_err mp_radix_size(const mp_int *a, int radix, int *size) return MP_VAL; } - if (MP_IS_ZERO(a)) { + if (mp_iszero(a) == MP_YES) { *size = 2; return MP_OKAY; } @@ -38,18 +46,18 @@ mp_err mp_radix_size(const mp_int *a, int radix, int *size) } /* init a copy of the input */ - if ((err = mp_init_copy(&t, a)) != MP_OKAY) { - return err; + if ((res = mp_init_copy(&t, a)) != MP_OKAY) { + return res; } /* force temp to positive */ t.sign = MP_ZPOS; /* fetch out all of the digits */ - while (!MP_IS_ZERO(&t)) { - if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) { + while (mp_iszero(&t) == MP_NO) { + if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) { mp_clear(&t); - return err; + return res; } ++digs; } @@ -61,3 +69,7 @@ mp_err mp_radix_size(const mp_int *a, int radix, int *size) } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_radix_smap.c b/src/ltm/bn_mp_radix_smap.c index eb4765a8..f0b743e6 100644 --- a/src/ltm/bn_mp_radix_smap.c +++ b/src/ltm/bn_mp_radix_smap.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_RADIX_SMAP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* chars used in radix conversions */ const char *const mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; @@ -20,3 +29,7 @@ const unsigned char mp_s_rmap_reverse[] = { }; const size_t mp_s_rmap_reverse_sz = sizeof(mp_s_rmap_reverse); #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_rand.c b/src/ltm/bn_mp_rand.c index 7e9052c2..b66d1b0f 100644 --- a/src/ltm/bn_mp_rand.c +++ b/src/ltm/bn_mp_rand.c @@ -1,46 +1,222 @@ #include "tommath_private.h" #ifdef BN_MP_RAND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ -mp_err(*s_mp_rand_source)(void *out, size_t size) = s_mp_rand_platform; +/* First the OS-specific special cases + * - *BSD + * - Windows + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +#define MP_ARC4RANDOM +#define MP_GEN_RANDOM_MAX 0xffffffffu +#define MP_GEN_RANDOM_SHIFT 32 -void mp_rand_source(mp_err(*source)(void *out, size_t size)) +static int s_read_arc4random(mp_digit *p) { - s_mp_rand_source = (source == NULL) ? s_mp_rand_platform : source; + mp_digit d = 0, msk = 0; + do { + d <<= MP_GEN_RANDOM_SHIFT; + d |= ((mp_digit) arc4random()); + msk <<= MP_GEN_RANDOM_SHIFT; + msk |= (MP_MASK & MP_GEN_RANDOM_MAX); + } while ((MP_MASK & msk) != MP_MASK); + *p = d; + return MP_OKAY; } +#endif + +#if defined(_WIN32) || defined(_WIN32_WCE) +#define MP_WIN_CSP + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif +#ifdef _WIN32_WCE +#define UNDER_CE +#define ARM +#endif + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <wincrypt.h> + +static HCRYPTPROV hProv = 0; -mp_err mp_rand(mp_int *a, int digits) +static void s_cleanup_win_csp(void) { - int i; - mp_err err; + CryptReleaseContext(hProv, 0); + hProv = 0; +} - mp_zero(a); +static int s_read_win_csp(mp_digit *p) +{ + int ret = -1; + if (hProv == 0) { + if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && + !CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) { + hProv = 0; + return ret; + } + atexit(s_cleanup_win_csp); + } + if (CryptGenRandom(hProv, sizeof(*p), (void *)p) == TRUE) { + ret = MP_OKAY; + } + return ret; +} +#endif /* WIN32 */ +#if !defined(MP_WIN_CSP) && defined(__linux__) && defined(__GLIBC_PREREQ) +#if __GLIBC_PREREQ(2, 25) +#define MP_GETRANDOM +#include <sys/random.h> +#include <errno.h> + +static int s_read_getrandom(mp_digit *p) +{ + int ret; + do { + ret = getrandom(p, sizeof(*p), 0); + } while ((ret == -1) && (errno == EINTR)); + if (ret == sizeof(*p)) return MP_OKAY; + return -1; +} +#endif +#endif + +/* We assume all platforms besides windows provide "/dev/urandom". + * In case yours doesn't, define MP_NO_DEV_URANDOM at compile-time. + */ +#if !defined(MP_WIN_CSP) && !defined(MP_NO_DEV_URANDOM) +#ifndef MP_DEV_URANDOM +#define MP_DEV_URANDOM "/dev/urandom" +#endif +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> + +static int s_read_dev_urandom(mp_digit *p) +{ + ssize_t r; + int fd; + do { + fd = open(MP_DEV_URANDOM, O_RDONLY); + } while ((fd == -1) && (errno == EINTR)); + if (fd == -1) return -1; + do { + r = read(fd, p, sizeof(*p)); + } while ((r == -1) && (errno == EINTR)); + close(fd); + if (r != sizeof(*p)) return -1; + return MP_OKAY; +} +#endif + +#if defined(MP_PRNG_ENABLE_LTM_RNG) +unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void)); +void (*ltm_rng_callback)(void); + +static int s_read_ltm_rng(mp_digit *p) +{ + unsigned long ret; + if (ltm_rng == NULL) return -1; + ret = ltm_rng((void *)p, sizeof(*p), ltm_rng_callback); + if (ret != sizeof(*p)) return -1; + return MP_OKAY; +} +#endif + +static int s_rand_digit(mp_digit *p) +{ + int ret = -1; + +#if defined(MP_ARC4RANDOM) + ret = s_read_arc4random(p); + if (ret == MP_OKAY) return ret; +#endif + +#if defined(MP_WIN_CSP) + ret = s_read_win_csp(p); + if (ret == MP_OKAY) return ret; +#else + +#if defined(MP_GETRANDOM) + ret = s_read_getrandom(p); + if (ret == MP_OKAY) return ret; +#endif +#if defined(MP_DEV_URANDOM) + ret = s_read_dev_urandom(p); + if (ret == MP_OKAY) return ret; +#endif + +#endif /* MP_WIN_CSP */ + +#if defined(MP_PRNG_ENABLE_LTM_RNG) + ret = s_read_ltm_rng(p); + if (ret == MP_OKAY) return ret; +#endif + + return ret; +} + +/* makes a pseudo-random int of a given size */ +static int s_gen_random(mp_digit *r) +{ + int ret = s_rand_digit(r); + *r &= MP_MASK; + return ret; +} + +int mp_rand(mp_int *a, int digits) +{ + int res; + mp_digit d; + + mp_zero(a); if (digits <= 0) { return MP_OKAY; } - if ((err = mp_grow(a, digits)) != MP_OKAY) { - return err; - } + /* first place a random non-zero digit */ + do { + if (s_gen_random(&d) != MP_OKAY) { + return MP_VAL; + } + } while (d == 0u); - if ((err = s_mp_rand_source(a->dp, (size_t)digits * sizeof(mp_digit))) != MP_OKAY) { - return err; + if ((res = mp_add_d(a, d, a)) != MP_OKAY) { + return res; } - /* TODO: We ensure that the highest digit is nonzero. Should this be removed? */ - while ((a->dp[digits - 1] & MP_MASK) == 0u) { - if ((err = s_mp_rand_source(a->dp + digits - 1, sizeof(mp_digit))) != MP_OKAY) { - return err; + while (--digits > 0) { + if ((res = mp_lshd(a, 1)) != MP_OKAY) { + return res; } - } - a->used = digits; - for (i = 0; i < digits; ++i) { - a->dp[i] &= MP_MASK; + if (s_gen_random(&d) != MP_OKAY) { + return MP_VAL; + } + if ((res = mp_add_d(a, d, a)) != MP_OKAY) { + return res; + } } return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_read_radix.c b/src/ltm/bn_mp_read_radix.c index de18e06f..200601ed 100644 --- a/src/ltm/bn_mp_read_radix.c +++ b/src/ltm/bn_mp_read_radix.c @@ -1,18 +1,23 @@ #include "tommath_private.h" #ifdef BN_MP_READ_RADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -#define MP_TOUPPER(c) ((((c) >= 'a') && ((c) <= 'z')) ? (((c) + 'A') - 'a') : (c)) +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* read a string [ASCII] in a given radix */ -mp_err mp_read_radix(mp_int *a, const char *str, int radix) +int mp_read_radix(mp_int *a, const char *str, int radix) { - mp_err err; - int y; - mp_sign neg; + int y, res, neg; unsigned pos; - char ch; + char ch; /* zero the digit bignum */ mp_zero(a); @@ -41,7 +46,7 @@ mp_err mp_read_radix(mp_int *a, const char *str, int radix) * this allows numbers like 1AB and 1ab to represent the same value * [e.g. in hex] */ - ch = (radix <= 36) ? (char)MP_TOUPPER((int)*str) : *str; + ch = (radix <= 36) ? (char)toupper((int)*str) : *str; pos = (unsigned)(ch - '('); if (mp_s_rmap_reverse_sz < pos) { break; @@ -55,11 +60,11 @@ mp_err mp_read_radix(mp_int *a, const char *str, int radix) if ((y == 0xff) || (y >= radix)) { break; } - if ((err = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { - return err; + if ((res = mp_mul_d(a, (mp_digit)radix, a)) != MP_OKAY) { + return res; } - if ((err = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { - return err; + if ((res = mp_add_d(a, (mp_digit)y, a)) != MP_OKAY) { + return res; } ++str; } @@ -71,9 +76,13 @@ mp_err mp_read_radix(mp_int *a, const char *str, int radix) } /* set the sign only if a != 0 */ - if (!MP_IS_ZERO(a)) { + if (mp_iszero(a) != MP_YES) { a->sign = neg; } return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_read_signed_bin.c b/src/ltm/bn_mp_read_signed_bin.c index 2e163995..e97a1d07 100644 --- a/src/ltm/bn_mp_read_signed_bin.c +++ b/src/ltm/bn_mp_read_signed_bin.c @@ -1,16 +1,25 @@ #include "tommath_private.h" #ifdef BN_MP_READ_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* read signed bin, big endian, first byte is 0==positive or 1==negative */ -mp_err mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) +int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) { - mp_err err; + int res; /* read magnitude */ - if ((err = mp_read_unsigned_bin(a, b + 1, c - 1)) != MP_OKAY) { - return err; + if ((res = mp_read_unsigned_bin(a, b + 1, c - 1)) != MP_OKAY) { + return res; } /* first byte is 0 for positive, non-zero for negative */ @@ -23,3 +32,7 @@ mp_err mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_read_unsigned_bin.c b/src/ltm/bn_mp_read_unsigned_bin.c index 17b273e0..648762a6 100644 --- a/src/ltm/bn_mp_read_unsigned_bin.c +++ b/src/ltm/bn_mp_read_unsigned_bin.c @@ -1,17 +1,26 @@ #include "tommath_private.h" #ifdef BN_MP_READ_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* reads a unsigned char array, assumes the msb is stored first [big endian] */ -mp_err mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) +int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) { - mp_err err; + int res; /* make sure there are at least two digits */ if (a->alloc < 2) { - if ((err = mp_grow(a, 2)) != MP_OKAY) { - return err; + if ((res = mp_grow(a, 2)) != MP_OKAY) { + return res; } } @@ -20,8 +29,8 @@ mp_err mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) /* read the bytes in */ while (c-- > 0) { - if ((err = mp_mul_2d(a, 8, a)) != MP_OKAY) { - return err; + if ((res = mp_mul_2d(a, 8, a)) != MP_OKAY) { + return res; } #ifndef MP_8BIT @@ -37,3 +46,7 @@ mp_err mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_reduce.c b/src/ltm/bn_mp_reduce.c index d5d3fb10..cbf8641d 100644 --- a/src/ltm/bn_mp_reduce.c +++ b/src/ltm/bn_mp_reduce.c @@ -1,43 +1,51 @@ #include "tommath_private.h" #ifdef BN_MP_REDUCE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* reduces x mod m, assumes 0 < x < m**2, mu is * precomputed via mp_reduce_setup. * From HAC pp.604 Algorithm 14.42 */ -mp_err mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) +int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) { mp_int q; - mp_err err; - int um = m->used; + int res, um = m->used; /* q = x */ - if ((err = mp_init_copy(&q, x)) != MP_OKAY) { - return err; + if ((res = mp_init_copy(&q, x)) != MP_OKAY) { + return res; } /* q1 = x / b**(k-1) */ mp_rshd(&q, um - 1); /* according to HAC this optimization is ok */ - if ((mp_digit)um > ((mp_digit)1 << (MP_DIGIT_BIT - 1))) { - if ((err = mp_mul(&q, mu, &q)) != MP_OKAY) { + if ((mp_digit)um > ((mp_digit)1 << (DIGIT_BIT - 1))) { + if ((res = mp_mul(&q, mu, &q)) != MP_OKAY) { goto CLEANUP; } } else { #ifdef BN_S_MP_MUL_HIGH_DIGS_C - if ((err = s_mp_mul_high_digs(&q, mu, &q, um)) != MP_OKAY) { + if ((res = s_mp_mul_high_digs(&q, mu, &q, um)) != MP_OKAY) { goto CLEANUP; } -#elif defined(BN_S_MP_MUL_HIGH_DIGS_FAST_C) - if ((err = s_mp_mul_high_digs_fast(&q, mu, &q, um)) != MP_OKAY) { +#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) + if ((res = fast_s_mp_mul_high_digs(&q, mu, &q, um)) != MP_OKAY) { goto CLEANUP; } #else { - err = MP_VAL; + res = MP_VAL; goto CLEANUP; } #endif @@ -47,32 +55,32 @@ mp_err mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) mp_rshd(&q, um + 1); /* x = x mod b**(k+1), quick (no division) */ - if ((err = mp_mod_2d(x, MP_DIGIT_BIT * (um + 1), x)) != MP_OKAY) { + if ((res = mp_mod_2d(x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) { goto CLEANUP; } /* q = q * m mod b**(k+1), quick (no division) */ - if ((err = s_mp_mul_digs(&q, m, &q, um + 1)) != MP_OKAY) { + if ((res = s_mp_mul_digs(&q, m, &q, um + 1)) != MP_OKAY) { goto CLEANUP; } /* x = x - q */ - if ((err = mp_sub(x, &q, x)) != MP_OKAY) { + if ((res = mp_sub(x, &q, x)) != MP_OKAY) { goto CLEANUP; } /* If x < 0, add b**(k+1) to it */ if (mp_cmp_d(x, 0uL) == MP_LT) { mp_set(&q, 1uL); - if ((err = mp_lshd(&q, um + 1)) != MP_OKAY) + if ((res = mp_lshd(&q, um + 1)) != MP_OKAY) goto CLEANUP; - if ((err = mp_add(x, &q, x)) != MP_OKAY) + if ((res = mp_add(x, &q, x)) != MP_OKAY) goto CLEANUP; } /* Back off if it's too big */ while (mp_cmp(x, m) != MP_LT) { - if ((err = s_mp_sub(x, m, x)) != MP_OKAY) { + if ((res = s_mp_sub(x, m, x)) != MP_OKAY) { goto CLEANUP; } } @@ -80,6 +88,10 @@ mp_err mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) CLEANUP: mp_clear(&q); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_reduce_2k.c b/src/ltm/bn_mp_reduce_2k.c index 1cea6cb2..af673e63 100644 --- a/src/ltm/bn_mp_reduce_2k.c +++ b/src/ltm/bn_mp_reduce_2k.c @@ -1,40 +1,48 @@ #include "tommath_private.h" #ifdef BN_MP_REDUCE_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* reduces a modulo n where n is of the form 2**p - d */ -mp_err mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d) +int mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d) { mp_int q; - mp_err err; - int p; + int p, res; - if ((err = mp_init(&q)) != MP_OKAY) { - return err; + if ((res = mp_init(&q)) != MP_OKAY) { + return res; } p = mp_count_bits(n); top: /* q = a/2**p, a = a mod 2**p */ - if ((err = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { goto LBL_ERR; } if (d != 1u) { /* q = q * d */ - if ((err = mp_mul_d(&q, d, &q)) != MP_OKAY) { + if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { goto LBL_ERR; } } /* a = a + q */ - if ((err = s_mp_add(a, &q, a)) != MP_OKAY) { + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { goto LBL_ERR; } if (mp_cmp_mag(a, n) != MP_LT) { - if ((err = s_mp_sub(a, n, a)) != MP_OKAY) { + if ((res = s_mp_sub(a, n, a)) != MP_OKAY) { goto LBL_ERR; } goto top; @@ -42,7 +50,11 @@ top: LBL_ERR: mp_clear(&q); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_reduce_2k_l.c b/src/ltm/bn_mp_reduce_2k_l.c index 6a9f3d31..afdc3219 100644 --- a/src/ltm/bn_mp_reduce_2k_l.c +++ b/src/ltm/bn_mp_reduce_2k_l.c @@ -1,41 +1,49 @@ #include "tommath_private.h" #ifdef BN_MP_REDUCE_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* reduces a modulo n where n is of the form 2**p - d This differs from reduce_2k since "d" can be larger than a single digit. */ -mp_err mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d) +int mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d) { mp_int q; - mp_err err; - int p; + int p, res; - if ((err = mp_init(&q)) != MP_OKAY) { - return err; + if ((res = mp_init(&q)) != MP_OKAY) { + return res; } p = mp_count_bits(n); top: /* q = a/2**p, a = a mod 2**p */ - if ((err = mp_div_2d(a, p, &q, a)) != MP_OKAY) { + if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) { goto LBL_ERR; } /* q = q * d */ - if ((err = mp_mul(&q, d, &q)) != MP_OKAY) { + if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { goto LBL_ERR; } /* a = a + q */ - if ((err = s_mp_add(a, &q, a)) != MP_OKAY) { + if ((res = s_mp_add(a, &q, a)) != MP_OKAY) { goto LBL_ERR; } if (mp_cmp_mag(a, n) != MP_LT) { - if ((err = s_mp_sub(a, n, a)) != MP_OKAY) { + if ((res = s_mp_sub(a, n, a)) != MP_OKAY) { goto LBL_ERR; } goto top; @@ -43,7 +51,11 @@ top: LBL_ERR: mp_clear(&q); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_reduce_2k_setup.c b/src/ltm/bn_mp_reduce_2k_setup.c index 2eaf7add..166a9654 100644 --- a/src/ltm/bn_mp_reduce_2k_setup.c +++ b/src/ltm/bn_mp_reduce_2k_setup.c @@ -1,28 +1,36 @@ #include "tommath_private.h" #ifdef BN_MP_REDUCE_2K_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* determines the setup value */ -mp_err mp_reduce_2k_setup(const mp_int *a, mp_digit *d) +int mp_reduce_2k_setup(const mp_int *a, mp_digit *d) { - mp_err err; + int res, p; mp_int tmp; - int p; - if ((err = mp_init(&tmp)) != MP_OKAY) { - return err; + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; } p = mp_count_bits(a); - if ((err = mp_2expt(&tmp, p)) != MP_OKAY) { + if ((res = mp_2expt(&tmp, p)) != MP_OKAY) { mp_clear(&tmp); - return err; + return res; } - if ((err = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { + if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) { mp_clear(&tmp); - return err; + return res; } *d = tmp.dp[0]; @@ -30,3 +38,7 @@ mp_err mp_reduce_2k_setup(const mp_int *a, mp_digit *d) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_reduce_2k_setup_l.c b/src/ltm/bn_mp_reduce_2k_setup_l.c index 4f9aa14d..5584b487 100644 --- a/src/ltm/bn_mp_reduce_2k_setup_l.c +++ b/src/ltm/bn_mp_reduce_2k_setup_l.c @@ -1,28 +1,41 @@ #include "tommath_private.h" #ifdef BN_MP_REDUCE_2K_SETUP_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* determines the setup value */ -mp_err mp_reduce_2k_setup_l(const mp_int *a, mp_int *d) +int mp_reduce_2k_setup_l(const mp_int *a, mp_int *d) { - mp_err err; + int res; mp_int tmp; - if ((err = mp_init(&tmp)) != MP_OKAY) { - return err; + if ((res = mp_init(&tmp)) != MP_OKAY) { + return res; } - if ((err = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { + if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) { goto LBL_ERR; } - if ((err = s_mp_sub(&tmp, a, d)) != MP_OKAY) { + if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) { goto LBL_ERR; } LBL_ERR: mp_clear(&tmp); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_reduce_is_2k.c b/src/ltm/bn_mp_reduce_is_2k.c index bb70b553..8be985e9 100644 --- a/src/ltm/bn_mp_reduce_is_2k.c +++ b/src/ltm/bn_mp_reduce_is_2k.c @@ -1,10 +1,19 @@ #include "tommath_private.h" #ifdef BN_MP_REDUCE_IS_2K_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* determines if mp_reduce_2k can be used */ -mp_bool mp_reduce_is_2k(const mp_int *a) +int mp_reduce_is_2k(const mp_int *a) { int ix, iy, iw; mp_digit iz; @@ -19,20 +28,22 @@ mp_bool mp_reduce_is_2k(const mp_int *a) iw = 1; /* Test every bit from the second digit up, must be 1 */ - for (ix = MP_DIGIT_BIT; ix < iy; ix++) { + for (ix = DIGIT_BIT; ix < iy; ix++) { if ((a->dp[iw] & iz) == 0u) { return MP_NO; } iz <<= 1; - if (iz > MP_MASK) { + if (iz > (mp_digit)MP_MASK) { ++iw; iz = 1; } } - return MP_YES; - } else { - return MP_YES; } + return MP_YES; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_reduce_is_2k_l.c b/src/ltm/bn_mp_reduce_is_2k_l.c index 36fc59fe..da4aeda2 100644 --- a/src/ltm/bn_mp_reduce_is_2k_l.c +++ b/src/ltm/bn_mp_reduce_is_2k_l.c @@ -1,10 +1,19 @@ #include "tommath_private.h" #ifdef BN_MP_REDUCE_IS_2K_L_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* determines if reduce_2k_l can be used */ -mp_bool mp_reduce_is_2k_l(const mp_int *a) +int mp_reduce_is_2k_l(const mp_int *a) { int ix, iy; @@ -20,9 +29,13 @@ mp_bool mp_reduce_is_2k_l(const mp_int *a) } } return (iy >= (a->used/2)) ? MP_YES : MP_NO; - } else { - return MP_NO; + } + return MP_NO; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_reduce_setup.c b/src/ltm/bn_mp_reduce_setup.c index f02160fa..134d8a37 100644 --- a/src/ltm/bn_mp_reduce_setup.c +++ b/src/ltm/bn_mp_reduce_setup.c @@ -1,17 +1,31 @@ #include "tommath_private.h" #ifdef BN_MP_REDUCE_SETUP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* pre-calculate the value required for Barrett reduction * For a given modulus "b" it calulates the value required in "a" */ -mp_err mp_reduce_setup(mp_int *a, const mp_int *b) +int mp_reduce_setup(mp_int *a, const mp_int *b) { - mp_err err; - if ((err = mp_2expt(a, b->used * 2 * MP_DIGIT_BIT)) != MP_OKAY) { - return err; + int res; + + if ((res = mp_2expt(a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) { + return res; } return mp_div(a, b, a, NULL); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_rshd.c b/src/ltm/bn_mp_rshd.c index bb8743e3..61ab8c04 100644 --- a/src/ltm/bn_mp_rshd.c +++ b/src/ltm/bn_mp_rshd.c @@ -1,13 +1,21 @@ #include "tommath_private.h" #ifdef BN_MP_RSHD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* shift right a certain amount of digits */ void mp_rshd(mp_int *a, int b) { int x; - mp_digit *bottom, *top; /* if b <= 0 then ignore it */ if (b <= 0) { @@ -20,32 +28,42 @@ void mp_rshd(mp_int *a, int b) return; } - /* shift the digits down */ + { + mp_digit *bottom, *top; - /* bottom */ - bottom = a->dp; + /* shift the digits down */ - /* top [offset into digits] */ - top = a->dp + b; + /* bottom */ + bottom = a->dp; - /* this is implemented as a sliding window where - * the window is b-digits long and digits from - * the top of the window are copied to the bottom - * - * e.g. + /* top [offset into digits] */ + top = a->dp + b; - b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> - /\ | ----> - \-------------------/ ----> - */ - for (x = 0; x < (a->used - b); x++) { - *bottom++ = *top++; - } + /* this is implemented as a sliding window where + * the window is b-digits long and digits from + * the top of the window are copied to the bottom + * + * e.g. + + b-2 | b-1 | b0 | b1 | b2 | ... | bb | ----> + /\ | ----> + \-------------------/ ----> + */ + for (x = 0; x < (a->used - b); x++) { + *bottom++ = *top++; + } - /* zero the top digits */ - MP_ZERO_DIGITS(bottom, a->used - x); + /* zero the top digits */ + for (; x < a->used; x++) { + *bottom++ = 0; + } + } /* remove excess digits */ a->used -= b; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_set.c b/src/ltm/bn_mp_set.c index 44ac6df5..590a1008 100644 --- a/src/ltm/bn_mp_set.c +++ b/src/ltm/bn_mp_set.c @@ -1,14 +1,26 @@ #include "tommath_private.h" #ifdef BN_MP_SET_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* set to a digit */ void mp_set(mp_int *a, mp_digit b) { + mp_zero(a); a->dp[0] = b & MP_MASK; - a->sign = MP_ZPOS; a->used = (a->dp[0] != 0u) ? 1 : 0; - MP_ZERO_DIGITS(a->dp + a->used, a->alloc - a->used); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_set_i32.c b/src/ltm/bn_mp_set_i32.c deleted file mode 100644 index b266ed73..00000000 --- a/src/ltm/bn_mp_set_i32.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_SET_I32_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_SET_SIGNED(mp_set_i32, mp_set_u32, int, unsigned int) -#endif diff --git a/src/ltm/bn_mp_set_i64.c b/src/ltm/bn_mp_set_i64.c deleted file mode 100644 index a763406c..00000000 --- a/src/ltm/bn_mp_set_i64.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_SET_I64_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_SET_SIGNED(mp_set_i64, mp_set_u64, long long, unsigned long long) -#endif diff --git a/src/ltm/bn_mp_set_int.c b/src/ltm/bn_mp_set_int.c new file mode 100644 index 00000000..4f01e25b --- /dev/null +++ b/src/ltm/bn_mp_set_int.c @@ -0,0 +1,45 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_INT_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* set a 32-bit const */ +int mp_set_int(mp_int *a, unsigned long b) +{ + int x, res; + + mp_zero(a); + + /* set four bits at a time */ + for (x = 0; x < 8; x++) { + /* shift the number up four bits */ + if ((res = mp_mul_2d(a, 4, a)) != MP_OKAY) { + return res; + } + + /* OR in the top four bits of the source */ + a->dp[0] |= (mp_digit)(b >> 28) & 15uL; + + /* shift the source up to the next four bits */ + b <<= 4; + + /* ensure that digits are not clamped off */ + a->used += 1; + } + mp_clamp(a); + return MP_OKAY; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_set_long.c b/src/ltm/bn_mp_set_long.c new file mode 100644 index 00000000..35be8e75 --- /dev/null +++ b/src/ltm/bn_mp_set_long.c @@ -0,0 +1,21 @@ +#include "tommath_private.h" +#ifdef BN_MP_SET_LONG_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* set a platform dependent unsigned long int */ +MP_SET_XLONG(mp_set_long, unsigned long) +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_set_u32.c b/src/ltm/bn_mp_set_u32.c deleted file mode 100644 index 55781c50..00000000 --- a/src/ltm/bn_mp_set_u32.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_SET_U32_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_SET_UNSIGNED(mp_set_u32, unsigned int) -#endif diff --git a/src/ltm/bn_mp_set_u64.c b/src/ltm/bn_mp_set_u64.c deleted file mode 100644 index eca79f46..00000000 --- a/src/ltm/bn_mp_set_u64.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_SET_U64_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -MP_SET_UNSIGNED(mp_set_u64, unsigned long long) -#endif diff --git a/src/ltm/bn_mp_shrink.c b/src/ltm/bn_mp_shrink.c index cf27ed9e..ff7905f2 100644 --- a/src/ltm/bn_mp_shrink.c +++ b/src/ltm/bn_mp_shrink.c @@ -1,22 +1,38 @@ #include "tommath_private.h" #ifdef BN_MP_SHRINK_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* shrink a bignum */ -mp_err mp_shrink(mp_int *a) +int mp_shrink(mp_int *a) { mp_digit *tmp; - int alloc = MP_MAX(MP_MIN_PREC, a->used); - if (a->alloc != alloc) { - if ((tmp = (mp_digit *) MP_REALLOC(a->dp, - (size_t)a->alloc * sizeof(mp_digit), - (size_t)alloc * sizeof(mp_digit))) == NULL) { + int used = 1; + + if (a->used > 0) { + used = a->used; + } + + if (a->alloc != used) { + if ((tmp = OPT_CAST(mp_digit) XREALLOC(a->dp, sizeof(mp_digit) * (size_t)used)) == NULL) { return MP_MEM; } a->dp = tmp; - a->alloc = alloc; + a->alloc = used; } return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_signed_bin_size.c b/src/ltm/bn_mp_signed_bin_size.c index 1a7f49c9..89cd43ee 100644 --- a/src/ltm/bn_mp_signed_bin_size.c +++ b/src/ltm/bn_mp_signed_bin_size.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_SIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* get the size for an signed equivalent */ int mp_signed_bin_size(const mp_int *a) @@ -9,3 +18,7 @@ int mp_signed_bin_size(const mp_int *a) return 1 + mp_unsigned_bin_size(a); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_signed_rsh.c b/src/ltm/bn_mp_signed_rsh.c deleted file mode 100644 index 8d8d8414..00000000 --- a/src/ltm/bn_mp_signed_rsh.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_MP_SIGNED_RSH_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* shift right by a certain bit count with sign extension */ -mp_err mp_signed_rsh(const mp_int *a, int b, mp_int *c) -{ - mp_err res; - if (a->sign == MP_ZPOS) { - return mp_div_2d(a, b, c, NULL); - } - - res = mp_add_d(a, 1uL, c); - if (res != MP_OKAY) { - return res; - } - - res = mp_div_2d(c, b, c, NULL); - return (res == MP_OKAY) ? mp_sub_d(c, 1uL, c) : res; -} -#endif diff --git a/src/ltm/bn_mp_sqr.c b/src/ltm/bn_mp_sqr.c index d4c7d171..63bb2e2e 100644 --- a/src/ltm/bn_mp_sqr.c +++ b/src/ltm/bn_mp_sqr.c @@ -1,42 +1,56 @@ #include "tommath_private.h" #ifdef BN_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* computes b = a*a */ -mp_err mp_sqr(const mp_int *a, mp_int *b) +int mp_sqr(const mp_int *a, mp_int *b) { - mp_err err; + int res; -#ifdef BN_S_MP_TOOM_SQR_C +#ifdef BN_MP_TOOM_SQR_C /* use Toom-Cook? */ - if (a->used >= MP_TOOM_SQR_CUTOFF) { - err = s_mp_toom_sqr(a, b); + if (a->used >= TOOM_SQR_CUTOFF) { + res = mp_toom_sqr(a, b); /* Karatsuba? */ } else #endif -#ifdef BN_S_MP_KARATSUBA_SQR_C - if (a->used >= MP_KARATSUBA_SQR_CUTOFF) { - err = s_mp_karatsuba_sqr(a, b); +#ifdef BN_MP_KARATSUBA_SQR_C + if (a->used >= KARATSUBA_SQR_CUTOFF) { + res = mp_karatsuba_sqr(a, b); } else #endif { -#ifdef BN_S_MP_SQR_FAST_C +#ifdef BN_FAST_S_MP_SQR_C /* can we use the fast comba multiplier? */ - if ((((a->used * 2) + 1) < MP_WARRAY) && - (a->used < (MP_MAXFAST / 2))) { - err = s_mp_sqr_fast(a, b); + if ((((a->used * 2) + 1) < (int)MP_WARRAY) && + (a->used < + (int)(1u << (((sizeof(mp_word) * (size_t)CHAR_BIT) - (2u * (size_t)DIGIT_BIT)) - 1u)))) { + res = fast_s_mp_sqr(a, b); } else #endif { #ifdef BN_S_MP_SQR_C - err = s_mp_sqr(a, b); + res = s_mp_sqr(a, b); #else - err = MP_VAL; + res = MP_VAL; #endif } } b->sign = MP_ZPOS; - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_sqrmod.c b/src/ltm/bn_mp_sqrmod.c index b3c44e5c..953829e6 100644 --- a/src/ltm/bn_mp_sqrmod.c +++ b/src/ltm/bn_mp_sqrmod.c @@ -1,24 +1,37 @@ #include "tommath_private.h" #ifdef BN_MP_SQRMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* c = a * a (mod b) */ -mp_err mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c) +int mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c) { - mp_err err; + int res; mp_int t; - if ((err = mp_init(&t)) != MP_OKAY) { - return err; + if ((res = mp_init(&t)) != MP_OKAY) { + return res; } - if ((err = mp_sqr(a, &t)) != MP_OKAY) { + if ((res = mp_sqr(a, &t)) != MP_OKAY) { mp_clear(&t); - return err; + return res; } - err = mp_mod(&t, b, c); + res = mp_mod(&t, b, c); mp_clear(&t); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_sqrt.c b/src/ltm/bn_mp_sqrt.c index 82d68246..55b5c792 100644 --- a/src/ltm/bn_mp_sqrt.c +++ b/src/ltm/bn_mp_sqrt.c @@ -1,12 +1,21 @@ #include "tommath_private.h" #ifdef BN_MP_SQRT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* this function is less generic than mp_n_root, simpler and faster */ -mp_err mp_sqrt(const mp_int *arg, mp_int *ret) +int mp_sqrt(const mp_int *arg, mp_int *ret) { - mp_err err; + int res; mp_int t1, t2; /* must be positive */ @@ -15,16 +24,16 @@ mp_err mp_sqrt(const mp_int *arg, mp_int *ret) } /* easy out */ - if (MP_IS_ZERO(arg)) { + if (mp_iszero(arg) == MP_YES) { mp_zero(ret); return MP_OKAY; } - if ((err = mp_init_copy(&t1, arg)) != MP_OKAY) { - return err; + if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { + return res; } - if ((err = mp_init(&t2)) != MP_OKAY) { + if ((res = mp_init(&t2)) != MP_OKAY) { goto E2; } @@ -32,24 +41,24 @@ mp_err mp_sqrt(const mp_int *arg, mp_int *ret) mp_rshd(&t1, t1.used/2); /* t1 > 0 */ - if ((err = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) { + if ((res = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) { goto E1; } - if ((err = mp_add(&t1, &t2, &t1)) != MP_OKAY) { + if ((res = mp_add(&t1, &t2, &t1)) != MP_OKAY) { goto E1; } - if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) { + if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) { goto E1; } /* And now t1 > sqrt(arg) */ do { - if ((err = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) { + if ((res = mp_div(arg, &t1, &t2, NULL)) != MP_OKAY) { goto E1; } - if ((err = mp_add(&t1, &t2, &t1)) != MP_OKAY) { + if ((res = mp_add(&t1, &t2, &t1)) != MP_OKAY) { goto E1; } - if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) { + if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) { goto E1; } /* t1 >= sqrt(arg) >= t2 at this point */ @@ -61,7 +70,11 @@ E1: mp_clear(&t2); E2: mp_clear(&t1); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_sqrtmod_prime.c b/src/ltm/bn_mp_sqrtmod_prime.c index f8037605..cc4da3be 100644 --- a/src/ltm/bn_mp_sqrtmod_prime.c +++ b/src/ltm/bn_mp_sqrtmod_prime.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_SQRTMOD_PRIME_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* Tonelli-Shanks algorithm * https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm @@ -9,10 +18,9 @@ * */ -mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) +int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) { - mp_err err; - int legendre; + int res, legendre; mp_int t1, C, Q, S, Z, M, T, R, two; mp_digit i; @@ -22,89 +30,90 @@ mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) return MP_OKAY; } if (mp_cmp_d(prime, 2uL) == MP_EQ) return MP_VAL; /* prime must be odd */ - if ((err = mp_kronecker(n, prime, &legendre)) != MP_OKAY) return err; + if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res; if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */ - if ((err = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) { - return err; + if ((res = mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL)) != MP_OKAY) { + return res; } /* SPECIAL CASE: if prime mod 4 == 3 - * compute directly: err = n^(prime+1)/4 mod prime + * compute directly: res = n^(prime+1)/4 mod prime * Handbook of Applied Cryptography algorithm 3.36 */ - if ((err = mp_mod_d(prime, 4uL, &i)) != MP_OKAY) goto cleanup; + if ((res = mp_mod_d(prime, 4uL, &i)) != MP_OKAY) goto cleanup; if (i == 3u) { - if ((err = mp_add_d(prime, 1uL, &t1)) != MP_OKAY) goto cleanup; - if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; - if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; - if ((err = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup; - err = MP_OKAY; + if ((res = mp_add_d(prime, 1uL, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup; + res = MP_OKAY; goto cleanup; } /* NOW: Tonelli-Shanks algorithm */ /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */ - if ((err = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup; - if ((err = mp_sub_d(&Q, 1uL, &Q)) != MP_OKAY) goto cleanup; + if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup; + if ((res = mp_sub_d(&Q, 1uL, &Q)) != MP_OKAY) goto cleanup; /* Q = prime - 1 */ mp_zero(&S); /* S = 0 */ - while (MP_IS_EVEN(&Q)) { - if ((err = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup; + while (mp_iseven(&Q) != MP_NO) { + if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup; /* Q = Q / 2 */ - if ((err = mp_add_d(&S, 1uL, &S)) != MP_OKAY) goto cleanup; + if ((res = mp_add_d(&S, 1uL, &S)) != MP_OKAY) goto cleanup; /* S = S + 1 */ } /* find a Z such that the Legendre symbol (Z|prime) == -1 */ - mp_set_u32(&Z, 2u); + if ((res = mp_set_int(&Z, 2uL)) != MP_OKAY) goto cleanup; /* Z = 2 */ while (1) { - if ((err = mp_kronecker(&Z, prime, &legendre)) != MP_OKAY) goto cleanup; + if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup; if (legendre == -1) break; - if ((err = mp_add_d(&Z, 1uL, &Z)) != MP_OKAY) goto cleanup; + if ((res = mp_add_d(&Z, 1uL, &Z)) != MP_OKAY) goto cleanup; /* Z = Z + 1 */ } - if ((err = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup; + if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup; /* C = Z ^ Q mod prime */ - if ((err = mp_add_d(&Q, 1uL, &t1)) != MP_OKAY) goto cleanup; - if ((err = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_add_d(&Q, 1uL, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup; /* t1 = (Q + 1) / 2 */ - if ((err = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup; + if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup; /* R = n ^ ((Q + 1) / 2) mod prime */ - if ((err = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup; + if ((res = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup; /* T = n ^ Q mod prime */ - if ((err = mp_copy(&S, &M)) != MP_OKAY) goto cleanup; + if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup; /* M = S */ - mp_set_u32(&two, 2u); + if ((res = mp_set_int(&two, 2uL)) != MP_OKAY) goto cleanup; + res = MP_VAL; while (1) { - if ((err = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup; i = 0; while (1) { if (mp_cmp_d(&t1, 1uL) == MP_EQ) break; - if ((err = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup; i++; } if (i == 0u) { - if ((err = mp_copy(&R, ret)) != MP_OKAY) goto cleanup; - err = MP_OKAY; + if ((res = mp_copy(&R, ret)) != MP_OKAY) goto cleanup; + res = MP_OKAY; goto cleanup; } - if ((err = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup; - if ((err = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) goto cleanup; - if ((err = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_sub_d(&t1, 1uL, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup; /* t1 = 2 ^ (M - i - 1) */ - if ((err = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup; + if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup; /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */ - if ((err = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup; + if ((res = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup; /* C = (t1 * t1) mod prime */ - if ((err = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup; + if ((res = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup; /* R = (R * t1) mod prime */ - if ((err = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup; + if ((res = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup; /* T = (T * C) mod prime */ mp_set(&M, i); /* M = i */ @@ -112,7 +121,11 @@ mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) cleanup: mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_sub.c b/src/ltm/bn_mp_sub.c index c1ea39e1..df31951a 100644 --- a/src/ltm/bn_mp_sub.c +++ b/src/ltm/bn_mp_sub.c @@ -1,13 +1,24 @@ #include "tommath_private.h" #ifdef BN_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* high level subtraction (handles signs) */ -mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) +int mp_sub(const mp_int *a, const mp_int *b, mp_int *c) { - mp_sign sa = a->sign, sb = b->sign; - mp_err err; + int sa, sb, res; + + sa = a->sign; + sb = b->sign; if (sa != sb) { /* subtract a negative from a positive, OR */ @@ -15,7 +26,7 @@ mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) /* In either case, ADD their magnitudes, */ /* and use the sign of the first number. */ c->sign = sa; - err = s_mp_add(a, b, c); + res = s_mp_add(a, b, c); } else { /* subtract a positive from a positive, OR */ /* subtract a negative from a negative. */ @@ -25,16 +36,20 @@ mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) /* Copy the sign from the first */ c->sign = sa; /* The first has a larger or equal magnitude */ - err = s_mp_sub(a, b, c); + res = s_mp_sub(a, b, c); } else { /* The result has the *opposite* sign from */ /* the first number. */ c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS; /* The second has a larger magnitude */ - err = s_mp_sub(b, a, c); + res = s_mp_sub(b, a, c); } } - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_sub_d.c b/src/ltm/bn_mp_sub_d.c index 3ebf9b48..d8ac250b 100644 --- a/src/ltm/bn_mp_sub_d.c +++ b/src/ltm/bn_mp_sub_d.c @@ -1,19 +1,27 @@ #include "tommath_private.h" #ifdef BN_MP_SUB_D_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* single digit subtraction */ -mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) +int mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) { - mp_digit *tmpa, *tmpc; - mp_err err; - int ix, oldused; + mp_digit *tmpa, *tmpc, mu; + int res, ix, oldused; /* grow c as required */ if (c->alloc < (a->used + 1)) { - if ((err = mp_grow(c, a->used + 1)) != MP_OKAY) { - return err; + if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) { + return res; } } @@ -23,13 +31,13 @@ mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) if (a->sign == MP_NEG) { mp_int a_ = *a; a_.sign = MP_ZPOS; - err = mp_add_d(&a_, b, c); + res = mp_add_d(&a_, b, c); c->sign = MP_NEG; /* clamp */ mp_clamp(c); - return err; + return res; } /* setup regs */ @@ -50,25 +58,33 @@ mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) c->sign = MP_NEG; c->used = 1; } else { - mp_digit mu = b; - /* positive/size */ c->sign = MP_ZPOS; c->used = a->used; - /* subtract digits, mu is carry */ - for (ix = 0; ix < a->used; ix++) { + /* subtract first digit */ + *tmpc = *tmpa++ - b; + mu = *tmpc >> ((sizeof(mp_digit) * (size_t)CHAR_BIT) - 1u); + *tmpc++ &= MP_MASK; + + /* handle rest of the digits */ + for (ix = 1; ix < a->used; ix++) { *tmpc = *tmpa++ - mu; - mu = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); + mu = *tmpc >> ((sizeof(mp_digit) * (size_t)CHAR_BIT) - 1u); *tmpc++ &= MP_MASK; } } /* zero excess digits */ - MP_ZERO_DIGITS(tmpc, oldused - ix); - + while (ix++ < oldused) { + *tmpc++ = 0; + } mp_clamp(c); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_submod.c b/src/ltm/bn_mp_submod.c index 61c2d0f9..ba9ee6f4 100644 --- a/src/ltm/bn_mp_submod.c +++ b/src/ltm/bn_mp_submod.c @@ -1,24 +1,38 @@ #include "tommath_private.h" #ifdef BN_MP_SUBMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* d = a - b (mod c) */ -mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) +int mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) { - mp_err err; - mp_int t; + int res; + mp_int t; - if ((err = mp_init(&t)) != MP_OKAY) { - return err; + + if ((res = mp_init(&t)) != MP_OKAY) { + return res; } - if ((err = mp_sub(a, b, &t)) != MP_OKAY) { + if ((res = mp_sub(a, b, &t)) != MP_OKAY) { mp_clear(&t); - return err; + return res; } - err = mp_mod(&t, c, d); + res = mp_mod(&t, c, d); mp_clear(&t); - return err; + return res; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_tc_and.c b/src/ltm/bn_mp_tc_and.c new file mode 100644 index 00000000..9834dc68 --- /dev/null +++ b/src/ltm/bn_mp_tc_and.c @@ -0,0 +1,90 @@ +#include "tommath_private.h" +#ifdef BN_MP_TC_AND_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* two complement and */ +int mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c) +{ + int res = MP_OKAY, bits, abits, bbits; + int as = mp_isneg(a), bs = mp_isneg(b); + mp_int *mx = NULL, _mx, acpy, bcpy; + + if ((as != MP_NO) || (bs != MP_NO)) { + abits = mp_count_bits(a); + bbits = mp_count_bits(b); + bits = MAX(abits, bbits); + res = mp_init_set_int(&_mx, 1uL); + if (res != MP_OKAY) { + goto end; + } + + mx = &_mx; + res = mp_mul_2d(mx, bits + 1, mx); + if (res != MP_OKAY) { + goto end; + } + + if (as != MP_NO) { + res = mp_init(&acpy); + if (res != MP_OKAY) { + goto end; + } + + res = mp_add(mx, a, &acpy); + if (res != MP_OKAY) { + mp_clear(&acpy); + goto end; + } + a = &acpy; + } + if (bs != MP_NO) { + res = mp_init(&bcpy); + if (res != MP_OKAY) { + goto end; + } + + res = mp_add(mx, b, &bcpy); + if (res != MP_OKAY) { + mp_clear(&bcpy); + goto end; + } + b = &bcpy; + } + } + + res = mp_and(a, b, c); + + if ((as != MP_NO) && (bs != MP_NO) && (res == MP_OKAY)) { + res = mp_sub(c, mx, c); + } + +end: + if (a == &acpy) { + mp_clear(&acpy); + } + + if (b == &bcpy) { + mp_clear(&bcpy); + } + + if (mx == &_mx) { + mp_clear(mx); + } + + return res; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_tc_div_2d.c b/src/ltm/bn_mp_tc_div_2d.c new file mode 100644 index 00000000..4ff0acfc --- /dev/null +++ b/src/ltm/bn_mp_tc_div_2d.c @@ -0,0 +1,35 @@ +#include "tommath_private.h" +#ifdef BN_MP_TC_DIV_2D_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* two complement right shift */ +int mp_tc_div_2d(const mp_int *a, int b, mp_int *c) +{ + int res; + if (mp_isneg(a) == MP_NO) { + return mp_div_2d(a, b, c, NULL); + } + + res = mp_add_d(a, 1uL, c); + if (res != MP_OKAY) { + return res; + } + + res = mp_div_2d(c, b, c, NULL); + return (res == MP_OKAY) ? mp_sub_d(c, 1uL, c) : res; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_tc_or.c b/src/ltm/bn_mp_tc_or.c new file mode 100644 index 00000000..09414686 --- /dev/null +++ b/src/ltm/bn_mp_tc_or.c @@ -0,0 +1,90 @@ +#include "tommath_private.h" +#ifdef BN_MP_TC_OR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* two complement or */ +int mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c) +{ + int res = MP_OKAY, bits, abits, bbits; + int as = mp_isneg(a), bs = mp_isneg(b); + mp_int *mx = NULL, _mx, acpy, bcpy; + + if ((as != MP_NO) || (bs != MP_NO)) { + abits = mp_count_bits(a); + bbits = mp_count_bits(b); + bits = MAX(abits, bbits); + res = mp_init_set_int(&_mx, 1uL); + if (res != MP_OKAY) { + goto end; + } + + mx = &_mx; + res = mp_mul_2d(mx, bits + 1, mx); + if (res != MP_OKAY) { + goto end; + } + + if (as != MP_NO) { + res = mp_init(&acpy); + if (res != MP_OKAY) { + goto end; + } + + res = mp_add(mx, a, &acpy); + if (res != MP_OKAY) { + mp_clear(&acpy); + goto end; + } + a = &acpy; + } + if (bs != MP_NO) { + res = mp_init(&bcpy); + if (res != MP_OKAY) { + goto end; + } + + res = mp_add(mx, b, &bcpy); + if (res != MP_OKAY) { + mp_clear(&bcpy); + goto end; + } + b = &bcpy; + } + } + + res = mp_or(a, b, c); + + if (((as != MP_NO) || (bs != MP_NO)) && (res == MP_OKAY)) { + res = mp_sub(c, mx, c); + } + +end: + if (a == &acpy) { + mp_clear(&acpy); + } + + if (b == &bcpy) { + mp_clear(&bcpy); + } + + if (mx == &_mx) { + mp_clear(mx); + } + + return res; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_tc_xor.c b/src/ltm/bn_mp_tc_xor.c new file mode 100644 index 00000000..cdb1d400 --- /dev/null +++ b/src/ltm/bn_mp_tc_xor.c @@ -0,0 +1,90 @@ +#include "tommath_private.h" +#ifdef BN_MP_TC_XOR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* two complement xor */ +int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c) +{ + int res = MP_OKAY, bits, abits, bbits; + int as = mp_isneg(a), bs = mp_isneg(b); + mp_int *mx = NULL, _mx, acpy, bcpy; + + if ((as != MP_NO) || (bs != MP_NO)) { + abits = mp_count_bits(a); + bbits = mp_count_bits(b); + bits = MAX(abits, bbits); + res = mp_init_set_int(&_mx, 1uL); + if (res != MP_OKAY) { + goto end; + } + + mx = &_mx; + res = mp_mul_2d(mx, bits + 1, mx); + if (res != MP_OKAY) { + goto end; + } + + if (as != MP_NO) { + res = mp_init(&acpy); + if (res != MP_OKAY) { + goto end; + } + + res = mp_add(mx, a, &acpy); + if (res != MP_OKAY) { + mp_clear(&acpy); + goto end; + } + a = &acpy; + } + if (bs != MP_NO) { + res = mp_init(&bcpy); + if (res != MP_OKAY) { + goto end; + } + + res = mp_add(mx, b, &bcpy); + if (res != MP_OKAY) { + mp_clear(&bcpy); + goto end; + } + b = &bcpy; + } + } + + res = mp_xor(a, b, c); + + if ((as != bs) && (res == MP_OKAY)) { + res = mp_sub(c, mx, c); + } + +end: + if (a == &acpy) { + mp_clear(&acpy); + } + + if (b == &bcpy) { + mp_clear(&bcpy); + } + + if (mx == &_mx) { + mp_clear(mx); + } + + return res; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_to_signed_bin.c b/src/ltm/bn_mp_to_signed_bin.c index 73f37ca7..04e3b84d 100644 --- a/src/ltm/bn_mp_to_signed_bin.c +++ b/src/ltm/bn_mp_to_signed_bin.c @@ -1,16 +1,30 @@ #include "tommath_private.h" #ifdef BN_MP_TO_SIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* store in signed [big endian] format */ -mp_err mp_to_signed_bin(const mp_int *a, unsigned char *b) +int mp_to_signed_bin(const mp_int *a, unsigned char *b) { - mp_err err; - if ((err = mp_to_unsigned_bin(a, b + 1)) != MP_OKAY) { - return err; + int res; + + if ((res = mp_to_unsigned_bin(a, b + 1)) != MP_OKAY) { + return res; } b[0] = (a->sign == MP_ZPOS) ? (unsigned char)0 : (unsigned char)1; return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_to_signed_bin_n.c b/src/ltm/bn_mp_to_signed_bin_n.c index 4c36cb5f..d13fede6 100644 --- a/src/ltm/bn_mp_to_signed_bin_n.c +++ b/src/ltm/bn_mp_to_signed_bin_n.c @@ -1,10 +1,19 @@ #include "tommath_private.h" #ifdef BN_MP_TO_SIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* store in signed [big endian] format */ -mp_err mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) +int mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) { if (*outlen < (unsigned long)mp_signed_bin_size(a)) { return MP_VAL; @@ -13,3 +22,7 @@ mp_err mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outl return mp_to_signed_bin(a, b); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_to_unsigned_bin.c b/src/ltm/bn_mp_to_unsigned_bin.c index 093b01aa..ab575146 100644 --- a/src/ltm/bn_mp_to_unsigned_bin.c +++ b/src/ltm/bn_mp_to_unsigned_bin.c @@ -1,33 +1,45 @@ #include "tommath_private.h" #ifdef BN_MP_TO_UNSIGNED_BIN_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* store in unsigned [big endian] format */ -mp_err mp_to_unsigned_bin(const mp_int *a, unsigned char *b) +int mp_to_unsigned_bin(const mp_int *a, unsigned char *b) { - int x; - mp_err err; + int x, res; mp_int t; - if ((err = mp_init_copy(&t, a)) != MP_OKAY) { - return err; + if ((res = mp_init_copy(&t, a)) != MP_OKAY) { + return res; } x = 0; - while (!MP_IS_ZERO(&t)) { + while (mp_iszero(&t) == MP_NO) { #ifndef MP_8BIT b[x++] = (unsigned char)(t.dp[0] & 255u); #else b[x++] = (unsigned char)(t.dp[0] | ((t.dp[1] & 1u) << 7)); #endif - if ((err = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) { + if ((res = mp_div_2d(&t, 8, &t, NULL)) != MP_OKAY) { mp_clear(&t); - return err; + return res; } } - s_mp_reverse(b, x); + bn_reverse(b, x); mp_clear(&t); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_to_unsigned_bin_n.c b/src/ltm/bn_mp_to_unsigned_bin_n.c index 3c08465e..c53e7fb6 100644 --- a/src/ltm/bn_mp_to_unsigned_bin_n.c +++ b/src/ltm/bn_mp_to_unsigned_bin_n.c @@ -1,10 +1,19 @@ #include "tommath_private.h" #ifdef BN_MP_TO_UNSIGNED_BIN_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* store in unsigned [big endian] format */ -mp_err mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) +int mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) { if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) { return MP_VAL; @@ -13,3 +22,7 @@ mp_err mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *ou return mp_to_unsigned_bin(a, b); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_toom_mul.c b/src/ltm/bn_mp_toom_mul.c new file mode 100644 index 00000000..32b5e43a --- /dev/null +++ b/src/ltm/bn_mp_toom_mul.c @@ -0,0 +1,283 @@ +#include "tommath_private.h" +#ifdef BN_MP_TOOM_MUL_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* multiplication using the Toom-Cook 3-way algorithm + * + * Much more complicated than Karatsuba but has a lower + * asymptotic running time of O(N**1.464). This algorithm is + * only particularly useful on VERY large inputs + * (we're talking 1000s of digits here...). +*/ +int mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c) +{ + mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = MIN(a->used, b->used) / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto LBL_ERR; + } + mp_rshd(&a1, B); + if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto LBL_ERR; + } + mp_rshd(&a2, B*2); + + /* b = b2 * B**2 + b1 * B + b0 */ + if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_copy(b, &b1)) != MP_OKAY) { + goto LBL_ERR; + } + mp_rshd(&b1, B); + (void)mp_mod_2d(&b1, DIGIT_BIT * B, &b1); + + if ((res = mp_copy(b, &b2)) != MP_OKAY) { + goto LBL_ERR; + } + mp_rshd(&b2, B*2); + + /* w0 = a0*b0 */ + if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) { + goto LBL_ERR; + } + + /* w4 = a2 * b2 */ + if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) { + goto LBL_ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + + + /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, + 2 small divisions and 1 small multiplication + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3uL, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto LBL_ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) { + goto LBL_ERR; + } + +LBL_ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, + &a0, &a1, &a2, &b0, &b1, + &b2, &tmp1, &tmp2, NULL); + return res; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_toom_sqr.c b/src/ltm/bn_mp_toom_sqr.c new file mode 100644 index 00000000..8595db5d --- /dev/null +++ b/src/ltm/bn_mp_toom_sqr.c @@ -0,0 +1,224 @@ +#include "tommath_private.h" +#ifdef BN_MP_TOOM_SQR_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* squaring using Toom-Cook 3-way algorithm */ +int mp_toom_sqr(const mp_int *a, mp_int *b) +{ + mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2; + int res, B; + + /* init temps */ + if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) { + return res; + } + + /* B */ + B = a->used / 3; + + /* a = a2 * B**2 + a1 * B + a0 */ + if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_copy(a, &a1)) != MP_OKAY) { + goto LBL_ERR; + } + mp_rshd(&a1, B); + if ((res = mp_mod_2d(&a1, DIGIT_BIT * B, &a1)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_copy(a, &a2)) != MP_OKAY) { + goto LBL_ERR; + } + mp_rshd(&a2, B*2); + + /* w0 = a0*a0 */ + if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) { + goto LBL_ERR; + } + + /* w4 = a2 * a2 */ + if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) { + goto LBL_ERR; + } + + /* w1 = (a2 + 2(a1 + 2a0))**2 */ + if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + + /* w3 = (a0 + 2(a1 + 2a2))**2 */ + if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + + + /* w2 = (a2 + a1 + a0)**2 */ + if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + + /* now solve the matrix + + 0 0 0 0 1 + 1 2 4 8 16 + 1 1 1 1 1 + 16 8 4 2 1 + 1 0 0 0 0 + + using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication. + */ + + /* r1 - r4 */ + if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3 - r0 */ + if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1/2 */ + if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3/2 */ + if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* r2 - r0 - r4 */ + if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1 - 8r0 */ + if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3 - 8r4 */ + if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* 3r2 - r1 - r3 */ + if ((res = mp_mul_d(&w2, 3uL, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1 - r2 */ + if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3 - r2 */ + if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) { + goto LBL_ERR; + } + /* r1/3 */ + if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) { + goto LBL_ERR; + } + /* r3/3 */ + if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) { + goto LBL_ERR; + } + + /* at this point shift W[n] by B*n */ + if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) { + goto LBL_ERR; + } + + if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) { + goto LBL_ERR; + } + if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) { + goto LBL_ERR; + } + +LBL_ERR: + mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL); + return res; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_toradix.c b/src/ltm/bn_mp_toradix.c index 6322e91e..c6e1c656 100644 --- a/src/ltm/bn_mp_toradix.c +++ b/src/ltm/bn_mp_toradix.c @@ -1,13 +1,21 @@ #include "tommath_private.h" #ifdef BN_MP_TORADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* stores a bignum as a ASCII string in a given radix (2..64) */ -mp_err mp_toradix(const mp_int *a, char *str, int radix) +int mp_toradix(const mp_int *a, char *str, int radix) { - mp_err err; - int digs; + int res, digs; mp_int t; mp_digit d; char *_s = str; @@ -18,14 +26,14 @@ mp_err mp_toradix(const mp_int *a, char *str, int radix) } /* quick out if its zero */ - if (MP_IS_ZERO(a)) { + if (mp_iszero(a) == MP_YES) { *str++ = '0'; *str = '\0'; return MP_OKAY; } - if ((err = mp_init_copy(&t, a)) != MP_OKAY) { - return err; + if ((res = mp_init_copy(&t, a)) != MP_OKAY) { + return res; } /* if it is negative output a - */ @@ -36,10 +44,10 @@ mp_err mp_toradix(const mp_int *a, char *str, int radix) } digs = 0; - while (!MP_IS_ZERO(&t)) { - if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) { + while (mp_iszero(&t) == MP_NO) { + if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) { mp_clear(&t); - return err; + return res; } *str++ = mp_s_rmap[d]; ++digs; @@ -48,7 +56,7 @@ mp_err mp_toradix(const mp_int *a, char *str, int radix) /* reverse the digits of the string. In this case _s points * to the first digit [exluding the sign] of the number] */ - s_mp_reverse((unsigned char *)_s, digs); + bn_reverse((unsigned char *)_s, digs); /* append a NULL so the string is properly terminated */ *str = '\0'; @@ -58,3 +66,7 @@ mp_err mp_toradix(const mp_int *a, char *str, int radix) } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_toradix_n.c b/src/ltm/bn_mp_toradix_n.c index bb8af882..84431f21 100644 --- a/src/ltm/bn_mp_toradix_n.c +++ b/src/ltm/bn_mp_toradix_n.c @@ -1,16 +1,24 @@ #include "tommath_private.h" #ifdef BN_MP_TORADIX_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* stores a bignum as a ASCII string in a given radix (2..64) * * Stores upto maxlen-1 chars and always a NULL byte */ -mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) +int mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) { - int digs; - mp_err err; + int res, digs; mp_int t; mp_digit d; char *_s = str; @@ -21,14 +29,14 @@ mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) } /* quick out if its zero */ - if (MP_IS_ZERO(a)) { + if (mp_iszero(a) == MP_YES) { *str++ = '0'; *str = '\0'; return MP_OKAY; } - if ((err = mp_init_copy(&t, a)) != MP_OKAY) { - return err; + if ((res = mp_init_copy(&t, a)) != MP_OKAY) { + return res; } /* if it is negative output a - */ @@ -45,14 +53,14 @@ mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) } digs = 0; - while (!MP_IS_ZERO(&t)) { + while (mp_iszero(&t) == MP_NO) { if (--maxlen < 1) { /* no more room */ break; } - if ((err = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) { + if ((res = mp_div_d(&t, (mp_digit)radix, &t, &d)) != MP_OKAY) { mp_clear(&t); - return err; + return res; } *str++ = mp_s_rmap[d]; ++digs; @@ -61,7 +69,7 @@ mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) /* reverse the digits of the string. In this case _s points * to the first digit [exluding the sign] of the number */ - s_mp_reverse((unsigned char *)_s, digs); + bn_reverse((unsigned char *)_s, digs); /* append a NULL so the string is properly terminated */ *str = '\0'; @@ -71,3 +79,7 @@ mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_unsigned_bin_size.c b/src/ltm/bn_mp_unsigned_bin_size.c index 297de92d..d716c8f1 100644 --- a/src/ltm/bn_mp_unsigned_bin_size.c +++ b/src/ltm/bn_mp_unsigned_bin_size.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_MP_UNSIGNED_BIN_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* get the size for an unsigned equivalent */ int mp_unsigned_bin_size(const mp_int *a) @@ -10,3 +19,7 @@ int mp_unsigned_bin_size(const mp_int *a) return (size / 8) + ((((unsigned)size & 7u) != 0u) ? 1 : 0); } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_xor.c b/src/ltm/bn_mp_xor.c index 71e7ca18..bfcdbb90 100644 --- a/src/ltm/bn_mp_xor.c +++ b/src/ltm/bn_mp_xor.c @@ -1,56 +1,48 @@ #include "tommath_private.h" #ifdef BN_MP_XOR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* two complement xor */ -mp_err mp_xor(const mp_int *a, const mp_int *b, mp_int *c) +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* XOR two ints together */ +int mp_xor(const mp_int *a, const mp_int *b, mp_int *c) { - int used = MP_MAX(a->used, b->used) + 1, i; - mp_err err; - mp_digit ac = 1, bc = 1, cc = 1; - mp_sign csign = (a->sign != b->sign) ? MP_NEG : MP_ZPOS; - - if (c->alloc < used) { - if ((err = mp_grow(c, used)) != MP_OKAY) { - return err; - } - } - - for (i = 0; i < used; i++) { - mp_digit x, y; + int res, ix, px; + mp_int t; + const mp_int *x; - /* convert to two complement if negative */ - if (a->sign == MP_NEG) { - ac += (i >= a->used) ? MP_MASK : (~a->dp[i] & MP_MASK); - x = ac & MP_MASK; - ac >>= MP_DIGIT_BIT; - } else { - x = (i >= a->used) ? 0uL : a->dp[i]; + if (a->used > b->used) { + if ((res = mp_init_copy(&t, a)) != MP_OKAY) { + return res; } - - /* convert to two complement if negative */ - if (b->sign == MP_NEG) { - bc += (i >= b->used) ? MP_MASK : (~b->dp[i] & MP_MASK); - y = bc & MP_MASK; - bc >>= MP_DIGIT_BIT; - } else { - y = (i >= b->used) ? 0uL : b->dp[i]; - } - - c->dp[i] = x ^ y; - - /* convert to to sign-magnitude if negative */ - if (csign == MP_NEG) { - cc += ~c->dp[i] & MP_MASK; - c->dp[i] = cc & MP_MASK; - cc >>= MP_DIGIT_BIT; + px = b->used; + x = b; + } else { + if ((res = mp_init_copy(&t, b)) != MP_OKAY) { + return res; } + px = a->used; + x = a; } - c->used = used; - c->sign = csign; - mp_clamp(c); + for (ix = 0; ix < px; ix++) { + t.dp[ix] ^= x->dp[ix]; + } + mp_clamp(&t); + mp_exch(c, &t); + mp_clear(&t); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_mp_zero.c b/src/ltm/bn_mp_zero.c index 72a255ef..89f7c291 100644 --- a/src/ltm/bn_mp_zero.c +++ b/src/ltm/bn_mp_zero.c @@ -1,13 +1,33 @@ #include "tommath_private.h" #ifdef BN_MP_ZERO_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* set to zero */ void mp_zero(mp_int *a) { + int n; + mp_digit *tmp; + a->sign = MP_ZPOS; a->used = 0; - MP_ZERO_DIGITS(a->dp, a->alloc); + + tmp = a->dp; + for (n = 0; n < a->alloc; n++) { + *tmp++ = 0; + } } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_prime_tab.c b/src/ltm/bn_prime_tab.c index 008e9c38..5c0e1929 100644 --- a/src/ltm/bn_prime_tab.c +++ b/src/ltm/bn_prime_tab.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_PRIME_TAB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ const mp_digit ltm_prime_tab[] = { 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, @@ -43,19 +52,8 @@ const mp_digit ltm_prime_tab[] = { 0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653 #endif }; - -#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 301) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -const mp_digit *s_mp_prime_tab = ltm_prime_tab; -#pragma GCC diagnostic pop -#elif defined(_MSC_VER) && _MSC_VER >= 1500 -#pragma warning(push) -#pragma warning(disable: 4996) -const mp_digit *s_mp_prime_tab = ltm_prime_tab; -#pragma warning(pop) -#else -const mp_digit *s_mp_prime_tab = ltm_prime_tab; #endif -#endif +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_reverse.c b/src/ltm/bn_reverse.c new file mode 100644 index 00000000..29905287 --- /dev/null +++ b/src/ltm/bn_reverse.c @@ -0,0 +1,35 @@ +#include "tommath_private.h" +#ifdef BN_REVERSE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* reverse an array, used for radix code */ +void bn_reverse(unsigned char *s, int len) +{ + int ix, iy; + unsigned char t; + + ix = 0; + iy = len - 1; + while (ix < iy) { + t = s[ix]; + s[ix] = s[iy]; + s[iy] = t; + ++ix; + --iy; + } +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_add.c b/src/ltm/bn_s_mp_add.c index c946aa80..979e4708 100644 --- a/src/ltm/bn_s_mp_add.c +++ b/src/ltm/bn_s_mp_add.c @@ -1,14 +1,22 @@ #include "tommath_private.h" #ifdef BN_S_MP_ADD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* low level addition, based on HAC pp.594, Algorithm 14.7 */ -mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) +int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) { const mp_int *x; - mp_err err; - int olduse, min, max; + int olduse, res, min, max; /* find sizes, we let |a| <= |b| which means we have to sort * them. "x" will point to the input with the most digits @@ -25,8 +33,8 @@ mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) /* init result */ if (c->alloc < (max + 1)) { - if ((err = mp_grow(c, max + 1)) != MP_OKAY) { - return err; + if ((res = mp_grow(c, max + 1)) != MP_OKAY) { + return res; } } @@ -56,7 +64,7 @@ mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) *tmpc = *tmpa++ + *tmpb++ + u; /* U = carry bit of T[i] */ - u = *tmpc >> (mp_digit)MP_DIGIT_BIT; + u = *tmpc >> (mp_digit)DIGIT_BIT; /* take away carry bit from T[i] */ *tmpc++ &= MP_MASK; @@ -71,7 +79,7 @@ mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) *tmpc = x->dp[i] + u; /* U = carry bit of T[i] */ - u = *tmpc >> (mp_digit)MP_DIGIT_BIT; + u = *tmpc >> (mp_digit)DIGIT_BIT; /* take away carry bit from T[i] */ *tmpc++ &= MP_MASK; @@ -82,10 +90,16 @@ mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) *tmpc++ = u; /* clear digits above oldused */ - MP_ZERO_DIGITS(tmpc, olduse - c->used); + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } } mp_clamp(c); return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_balance_mul.c b/src/ltm/bn_s_mp_balance_mul.c deleted file mode 100644 index efc1809f..00000000 --- a/src/ltm/bn_s_mp_balance_mul.c +++ /dev/null @@ -1,79 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_S_MP_BALANCE_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* single-digit multiplication with the smaller number as the single-digit */ -mp_err s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c) -{ - int count, len_a, len_b, nblocks, i, j, bsize; - mp_int a0, tmp, A, B, r; - mp_err err; - - len_a = a->used; - len_b = b->used; - - nblocks = MP_MAX(a->used, b->used) / MP_MIN(a->used, b->used); - bsize = MP_MIN(a->used, b->used) ; - - if ((err = mp_init_size(&a0, bsize + 2)) != MP_OKAY) { - return err; - } - if ((err = mp_init_multi(&tmp, &r, NULL)) != MP_OKAY) { - mp_clear(&a0); - return err; - } - - /* Make sure that A is the larger one*/ - if (len_a < len_b) { - B = *a; - A = *b; - } else { - A = *a; - B = *b; - } - - for (i = 0, j=0; i < nblocks; i++) { - /* Cut a slice off of a */ - a0.used = 0; - for (count = 0; count < bsize; count++) { - a0.dp[count] = A.dp[ j++ ]; - a0.used++; - } - /* Multiply with b */ - if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) { - goto LBL_ERR; - } - /* Shift tmp to the correct position */ - if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) { - goto LBL_ERR; - } - /* Add to output. No carry needed */ - if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) { - goto LBL_ERR; - } - } - /* The left-overs; there are always left-overs */ - if (j < A.used) { - a0.used = 0; - for (count = 0; j < A.used; count++) { - a0.dp[count] = A.dp[ j++ ]; - a0.used++; - } - if ((err = mp_mul(&a0, &B, &tmp)) != MP_OKAY) { - goto LBL_ERR; - } - if ((err = mp_lshd(&tmp, bsize * i)) != MP_OKAY) { - goto LBL_ERR; - } - if ((err = mp_add(&r, &tmp, &r)) != MP_OKAY) { - goto LBL_ERR; - } - } - - mp_exch(&r,c); -LBL_ERR: - mp_clear_multi(&a0, &tmp, &r,NULL); - return err; -} -#endif diff --git a/src/ltm/bn_s_mp_exptmod.c b/src/ltm/bn_s_mp_exptmod.c index 5d5510fc..b22cde87 100644 --- a/src/ltm/bn_s_mp_exptmod.c +++ b/src/ltm/bn_s_mp_exptmod.c @@ -1,7 +1,16 @@ #include "tommath_private.h" #ifdef BN_S_MP_EXPTMOD_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ #ifdef MP_LOW_MEM # define TAB_SIZE 32 @@ -9,13 +18,12 @@ # define TAB_SIZE 256 #endif -mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) +int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) { mp_int M[TAB_SIZE], res, mu; mp_digit buf; - mp_err err; - int bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; - mp_err(*redux)(mp_int *x, const mp_int *m, const mp_int *mu); + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; + int (*redux)(mp_int *x, const mp_int *m, const mp_int *mu); /* find window size */ x = mp_count_bits(X); @@ -142,11 +150,11 @@ mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y } /* read next digit and reset the bitcnt */ buf = X->dp[digidx--]; - bitcnt = (int)MP_DIGIT_BIT; + bitcnt = (int)DIGIT_BIT; } /* grab the next msb from the exponent */ - y = (buf >> (mp_digit)(MP_DIGIT_BIT - 1)) & 1uL; + y = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1; buf <<= (mp_digit)1; /* if the bit is zero and mode == 0 then we ignore it @@ -238,3 +246,7 @@ LBL_M: return err; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_get_bit.c b/src/ltm/bn_s_mp_get_bit.c deleted file mode 100644 index 28598dfe..00000000 --- a/src/ltm/bn_s_mp_get_bit.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_S_MP_GET_BIT_C - -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* Get bit at position b and return MP_YES if the bit is 1, MP_NO if it is 0 */ -mp_bool s_mp_get_bit(const mp_int *a, unsigned int b) -{ - mp_digit bit; - int limb = (int)(b / MP_DIGIT_BIT); - - if (limb >= a->used) { - return MP_NO; - } - - bit = (mp_digit)1 << (b % MP_DIGIT_BIT); - return ((a->dp[limb] & bit) != 0u) ? MP_YES : MP_NO; -} - -#endif diff --git a/src/ltm/bn_s_mp_mul_digs.c b/src/ltm/bn_s_mp_mul_digs.c index 64509d4c..332e974d 100644 --- a/src/ltm/bn_s_mp_mul_digs.c +++ b/src/ltm/bn_s_mp_mul_digs.c @@ -1,29 +1,38 @@ #include "tommath_private.h" #ifdef BN_S_MP_MUL_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* multiplies |a| * |b| and only computes upto digs digits of result * HAC pp. 595, Algorithm 14.12 Modified so you can control how * many digits of output are created. */ -mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) +int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) { mp_int t; - mp_err err; - int pa, pb, ix, iy; + int res, pa, pb, ix, iy; mp_digit u; mp_word r; mp_digit tmpx, *tmpt, *tmpy; /* can we use the fast multiplier? */ - if ((digs < MP_WARRAY) && - (MP_MIN(a->used, b->used) < MP_MAXFAST)) { - return s_mp_mul_digs_fast(a, b, c, digs); + if ((digs < (int)MP_WARRAY) && + (MIN(a->used, b->used) < + (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { + return fast_s_mp_mul_digs(a, b, c, digs); } - if ((err = mp_init_size(&t, digs)) != MP_OKAY) { - return err; + if ((res = mp_init_size(&t, digs)) != MP_OKAY) { + return res; } t.used = digs; @@ -34,7 +43,7 @@ mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) u = 0; /* limit ourselves to making digs digits of output */ - pb = MP_MIN(b->used, digs - ix); + pb = MIN(b->used, digs - ix); /* setup some aliases */ /* copy of the digit from a used within the nested loop */ @@ -57,7 +66,7 @@ mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); /* get the carry word from the result */ - u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } /* set carry if it is placed below digs */ if ((ix + iy) < digs) { @@ -72,3 +81,7 @@ mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_mul_high_digs.c b/src/ltm/bn_s_mp_mul_high_digs.c index e5e1ba47..509682b7 100644 --- a/src/ltm/bn_s_mp_mul_high_digs.c +++ b/src/ltm/bn_s_mp_mul_high_digs.c @@ -1,30 +1,38 @@ #include "tommath_private.h" #ifdef BN_S_MP_MUL_HIGH_DIGS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* multiplies |a| * |b| and does not compute the lower digs digits * [meant to get the higher part of the product] */ -mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) +int s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) { - mp_int t; - int pa, pb, ix, iy; - mp_err err; + mp_int t; + int res, pa, pb, ix, iy; mp_digit u; - mp_word r; + mp_word r; mp_digit tmpx, *tmpt, *tmpy; /* can we use the fast multiplier? */ -#ifdef BN_S_MP_MUL_HIGH_DIGS_FAST_C - if (((a->used + b->used + 1) < MP_WARRAY) - && (MP_MIN(a->used, b->used) < MP_MAXFAST)) { - return s_mp_mul_high_digs_fast(a, b, c, digs); +#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C + if (((a->used + b->used + 1) < (int)MP_WARRAY) + && (MIN(a->used, b->used) < (int)(1u << (((size_t)CHAR_BIT * sizeof(mp_word)) - (2u * (size_t)DIGIT_BIT))))) { + return fast_s_mp_mul_high_digs(a, b, c, digs); } #endif - if ((err = mp_init_size(&t, a->used + b->used + 1)) != MP_OKAY) { - return err; + if ((res = mp_init_size(&t, a->used + b->used + 1)) != MP_OKAY) { + return res; } t.used = a->used + b->used + 1; @@ -53,7 +61,7 @@ mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); /* carry the carry */ - u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } *tmpt = u; } @@ -63,3 +71,7 @@ mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_prime_is_divisible.c b/src/ltm/bn_s_mp_prime_is_divisible.c deleted file mode 100644 index ffd5093e..00000000 --- a/src/ltm/bn_s_mp_prime_is_divisible.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_S_MP_PRIME_IS_DIVISIBLE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* determines if an integers is divisible by one - * of the first PRIME_SIZE primes or not - * - * sets result to 0 if not, 1 if yes - */ -mp_err s_mp_prime_is_divisible(const mp_int *a, mp_bool *result) -{ - int ix; - mp_err err; - mp_digit res; - - /* default to not */ - *result = MP_NO; - - for (ix = 0; ix < PRIVATE_MP_PRIME_TAB_SIZE; ix++) { - /* what is a mod LBL_prime_tab[ix] */ - if ((err = mp_mod_d(a, s_mp_prime_tab[ix], &res)) != MP_OKAY) { - return err; - } - - /* is the residue zero? */ - if (res == 0u) { - *result = MP_YES; - return MP_OKAY; - } - } - - return MP_OKAY; -} -#endif diff --git a/src/ltm/bn_s_mp_rand_jenkins.c b/src/ltm/bn_s_mp_rand_jenkins.c deleted file mode 100644 index 7564c776..00000000 --- a/src/ltm/bn_s_mp_rand_jenkins.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_S_MP_RAND_JENKINS_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* Bob Jenkins' http://burtleburtle.net/bob/rand/smallprng.html */ -/* Chosen for speed and a good "mix" */ -typedef struct { - unsigned long long a; - unsigned long long b; - unsigned long long c; - unsigned long long d; -} ranctx; - -static ranctx jenkins_x; - -#define rot(x,k) (((x)<<(k))|((x)>>(64-(k)))) -static unsigned long long s_rand_jenkins_val(void) -{ - unsigned long long e = jenkins_x.a - rot(jenkins_x.b, 7); - jenkins_x.a = jenkins_x.b ^ rot(jenkins_x.c, 13); - jenkins_x.b = jenkins_x.c + rot(jenkins_x.d, 37); - jenkins_x.c = jenkins_x.d + e; - jenkins_x.d = e + jenkins_x.a; - return jenkins_x.d; -} - -void s_mp_rand_jenkins_init(unsigned long long seed) -{ - unsigned long long i; - jenkins_x.a = 0xf1ea5eedULL; - jenkins_x.b = jenkins_x.c = jenkins_x.d = seed; - for (i = 0uLL; i < 20uLL; ++i) { - (void)s_rand_jenkins_val(); - } -} - -mp_err s_mp_rand_jenkins(void *p, size_t n) -{ - char *q = (char *)p; - while (n > 0u) { - int i; - unsigned long long x = s_rand_jenkins_val(); - for (i = 0; (i < 8) && (n > 0u); ++i, --n) { - *q++ = (char)(x & 0xFFuLL); - x >>= 8; - } - } - return MP_OKAY; -} - -#endif diff --git a/src/ltm/bn_s_mp_rand_platform.c b/src/ltm/bn_s_mp_rand_platform.c deleted file mode 100644 index 1349b7c6..00000000 --- a/src/ltm/bn_s_mp_rand_platform.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_S_MP_RAND_PLATFORM_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* First the OS-specific special cases - * - *BSD - * - Windows - */ -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) -# define MP_ARC4RANDOM -#endif - -#if defined(_WIN32) || defined(_WIN32_WCE) -#define MP_WIN_CSP - -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0400 -#endif -#ifdef _WIN32_WCE -#define UNDER_CE -#define ARM -#endif - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning (disable : 4668) -#endif -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <wincrypt.h> -#ifdef _MSC_VER -# pragma warning(pop) -#endif - -static mp_err s_read_win_csp(void *p, size_t n) -{ - static HCRYPTPROV hProv = 0; - if (hProv == 0) { - HCRYPTPROV h = 0; - if (!CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL, - (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && - !CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) { - return MP_ERR; - } - hProv = h; - } - return CryptGenRandom(hProv, (DWORD)n, (BYTE *)p) == TRUE ? MP_OKAY : MP_ERR; -} -#endif /* WIN32 */ - -#if !defined(MP_WIN_CSP) && defined(__linux__) && defined(__GLIBC_PREREQ) -#if __GLIBC_PREREQ(2, 25) -#define MP_GETRANDOM -#include <sys/random.h> -#include <errno.h> - -static mp_err s_read_getrandom(void *p, size_t n) -{ - char *q = (char *)p; - while (n > 0u) { - ssize_t ret = getrandom(q, n, 0); - if (ret < 0) { - if (errno == EINTR) { - continue; - } - return MP_ERR; - } - q += ret; - n -= (size_t)ret; - } - return MP_OKAY; -} -#endif -#endif - -/* We assume all platforms besides windows provide "/dev/urandom". - * In case yours doesn't, define MP_NO_DEV_URANDOM at compile-time. - */ -#if !defined(MP_WIN_CSP) && !defined(MP_NO_DEV_URANDOM) -#ifndef MP_DEV_URANDOM -#define MP_DEV_URANDOM "/dev/urandom" -#endif -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> - -static mp_err s_read_dev_urandom(void *p, size_t n) -{ - int fd; - char *q = (char *)p; - - do { - fd = open(MP_DEV_URANDOM, O_RDONLY); - } while ((fd == -1) && (errno == EINTR)); - if (fd == -1) return MP_ERR; - - while (n > 0u) { - ssize_t ret = read(fd, p, n); - if (ret < 0) { - if (errno == EINTR) { - continue; - } - close(fd); - return MP_ERR; - } - q += ret; - n -= (size_t)ret; - } - - close(fd); - return MP_OKAY; -} -#endif - -#if defined(MP_PRNG_ENABLE_LTM_RNG) -unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void)); -void (*ltm_rng_callback)(void); - -static mp_err s_read_ltm_rng(void *p, size_t n) -{ - unsigned long res; - if (ltm_rng == NULL) return MP_ERR; - res = ltm_rng(p, n, ltm_rng_callback); - if (res != n) return MP_ERR; - return MP_OKAY; -} -#endif - -mp_err s_mp_rand_platform(void *p, size_t n) -{ -#if defined(MP_ARC4RANDOM) - arc4random_buf(p, n); - return MP_OKAY; -#else - - mp_err res = MP_ERR; - -#if defined(MP_WIN_CSP) - res = s_read_win_csp(p, n); - if (res == MP_OKAY) return res; -#endif - -#if defined(MP_GETRANDOM) - res = s_read_getrandom(p, n); - if (res == MP_OKAY) return res; -#endif - -#if defined(MP_DEV_URANDOM) - res = s_read_dev_urandom(p, n); - if (res == MP_OKAY) return res; -#endif - -#if defined(MP_PRNG_ENABLE_LTM_RNG) - res = s_read_ltm_rng(p, n); - if (res == MP_OKAY) return res; -#endif - - return res; -#endif -} - -#endif diff --git a/src/ltm/bn_s_mp_reverse.c b/src/ltm/bn_s_mp_reverse.c deleted file mode 100644 index 92b0f1fc..00000000 --- a/src/ltm/bn_s_mp_reverse.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_S_MP_REVERSE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* reverse an array, used for radix code */ -void s_mp_reverse(unsigned char *s, int len) -{ - int ix, iy; - unsigned char t; - - ix = 0; - iy = len - 1; - while (ix < iy) { - t = s[ix]; - s[ix] = s[iy]; - s[iy] = t; - ++ix; - --iy; - } -} -#endif diff --git a/src/ltm/bn_s_mp_sqr.c b/src/ltm/bn_s_mp_sqr.c index 505c9f05..b3d0fd06 100644 --- a/src/ltm/bn_s_mp_sqr.c +++ b/src/ltm/bn_s_mp_sqr.c @@ -1,20 +1,28 @@ #include "tommath_private.h" #ifdef BN_S_MP_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ -mp_err s_mp_sqr(const mp_int *a, mp_int *b) +int s_mp_sqr(const mp_int *a, mp_int *b) { - mp_int t; - int ix, iy, pa; - mp_err err; - mp_word r; + mp_int t; + int res, ix, iy, pa; + mp_word r; mp_digit u, tmpx, *tmpt; pa = a->used; - if ((err = mp_init_size(&t, (2 * pa) + 1)) != MP_OKAY) { - return err; + if ((res = mp_init_size(&t, (2 * pa) + 1)) != MP_OKAY) { + return res; } /* default used is maximum possible size */ @@ -30,7 +38,7 @@ mp_err s_mp_sqr(const mp_int *a, mp_int *b) t.dp[ix+ix] = (mp_digit)(r & (mp_word)MP_MASK); /* get the carry */ - u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); /* left hand side of A[ix] * A[iy] */ tmpx = a->dp[ix]; @@ -51,13 +59,13 @@ mp_err s_mp_sqr(const mp_int *a, mp_int *b) *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); /* get carry */ - u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } /* propagate upwards */ while (u != 0uL) { r = (mp_word)*tmpt + (mp_word)u; *tmpt++ = (mp_digit)(r & (mp_word)MP_MASK); - u = (mp_digit)(r >> (mp_word)MP_DIGIT_BIT); + u = (mp_digit)(r >> (mp_word)DIGIT_BIT); } } @@ -67,3 +75,7 @@ mp_err s_mp_sqr(const mp_int *a, mp_int *b) return MP_OKAY; } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_sub.c b/src/ltm/bn_s_mp_sub.c index 5672dab5..88e44dc1 100644 --- a/src/ltm/bn_s_mp_sub.c +++ b/src/ltm/bn_s_mp_sub.c @@ -1,13 +1,21 @@ #include "tommath_private.h" #ifdef BN_S_MP_SUB_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ -mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) +int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) { - int olduse, min, max; - mp_err err; + int olduse, res, min, max; /* find sizes */ min = b->used; @@ -15,8 +23,8 @@ mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) /* init result */ if (c->alloc < max) { - if ((err = mp_grow(c, max)) != MP_OKAY) { - return err; + if ((res = mp_grow(c, max)) != MP_OKAY) { + return res; } } olduse = c->used; @@ -42,7 +50,7 @@ mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) * if a carry does occur it will propagate all the way to the * MSB. As a result a single shift is enough to get the carry */ - u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); + u = *tmpc >> (((size_t)CHAR_BIT * sizeof(mp_digit)) - 1u); /* Clear carry from T[i] */ *tmpc++ &= MP_MASK; @@ -54,14 +62,16 @@ mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) *tmpc = *tmpa++ - u; /* U = carry bit of T[i] */ - u = *tmpc >> (MP_SIZEOF_BITS(mp_digit) - 1u); + u = *tmpc >> (((size_t)CHAR_BIT * sizeof(mp_digit)) - 1u); /* Clear carry from T[i] */ *tmpc++ &= MP_MASK; } /* clear digits above used (since we may not have grown result above) */ - MP_ZERO_DIGITS(tmpc, olduse - c->used); + for (i = c->used; i < olduse; i++) { + *tmpc++ = 0; + } } mp_clamp(c); @@ -69,3 +79,7 @@ mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) } #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/bn_s_mp_toom_mul.c b/src/ltm/bn_s_mp_toom_mul.c deleted file mode 100644 index ce47f250..00000000 --- a/src/ltm/bn_s_mp_toom_mul.c +++ /dev/null @@ -1,270 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_S_MP_TOOM_MUL_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* multiplication using the Toom-Cook 3-way algorithm - * - * Much more complicated than Karatsuba but has a lower - * asymptotic running time of O(N**1.464). This algorithm is - * only particularly useful on VERY large inputs - * (we're talking 1000s of digits here...). -*/ - -/* - This file contains code from J. Arndt's book "Matters Computational" - and the accompanying FXT-library with permission of the author. -*/ - -/* - Setup from - - Chung, Jaewook, and M. Anwar Hasan. "Asymmetric squaring formulae." - 18th IEEE Symposium on Computer Arithmetic (ARITH'07). IEEE, 2007. - - The interpolation from above needed one temporary variable more - than the interpolation here: - - Bodrato, Marco, and Alberto Zanoni. "What about Toom-Cook matrices optimality." - Centro Vito Volterra Universita di Roma Tor Vergata (2006) -*/ - -mp_err s_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c) -{ - mp_int S1, S2, T1, a0, a1, a2, b0, b1, b2; - int err, B, count; - - /* init temps */ - if ((err = mp_init_multi(&S1, &S2, &T1, NULL)) != MP_OKAY) { - return err; - } - - /* B */ - B = MP_MIN(a->used, b->used) / 3; - - /** a = a2 * x^2 + a1 * x + a0; */ - if ((err = mp_init_size(&a0, B)) != MP_OKAY) { - goto LTM_ERRa0; - } - for (count = 0; count < B; count++) { - a0.dp[count] = a->dp[count]; - a0.used++; - } - mp_clamp(&a0); - if ((err = mp_init_size(&a1, B)) != MP_OKAY) { - goto LTM_ERRa1; - } - for (; count < (2 * B); count++) { - a1.dp[count - B] = a->dp[count]; - a1.used++; - } - mp_clamp(&a1); - if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) { - goto LTM_ERRa2; - } - for (; count < a->used; count++) { - a2.dp[count - (2 * B)] = a->dp[count]; - a2.used++; - } - - /** b = b2 * x^2 + b1 * x + b0; */ - if ((err = mp_init_size(&b0, B)) != MP_OKAY) { - goto LTM_ERRb0; - } - for (count = 0; count < B; count++) { - b0.dp[count] = b->dp[count]; - b0.used++; - } - mp_clamp(&b0); - if ((err = mp_init_size(&b1, B)) != MP_OKAY) { - goto LTM_ERRb1; - } - for (; count < (2 * B); count++) { - b1.dp[count - B] = b->dp[count]; - b1.used++; - } - mp_clamp(&b1); - if ((err = mp_init_size(&b2, B + (b->used - (3 * B)))) != MP_OKAY) { - goto LTM_ERRb2; - } - for (; count < b->used; count++) { - b2.dp[count - (2 * B)] = b->dp[count]; - b2.used++; - } - - /** \\ S1 = (a2+a1+a0) * (b2+b1+b0); */ - /** T1 = a2 + a1; */ - if ((err = mp_add(&a2, &a1, &T1)) != MP_OKAY) { - goto LTM_ERR; - } - /** S2 = T1 + a0; */ - if ((err = mp_add(&T1, &a0, &S2)) != MP_OKAY) { - goto LTM_ERR; - } - /** c = b2 + b1; */ - if ((err = mp_add(&b2, &b1, c)) != MP_OKAY) { - goto LTM_ERR; - } - /** S1 = c + b0; */ - if ((err = mp_add(c, &b0, &S1)) != MP_OKAY) { - goto LTM_ERR; - } - /** S1 = S1 * S2; */ - if ((err = mp_mul(&S1, &S2, &S1)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S2 = (4*a2+2*a1+a0) * (4*b2+2*b1+b0); */ - /** T1 = T1 + a2; */ - if ((err = mp_add(&T1, &a2, &T1)) != MP_OKAY) { - goto LTM_ERR; - } - /** T1 = T1 << 1; */ - if ((err = mp_mul_2(&T1, &T1)) != MP_OKAY) { - goto LTM_ERR; - } - /** T1 = T1 + a0; */ - if ((err = mp_add(&T1, &a0, &T1)) != MP_OKAY) { - goto LTM_ERR; - } - /** c = c + b2; */ - if ((err = mp_add(c, &b2, c)) != MP_OKAY) { - goto LTM_ERR; - } - /** c = c << 1; */ - if ((err = mp_mul_2(c, c)) != MP_OKAY) { - goto LTM_ERR; - } - /** c = c + b0; */ - if ((err = mp_add(c, &b0, c)) != MP_OKAY) { - goto LTM_ERR; - } - /** S2 = T1 * c; */ - if ((err = mp_mul(&T1, c, &S2)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S3 = (a2-a1+a0) * (b2-b1+b0); */ - /** a1 = a2 - a1; */ - if ((err = mp_sub(&a2, &a1, &a1)) != MP_OKAY) { - goto LTM_ERR; - } - /** a1 = a1 + a0; */ - if ((err = mp_add(&a1, &a0, &a1)) != MP_OKAY) { - goto LTM_ERR; - } - /** b1 = b2 - b1; */ - if ((err = mp_sub(&b2, &b1, &b1)) != MP_OKAY) { - goto LTM_ERR; - } - /** b1 = b1 + b0; */ - if ((err = mp_add(&b1, &b0, &b1)) != MP_OKAY) { - goto LTM_ERR; - } - /** a1 = a1 * b1; */ - if ((err = mp_mul(&a1, &b1, &a1)) != MP_OKAY) { - goto LTM_ERR; - } - /** b1 = a2 * b2; */ - if ((err = mp_mul(&a2, &b2, &b1)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S2 = (S2 - S3)/3; */ - /** S2 = S2 - a1; */ - if ((err = mp_sub(&S2, &a1, &S2)) != MP_OKAY) { - goto LTM_ERR; - } - /** S2 = S2 / 3; \\ this is an exact division */ - if ((err = mp_div_3(&S2, &S2, NULL)) != MP_OKAY) { - goto LTM_ERR; - } - /** a1 = S1 - a1; */ - if ((err = mp_sub(&S1, &a1, &a1)) != MP_OKAY) { - goto LTM_ERR; - } - /** a1 = a1 >> 1; */ - if ((err = mp_div_2(&a1, &a1)) != MP_OKAY) { - goto LTM_ERR; - } - /** a0 = a0 * b0; */ - if ((err = mp_mul(&a0, &b0, &a0)) != MP_OKAY) { - goto LTM_ERR; - } - /** S1 = S1 - a0; */ - if ((err = mp_sub(&S1, &a0, &S1)) != MP_OKAY) { - goto LTM_ERR; - } - /** S2 = S2 - S1; */ - if ((err = mp_sub(&S2, &S1, &S2)) != MP_OKAY) { - goto LTM_ERR; - } - /** S2 = S2 >> 1; */ - if ((err = mp_div_2(&S2, &S2)) != MP_OKAY) { - goto LTM_ERR; - } - /** S1 = S1 - a1; */ - if ((err = mp_sub(&S1, &a1, &S1)) != MP_OKAY) { - goto LTM_ERR; - } - /** S1 = S1 - b1; */ - if ((err = mp_sub(&S1, &b1, &S1)) != MP_OKAY) { - goto LTM_ERR; - } - /** T1 = b1 << 1; */ - if ((err = mp_mul_2(&b1, &T1)) != MP_OKAY) { - goto LTM_ERR; - } - /** S2 = S2 - T1; */ - if ((err = mp_sub(&S2, &T1, &S2)) != MP_OKAY) { - goto LTM_ERR; - } - /** a1 = a1 - S2; */ - if ((err = mp_sub(&a1, &S2, &a1)) != MP_OKAY) { - goto LTM_ERR; - } - - /** P = b1*x^4+ S2*x^3+ S1*x^2+ a1*x + a0; */ - if ((err = mp_lshd(&b1, 4 * B)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_lshd(&S2, 3 * B)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_add(&b1, &S2, &b1)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_lshd(&S1, 2 * B)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_add(&b1, &S1, &b1)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_lshd(&a1, 1 * B)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_add(&b1, &a1, &b1)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_add(&b1, &a0, c)) != MP_OKAY) { - goto LTM_ERR; - } - - /** a * b - P */ - - -LTM_ERR: - mp_clear(&b2); -LTM_ERRb2: - mp_clear(&b1); -LTM_ERRb1: - mp_clear(&b0); -LTM_ERRb0: - mp_clear(&a2); -LTM_ERRa2: - mp_clear(&a1); -LTM_ERRa1: - mp_clear(&a0); -LTM_ERRa0: - mp_clear_multi(&S1, &S2, &T1, NULL); - return err; -} - -#endif diff --git a/src/ltm/bn_s_mp_toom_sqr.c b/src/ltm/bn_s_mp_toom_sqr.c deleted file mode 100644 index a6bf85e9..00000000 --- a/src/ltm/bn_s_mp_toom_sqr.c +++ /dev/null @@ -1,194 +0,0 @@ -#include "tommath_private.h" -#ifdef BN_S_MP_TOOM_SQR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - -/* squaring using Toom-Cook 3-way algorithm */ - -/* - This file contains code from J. Arndt's book "Matters Computational" - and the accompanying FXT-library with permission of the author. -*/ - -/* squaring using Toom-Cook 3-way algorithm */ -/* - Setup and interpolation from algorithm SQR_3 in - - Chung, Jaewook, and M. Anwar Hasan. "Asymmetric squaring formulae." - 18th IEEE Symposium on Computer Arithmetic (ARITH'07). IEEE, 2007. - -*/ -mp_err s_mp_toom_sqr(const mp_int *a, mp_int *b) -{ - mp_int S0, a0, a1, a2; - mp_digit *tmpa, *tmpc; - mp_err err, B, count; - - - /* init temps */ - if ((err = mp_init(&S0)) != MP_OKAY) { - return err; - } - - /* B */ - B = a->used / 3; - - /** a = a2 * x^2 + a1 * x + a0; */ - if ((err = mp_init_size(&a0, B)) != MP_OKAY) { - goto LTM_ERRa0; - } - a0.used = B; - if ((err = mp_init_size(&a1, B)) != MP_OKAY) { - goto LTM_ERRa1; - } - a1.used = B; - if ((err = mp_init_size(&a2, B + (a->used - (3 * B)))) != MP_OKAY) { - goto LTM_ERRa2; - } - tmpa = a->dp; - tmpc = a0.dp; - for (count = 0; count < B; count++) { - *tmpc++ = *tmpa++; - } - tmpc = a1.dp; - for (; count < (2 * B); count++) { - *tmpc++ = *tmpa++; - } - tmpc = a2.dp; - for (; count < a->used; count++) { - *tmpc++ = *tmpa++; - a2.used++; - } - mp_clamp(&a0); - mp_clamp(&a1); - - /** S0 = a0^2; */ - if ((err = mp_sqr(&a0, &S0)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S1 = (a2 + a1 + a0)^2 */ - /** \\S2 = (a2 - a1 + a0)^2 */ - /** \\S1 = a0 + a2; */ - /** a0 = a0 + a2; */ - if ((err = mp_add(&a0, &a2, &a0)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S2 = S1 - a1; */ - /** b = a0 - a1; */ - if ((err = mp_sub(&a0, &a1, b)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S1 = S1 + a1; */ - /** a0 = a0 + a1; */ - if ((err = mp_add(&a0, &a1, &a0)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S1 = S1^2; */ - /** a0 = a0^2; */ - if ((err = mp_sqr(&a0, &a0)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S2 = S2^2; */ - /** b = b^2; */ - if ((err = mp_sqr(b, b)) != MP_OKAY) { - goto LTM_ERR; - } - - /** \\ S3 = 2 * a1 * a2 */ - /** \\S3 = a1 * a2; */ - /** a1 = a1 * a2; */ - if ((err = mp_mul(&a1, &a2, &a1)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S3 = S3 << 1; */ - /** a1 = a1 << 1; */ - if ((err = mp_mul_2(&a1, &a1)) != MP_OKAY) { - goto LTM_ERR; - } - - /** \\S4 = a2^2; */ - /** a2 = a2^2; */ - if ((err = mp_sqr(&a2, &a2)) != MP_OKAY) { - goto LTM_ERR; - } - - /** \\ tmp = (S1 + S2)/2 */ - /** \\tmp = S1 + S2; */ - /** b = a0 + b; */ - if ((err = mp_add(&a0, b, b)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\tmp = tmp >> 1; */ - /** b = b >> 1; */ - if ((err = mp_div_2(b, b)) != MP_OKAY) { - goto LTM_ERR; - } - - /** \\ S1 = S1 - tmp - S3 */ - /** \\S1 = S1 - tmp; */ - /** a0 = a0 - b; */ - if ((err = mp_sub(&a0, b, &a0)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S1 = S1 - S3; */ - /** a0 = a0 - a1; */ - if ((err = mp_sub(&a0, &a1, &a0)) != MP_OKAY) { - goto LTM_ERR; - } - - /** \\S2 = tmp - S4 -S0 */ - /** \\S2 = tmp - S4; */ - /** b = b - a2; */ - if ((err = mp_sub(b, &a2, b)) != MP_OKAY) { - goto LTM_ERR; - } - /** \\S2 = S2 - S0; */ - /** b = b - S0; */ - if ((err = mp_sub(b, &S0, b)) != MP_OKAY) { - goto LTM_ERR; - } - - - /** \\P = S4*x^4 + S3*x^3 + S2*x^2 + S1*x + S0; */ - /** P = a2*x^4 + a1*x^3 + b*x^2 + a0*x + S0; */ - - if ((err = mp_lshd(&a2, 4 * B)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_lshd(&a1, 3 * B)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_lshd(b, 2 * B)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_lshd(&a0, 1 * B)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_add(&a2, &a1, &a2)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_add(&a2, b, b)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_add(b, &a0, b)) != MP_OKAY) { - goto LTM_ERR; - } - if ((err = mp_add(b, &S0, b)) != MP_OKAY) { - goto LTM_ERR; - } - /** a^2 - P */ - - -LTM_ERR: - mp_clear(&a2); -LTM_ERRa2: - mp_clear(&a1); -LTM_ERRa1: - mp_clear(&a0); -LTM_ERRa0: - mp_clear(&S0); - - return err; -} - -#endif diff --git a/src/ltm/bncore.c b/src/ltm/bncore.c new file mode 100644 index 00000000..c97b8e19 --- /dev/null +++ b/src/ltm/bncore.c @@ -0,0 +1,33 @@ +#include "tommath_private.h" +#ifdef BNCORE_C +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ + +/* Known optimal configurations + + CPU /Compiler /MUL CUTOFF/SQR CUTOFF +------------------------------------------------------------- + Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-) + AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35 + +*/ + +int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */ + KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */ + + TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ + TOOM_SQR_CUTOFF = 400; +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/tommath.h b/src/ltm/tommath.h index b92a7426..f8051a2a 100644 --- a/src/ltm/tommath.h +++ b/src/ltm/tommath.h @@ -1,27 +1,29 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ #ifndef BN_H_ #define BN_H_ - +#include <stdio.h> +#include <stdlib.h> #include <limits.h> -#ifdef LTM_NO_FILE -# warning LTM_NO_FILE has been deprecated, use MP_NO_FILE. -# define MP_NO_FILE -#endif - -#ifndef MP_NO_FILE -# include <stdio.h> -#endif +#include "tommath_class.h" #ifdef __cplusplus extern "C" { #endif /* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */ -#if (defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__)) && !defined(MP_64BIT) +#if defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__) # define MP_32BIT #endif @@ -32,7 +34,7 @@ extern "C" { defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \ defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \ defined(__LP64__) || defined(_LP64) || defined(__64BIT__) -# if !(defined(MP_64BIT) || defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT)) +# if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT)) # if defined(__GNUC__) && !defined(__hppa) /* we support 128bit integers only via: __attribute__((mode(TI))) */ # define MP_64BIT @@ -43,119 +45,95 @@ extern "C" { # endif #endif -#ifdef MP_DIGIT_BIT -# error Defining MP_DIGIT_BIT is disallowed, use MP_8/16/31/32/64BIT -#endif - /* some default configurations. * - * A "mp_digit" must be able to hold MP_DIGIT_BIT + 1 bits - * A "mp_word" must be able to hold 2*MP_DIGIT_BIT + 1 bits + * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits + * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits * * At the very least a mp_digit must be able to hold 7 bits * [any size beyond that is ok provided it doesn't overflow the data type] */ - #ifdef MP_8BIT -typedef unsigned char mp_digit; -typedef unsigned short private_mp_word; -# define MP_DIGIT_BIT 7 +typedef unsigned char mp_digit; +typedef unsigned short mp_word; +# define MP_SIZEOF_MP_DIGIT 1 +# ifdef DIGIT_BIT +# error You must not define DIGIT_BIT when using MP_8BIT +# endif #elif defined(MP_16BIT) -typedef unsigned short mp_digit; -typedef unsigned int private_mp_word; -# define MP_DIGIT_BIT 15 +typedef unsigned short mp_digit; +typedef unsigned int mp_word; +# define MP_SIZEOF_MP_DIGIT 2 +# ifdef DIGIT_BIT +# error You must not define DIGIT_BIT when using MP_16BIT +# endif #elif defined(MP_64BIT) /* for GCC only on supported platforms */ -typedef unsigned long long mp_digit; -#if defined(__GNUC__) -typedef unsigned long private_mp_word __attribute__((mode(TI))); -#endif -# define MP_DIGIT_BIT 60 +typedef unsigned long long mp_digit; +typedef unsigned long mp_word __attribute__((mode(TI))); +# define DIGIT_BIT 60 +#else +/* this is the default case, 28-bit digits */ + +/* this is to make porting into LibTomCrypt easier :-) */ +typedef unsigned int mp_digit; +#ifdef _MSC_VER +typedef unsigned __int64 mp_word; #else -typedef unsigned int mp_digit; -typedef unsigned long long private_mp_word; +typedef unsigned long long mp_word; /* PATCHED */ +#endif + # ifdef MP_31BIT -/* - * This is an extension that uses 31-bit digits. - * Please be aware that not all functions support this size, especially s_mp_mul_digs_fast - * will be reduced to work on small numbers only: - * Up to 8 limbs, 248 bits instead of up to 512 limbs, 15872 bits with MP_28BIT. - */ -# define MP_DIGIT_BIT 31 +/* this is an extension that uses 31-bit digits */ +# define DIGIT_BIT 31 # else /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */ -# define MP_DIGIT_BIT 28 +# define DIGIT_BIT 28 # define MP_28BIT # endif #endif -/* mp_word is a private type */ -#define mp_word MP_DEPRECATED_PRAGMA("mp_word has been made private") private_mp_word - -#define MP_SIZEOF_MP_DIGIT (MP_DEPRECATED_PRAGMA("MP_SIZEOF_MP_DIGIT has been deprecated, use sizeof (mp_digit)") sizeof (mp_digit)) +/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */ +#ifndef DIGIT_BIT +# define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */ +typedef unsigned long mp_min_u32; +#else +typedef mp_digit mp_min_u32; +#endif -#define MP_MASK ((((mp_digit)1)<<((mp_digit)MP_DIGIT_BIT))-((mp_digit)1)) +#define MP_DIGIT_BIT DIGIT_BIT +#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) #define MP_DIGIT_MAX MP_MASK -/* Primality generation flags */ -#define MP_PRIME_BBS 0x0001 /* BBS style prime */ -#define MP_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ -#define MP_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ - -#define LTM_PRIME_BBS (MP_DEPRECATED_PRAGMA("LTM_PRIME_BBS has been deprecated, use MP_PRIME_BBS") MP_PRIME_BBS) -#define LTM_PRIME_SAFE (MP_DEPRECATED_PRAGMA("LTM_PRIME_SAFE has been deprecated, use MP_PRIME_SAFE") MP_PRIME_SAFE) -#define LTM_PRIME_2MSB_ON (MP_DEPRECATED_PRAGMA("LTM_PRIME_2MSB_ON has been deprecated, use MP_PRIME_2MSB_ON") MP_PRIME_2MSB_ON) - -#ifdef MP_USE_ENUMS -typedef enum { - MP_ZPOS = 0, - MP_NEG = 1 -} mp_sign; -typedef enum { - MP_LT = -1, - MP_EQ = 0, - MP_GT = 1 -} mp_ord; -typedef enum { - MP_NO = 0, - MP_YES = 1 -} mp_bool; -typedef enum { - MP_OKAY = 0, - MP_ERR = -1, - MP_MEM = -2, - MP_VAL = -3, - MP_ITER = -4 -} mp_err; -#else -typedef int mp_sign; -#define MP_ZPOS 0 /* positive integer */ -#define MP_NEG 1 /* negative */ -typedef int mp_ord; +/* equalities */ #define MP_LT -1 /* less than */ #define MP_EQ 0 /* equal to */ #define MP_GT 1 /* greater than */ -typedef int mp_bool; -#define MP_YES 1 /* yes response */ -#define MP_NO 0 /* no response */ -typedef int mp_err; + +#define MP_ZPOS 0 /* positive integer */ +#define MP_NEG 1 /* negative */ + #define MP_OKAY 0 /* ok result */ -#define MP_ERR -1 /* unknown error */ #define MP_MEM -2 /* out of mem */ #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_RANGE MP_VAL #define MP_ITER -4 /* Max. iterations reached */ -#endif -/* tunable cutoffs */ +#define MP_YES 1 /* yes response */ +#define MP_NO 0 /* no response */ -#ifndef MP_FIXED_CUTOFFS -extern int -KARATSUBA_MUL_CUTOFF, -KARATSUBA_SQR_CUTOFF, -TOOM_MUL_CUTOFF, -TOOM_SQR_CUTOFF; -#endif +/* Primality generation flags */ +#define LTM_PRIME_BBS 0x0001 /* BBS style prime */ +#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ +#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ + +typedef int mp_err; + +/* you'll have to tune these... */ +extern int KARATSUBA_MUL_CUTOFF, + KARATSUBA_SQR_CUTOFF, + TOOM_MUL_CUTOFF, + TOOM_SQR_CUTOFF; /* define this to use lower memory usage routines (exptmods mostly) */ /* #define MP_LOW_MEM */ @@ -163,177 +141,113 @@ TOOM_SQR_CUTOFF; /* default precision */ #ifndef MP_PREC # ifndef MP_LOW_MEM -# define PRIVATE_MP_PREC 32 /* default digits of precision */ -# elif defined(MP_8BIT) -# define PRIVATE_MP_PREC 16 /* default digits of precision */ +# define MP_PREC 32 /* default digits of precision */ # else -# define PRIVATE_MP_PREC 8 /* default digits of precision */ +# define MP_PREC 8 /* default digits of precision */ # endif -# define MP_PREC (MP_DEPRECATED_PRAGMA("MP_PREC is an internal macro") PRIVATE_MP_PREC) #endif /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */ -#define PRIVATE_MP_WARRAY (int)(1uLL << (((CHAR_BIT * sizeof(private_mp_word)) - (2 * MP_DIGIT_BIT)) + 1)) -#define MP_WARRAY (MP_DEPRECATED_PRAGMA("MP_WARRAY is an internal macro") PRIVATE_MP_WARRAY) - -#if defined(__GNUC__) && __GNUC__ >= 4 -# define MP_NULL_TERMINATED __attribute__((sentinel)) -#else -# define MP_NULL_TERMINATED -#endif - -/* - * MP_WUR - warn unused result - * --------------------------- - * - * The result of functions annotated with MP_WUR must be - * checked and cannot be ignored. - * - * Most functions in libtommath return an error code. - * This error code must be checked in order to prevent crashes or invalid - * results. - * - * If you still want to avoid the error checks for quick and dirty programs - * without robustness guarantees, you can `#define MP_WUR` before including - * tommath.h, disabling the warnings. - */ -#ifndef MP_WUR -# if defined(__GNUC__) && __GNUC__ >= 4 -# define MP_WUR __attribute__((warn_unused_result)) -# else -# define MP_WUR -# endif -#endif - -#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 301) -# define MP_DEPRECATED(x) __attribute__((deprecated("replaced by " #x))) -# define PRIVATE_MP_DEPRECATED_PRAGMA(s) _Pragma(#s) -# define MP_DEPRECATED_PRAGMA(s) PRIVATE_MP_DEPRECATED_PRAGMA(GCC warning s) -#elif defined(_MSC_VER) && _MSC_VER >= 1500 -# define MP_DEPRECATED(x) __declspec(deprecated("replaced by " #x)) -# define MP_DEPRECATED_PRAGMA(s) __pragma(message(s)) -#else -# define MP_DEPRECATED(s) -# define MP_DEPRECATED_PRAGMA(s) -#endif - -#define DIGIT_BIT (MP_DEPRECATED_PRAGMA("DIGIT_BIT macro is deprecated, MP_DIGIT_BIT instead") MP_DIGIT_BIT) -#define USED(m) (MP_DEPRECATED_PRAGMA("USED macro is deprecated, use z->used instead") (m)->used) -#define DIGIT(m, k) (MP_DEPRECATED_PRAGMA("DIGIT macro is deprecated, use z->dp instead") (m)->dp[(k)]) -#define SIGN(m) (MP_DEPRECATED_PRAGMA("SIGN macro is deprecated, use z->sign instead") (m)->sign) +#define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1)) /* the infamous mp_int structure */ typedef struct { - int used, alloc; - mp_sign sign; + int used, alloc, sign; mp_digit *dp; } mp_int; /* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */ -typedef int private_mp_prime_callback(unsigned char *dst, int len, void *dat); -typedef private_mp_prime_callback MP_DEPRECATED(mp_rand_source) ltm_prime_callback; +typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); + + +#define USED(m) ((m)->used) +#define DIGIT(m, k) ((m)->dp[(k)]) +#define SIGN(m) ((m)->sign) /* error code to char* string */ -const char *mp_error_to_string(mp_err code) MP_WUR; +const char *mp_error_to_string(int code); /* ---> init and deinit bignum functions <--- */ /* init a bignum */ -mp_err mp_init(mp_int *a) MP_WUR; +int mp_init(mp_int *a); /* free a bignum */ void mp_clear(mp_int *a); /* init a null terminated series of arguments */ -mp_err mp_init_multi(mp_int *mp, ...) MP_NULL_TERMINATED MP_WUR; +int mp_init_multi(mp_int *mp, ...); /* clear a null terminated series of arguments */ -void mp_clear_multi(mp_int *mp, ...) MP_NULL_TERMINATED; +void mp_clear_multi(mp_int *mp, ...); /* exchange two ints */ void mp_exch(mp_int *a, mp_int *b); /* shrink ram required for a bignum */ -mp_err mp_shrink(mp_int *a) MP_WUR; +int mp_shrink(mp_int *a); /* grow an int to a given size */ -mp_err mp_grow(mp_int *a, int size) MP_WUR; +int mp_grow(mp_int *a, int size); /* init to a given number of digits */ -mp_err mp_init_size(mp_int *a, int size) MP_WUR; +int mp_init_size(mp_int *a, int size); /* ---> Basic Manipulations <--- */ #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) -mp_bool mp_iseven(const mp_int *a) MP_WUR; -mp_bool mp_isodd(const mp_int *a) MP_WUR; +#define mp_iseven(a) ((((a)->used == 0) || (((a)->dp[0] & 1u) == 0u)) ? MP_YES : MP_NO) +#define mp_isodd(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 1u)) ? MP_YES : MP_NO) #define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO) /* set to zero */ void mp_zero(mp_int *a); -/* get and set doubles */ -double mp_get_double(const mp_int *a) MP_WUR; -mp_err mp_set_double(mp_int *a, double b) MP_WUR; +/* set to a digit */ +void mp_set(mp_int *a, mp_digit b); -/* get integer, set integer and init with integer (int) */ -int mp_get_i32(const mp_int *a) MP_WUR; -void mp_set_i32(mp_int *a, int b); -mp_err mp_init_i32(mp_int *a, int b) MP_WUR; +/* set a double */ +int mp_set_double(mp_int *a, double b); -/* get integer, set integer and init with integer, behaves like two complement for negative numbers (unsigned int) */ -#define mp_get_u32(a) ((unsigned int)mp_get_i32(a)) -void mp_set_u32(mp_int *a, unsigned int b); -mp_err mp_init_u32(mp_int *a, unsigned int b) MP_WUR; +/* set a 32-bit const */ +int mp_set_int(mp_int *a, unsigned long b); -/* get integer, set integer and init with integer (long long) */ -long long mp_get_i64(const mp_int *a) MP_WUR; -void mp_set_i64(mp_int *a, long long b); -mp_err mp_init_i64(mp_int *a, long long b) MP_WUR; +/* set a platform dependent unsigned long value */ +int mp_set_long(mp_int *a, unsigned long b); -/* get integer, set integer and init with integer, behaves like two complement for negative numbers (unsigned long long) */ -#define mp_get_u64(a) ((unsigned long long)mp_get_i64(a)) -void mp_set_u64(mp_int *a, unsigned long long b); -mp_err mp_init_u64(mp_int *a, unsigned long long b) MP_WUR; +/* set a platform dependent unsigned long long value */ +/* int mp_set_long_long(mp_int *a, unsigned long long b); */ -/* get magnitude */ -unsigned int mp_get_mag32(const mp_int *a) MP_WUR; -unsigned long long mp_get_mag64(const mp_int *a) MP_WUR; +/* get a double */ +double mp_get_double(const mp_int *a); -/* get integer, set integer (long) */ -#define mp_get_l(a) (sizeof (long) == 8 ? (long)mp_get_i64(a) : (long)mp_get_i32(a)) -#define mp_set_l(a, b) (sizeof (long) == 8 ? mp_set_i64((a), (b)) : mp_set_i32((a), (int)(b))) +/* get a 32-bit value */ +unsigned long mp_get_int(const mp_int *a); -/* get integer, set integer (unsigned long) */ -#define mp_get_ul(a) (sizeof (long) == 8 ? (unsigned long)mp_get_u64(a) : (unsigned long)mp_get_u32(a)) -#define mp_set_ul(a, b) (sizeof (long) == 8 ? mp_set_u64((a), (b)) : mp_set_u32((a), (unsigned int)(b))) -#define mp_get_magl(a) (sizeof (long) == 8 ? (unsigned long)mp_get_mag64(a) : (unsigned long)mp_get_mag32(a)) +/* get a platform dependent unsigned long value */ +unsigned long mp_get_long(const mp_int *a); -/* set to single unsigned digit, up to MP_DIGIT_MAX */ -void mp_set(mp_int *a, mp_digit b); -mp_err mp_init_set(mp_int *a, mp_digit b) MP_WUR; +/* get a platform dependent unsigned long long value */ +/* unsigned long long mp_get_long_long(const mp_int *a); */ + +/* initialize and set a digit */ +int mp_init_set(mp_int *a, mp_digit b); -/* get integer, set integer and init with integer (deprecated) */ -MP_DEPRECATED(mp_get_mag32/mp_get_u32) unsigned long mp_get_int(const mp_int *a) MP_WUR; -MP_DEPRECATED(mp_get_magl/mp_get_ul) unsigned long mp_get_long(const mp_int *a) MP_WUR; -MP_DEPRECATED(mp_get_mag64/mp_get_u64) unsigned long long mp_get_long_long(const mp_int *a) MP_WUR; -MP_DEPRECATED(mp_set_u32) mp_err mp_set_int(mp_int *a, unsigned long b); -MP_DEPRECATED(mp_set_ul) mp_err mp_set_long(mp_int *a, unsigned long b); -MP_DEPRECATED(mp_set_u64) mp_err mp_set_long_long(mp_int *a, unsigned long long b); -MP_DEPRECATED(mp_init_u32) mp_err mp_init_set_int(mp_int *a, unsigned long b) MP_WUR; +/* initialize and set 32-bit value */ +int mp_init_set_int(mp_int *a, unsigned long b); /* copy, b = a */ -mp_err mp_copy(const mp_int *a, mp_int *b) MP_WUR; +int mp_copy(const mp_int *a, mp_int *b); /* inits and copies, a = b */ -mp_err mp_init_copy(mp_int *a, const mp_int *b) MP_WUR; +int mp_init_copy(mp_int *a, const mp_int *b); /* trim unused digits */ 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; +int mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails, const void *op); /* 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; +int mp_export(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, const mp_int *op); /* ---> digit manipulation <--- */ @@ -341,279 +255,269 @@ mp_err mp_export(void *rop, size_t *countp, int order, size_t size, int endian, void mp_rshd(mp_int *a, int b); /* left shift by "b" digits */ -mp_err mp_lshd(mp_int *a, int b) MP_WUR; +int mp_lshd(mp_int *a, int b); /* c = a / 2**b, implemented as c = a >> b */ -mp_err mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d) MP_WUR; +int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d); /* b = a/2 */ -mp_err mp_div_2(const mp_int *a, mp_int *b) MP_WUR; +int mp_div_2(const mp_int *a, mp_int *b); /* c = a * 2**b, implemented as c = a << b */ -mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c) MP_WUR; +int mp_mul_2d(const mp_int *a, int b, mp_int *c); /* b = a*2 */ -mp_err mp_mul_2(const mp_int *a, mp_int *b) MP_WUR; +int mp_mul_2(const mp_int *a, mp_int *b); /* c = a mod 2**b */ -mp_err mp_mod_2d(const mp_int *a, int b, mp_int *c) MP_WUR; +int mp_mod_2d(const mp_int *a, int b, mp_int *c); /* computes a = 2**b */ -mp_err mp_2expt(mp_int *a, int b) MP_WUR; +int mp_2expt(mp_int *a, int b); /* Counts the number of lsbs which are zero before the first zero bit */ -int mp_cnt_lsb(const mp_int *a) MP_WUR; +int mp_cnt_lsb(const mp_int *a); /* I Love Earth! */ -/* makes a pseudo-random mp_int of a given size */ -mp_err mp_rand(mp_int *a, int digits) MP_WUR; -/* makes a pseudo-random small int of a given size */ -MP_DEPRECATED(mp_rand) mp_err mp_rand_digit(mp_digit *r) MP_WUR; -/* use custom random data source instead of source provided the platform */ -void mp_rand_source(mp_err(*source)(void *out, size_t size)); +/* makes a pseudo-random int of a given size */ +int mp_rand(mp_int *a, int digits); #ifdef MP_PRNG_ENABLE_LTM_RNG -# warning MP_PRNG_ENABLE_LTM_RNG has been deprecated, use mp_rand_source instead. -/* A last resort to provide random data on systems without any of the other - * implemented ways to gather entropy. - * It is compatible with `rng_get_bytes()` from libtomcrypt so you could - * provide that one and then set `ltm_rng = rng_get_bytes;` */ +/* as last resort we will fall back to libtomcrypt's rng_get_bytes() + * in case you don't use libtomcrypt or use it w/o rng_get_bytes() + * you have to implement it somewhere else, as it's required */ extern unsigned long (*ltm_rng)(unsigned char *out, unsigned long outlen, void (*callback)(void)); extern void (*ltm_rng_callback)(void); #endif /* ---> binary operations <--- */ +/* c = a XOR b */ +int mp_xor(const mp_int *a, const mp_int *b, mp_int *c); + +/* c = a OR b */ +int mp_or(const mp_int *a, const mp_int *b, mp_int *c); + +/* c = a AND b */ +int mp_and(const mp_int *a, const mp_int *b, mp_int *c); /* Checks the bit at position b and returns MP_YES - * if the bit is 1, MP_NO if it is 0 and MP_VAL - * in case of error - */ -MP_DEPRECATED(s_mp_get_bit) int mp_get_bit(const mp_int *a, int b) MP_WUR; + if the bit is 1, MP_NO if it is 0 and MP_VAL + in case of error */ +int mp_get_bit(const mp_int *a, int b); /* c = a XOR b (two complement) */ -MP_DEPRECATED(mp_xor) mp_err mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -mp_err mp_xor(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_tc_xor(const mp_int *a, const mp_int *b, mp_int *c); /* c = a OR b (two complement) */ -MP_DEPRECATED(mp_or) mp_err mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -mp_err mp_or(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_tc_or(const mp_int *a, const mp_int *b, mp_int *c); /* c = a AND b (two complement) */ -MP_DEPRECATED(mp_and) mp_err mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -mp_err mp_and(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; - -/* b = ~a (bitwise not, two complement) */ -mp_err mp_complement(const mp_int *a, mp_int *b) MP_WUR; +int mp_tc_and(const mp_int *a, const mp_int *b, mp_int *c); -/* right shift with sign extension */ -MP_DEPRECATED(mp_signed_rsh) mp_err mp_tc_div_2d(const mp_int *a, int b, mp_int *c) MP_WUR; -mp_err mp_signed_rsh(const mp_int *a, int b, mp_int *c) MP_WUR; +/* right shift (two complement) */ +int mp_tc_div_2d(const mp_int *a, int b, mp_int *c); /* ---> Basic arithmetic <--- */ +/* b = ~a */ +int mp_complement(const mp_int *a, mp_int *b); + /* b = -a */ -mp_err mp_neg(const mp_int *a, mp_int *b) MP_WUR; +int mp_neg(const mp_int *a, mp_int *b); /* b = |a| */ -mp_err mp_abs(const mp_int *a, mp_int *b) MP_WUR; +int mp_abs(const mp_int *a, mp_int *b); /* compare a to b */ -mp_ord mp_cmp(const mp_int *a, const mp_int *b) MP_WUR; +int mp_cmp(const mp_int *a, const mp_int *b); /* compare |a| to |b| */ -mp_ord mp_cmp_mag(const mp_int *a, const mp_int *b) MP_WUR; +int mp_cmp_mag(const mp_int *a, const mp_int *b); /* c = a + b */ -mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_add(const mp_int *a, const mp_int *b, mp_int *c); /* c = a - b */ -mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_sub(const mp_int *a, const mp_int *b, mp_int *c); /* c = a * b */ -mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_mul(const mp_int *a, const mp_int *b, mp_int *c); /* b = a*a */ -mp_err mp_sqr(const mp_int *a, mp_int *b) MP_WUR; +int mp_sqr(const mp_int *a, mp_int *b); /* a/b => cb + d == a */ -mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d) MP_WUR; +int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d); /* c = a mod b, 0 <= c < b */ -mp_err mp_mod(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_mod(const mp_int *a, const mp_int *b, mp_int *c); /* ---> single digit functions <--- */ /* compare against a single digit */ -mp_ord mp_cmp_d(const mp_int *a, mp_digit b) MP_WUR; +int mp_cmp_d(const mp_int *a, mp_digit b); /* c = a + b */ -mp_err mp_add_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; - -/* Increment "a" by one like "a++". Changes input! */ -mp_err mp_incr(mp_int *a) MP_WUR; +int mp_add_d(const mp_int *a, mp_digit b, mp_int *c); /* c = a - b */ -mp_err mp_sub_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; - -/* Decrement "a" by one like "a--". Changes input! */ -mp_err mp_decr(mp_int *a) MP_WUR; +int mp_sub_d(const mp_int *a, mp_digit b, mp_int *c); /* c = a * b */ -mp_err mp_mul_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; +int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c); /* a/b => cb + d == a */ -mp_err mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d) MP_WUR; +int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d); /* a/3 => 3c + d == a */ -mp_err mp_div_3(const mp_int *a, mp_int *c, mp_digit *d) MP_WUR; +int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d); /* c = a**b */ -mp_err mp_expt_d(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; -MP_DEPRECATED(mp_expt_d) mp_err mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) MP_WUR; +int mp_expt_d(const mp_int *a, mp_digit b, mp_int *c); +int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast); /* c = a mod b, 0 <= c < b */ -mp_err mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c) MP_WUR; +int mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c); /* ---> number theory <--- */ /* d = a + b (mod c) */ -mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) MP_WUR; +int mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d); /* d = a - b (mod c) */ -mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) MP_WUR; +int mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d); /* d = a * b (mod c) */ -mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d) MP_WUR; +int mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d); /* c = a * a (mod b) */ -mp_err mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c); /* c = 1/a (mod b) */ -mp_err mp_invmod(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_invmod(const mp_int *a, const mp_int *b, mp_int *c); /* c = (a, b) */ -mp_err mp_gcd(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_gcd(const mp_int *a, const mp_int *b, mp_int *c); /* produces value such that U1*a + U2*b = U3 */ -mp_err mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) MP_WUR; +int mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3); /* c = [a, b] or (a*b)/(a, b) */ -mp_err mp_lcm(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; +int mp_lcm(const mp_int *a, const mp_int *b, mp_int *c); /* finds one of the b'th root of a, such that |c|**b <= |a| * * returns error if a < 0 and b is even */ -mp_err mp_n_root(const mp_int *a, mp_digit b, mp_int *c) MP_WUR; -MP_DEPRECATED(mp_n_root_ex) mp_err mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast) MP_WUR; +int mp_n_root(const mp_int *a, mp_digit b, mp_int *c); +int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast); /* special sqrt algo */ -mp_err mp_sqrt(const mp_int *arg, mp_int *ret) MP_WUR; +int mp_sqrt(const mp_int *arg, mp_int *ret); /* special sqrt (mod prime) */ -mp_err mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret) MP_WUR; +int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret); /* is number a square? */ -mp_err mp_is_square(const mp_int *arg, mp_bool *ret) MP_WUR; +int mp_is_square(const mp_int *arg, int *ret); /* computes the jacobi c = (a | n) (or Legendre if b is prime) */ -MP_DEPRECATED(mp_kronecker) mp_err mp_jacobi(const mp_int *a, const mp_int *n, int *c) MP_WUR; +int mp_jacobi(const mp_int *a, const mp_int *n, int *c); /* computes the Kronecker symbol c = (a | p) (like jacobi() but with {a,p} in Z */ -mp_err mp_kronecker(const mp_int *a, const mp_int *p, int *c) MP_WUR; +int mp_kronecker(const mp_int *a, const mp_int *p, int *c); /* used to setup the Barrett reduction for a given modulus b */ -mp_err mp_reduce_setup(mp_int *a, const mp_int *b) MP_WUR; +int mp_reduce_setup(mp_int *a, const mp_int *b); /* Barrett Reduction, computes a (mod b) with a precomputed value c * * Assumes that 0 < x <= m*m, note if 0 > x > -(m*m) then you can merely * compute the reduction as -1 * mp_reduce(mp_abs(x)) [pseudo code]. */ -mp_err mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu) MP_WUR; +int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu); /* setups the montgomery reduction */ -mp_err mp_montgomery_setup(const mp_int *n, mp_digit *rho) MP_WUR; +int mp_montgomery_setup(const mp_int *n, mp_digit *rho); /* computes a = B**n mod b without division or multiplication useful for * normalizing numbers in a Montgomery system. */ -mp_err mp_montgomery_calc_normalization(mp_int *a, const mp_int *b) MP_WUR; +int mp_montgomery_calc_normalization(mp_int *a, const mp_int *b); /* computes x/R == x (mod N) via Montgomery Reduction */ -mp_err mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho) MP_WUR; +int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho); /* returns 1 if a is a valid DR modulus */ -mp_bool mp_dr_is_modulus(const mp_int *a) MP_WUR; +int mp_dr_is_modulus(const mp_int *a); /* sets the value of "d" required for mp_dr_reduce */ void mp_dr_setup(const mp_int *a, mp_digit *d); /* reduces a modulo n using the Diminished Radix method */ -mp_err mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k) MP_WUR; +int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k); /* returns true if a can be reduced with mp_reduce_2k */ -mp_bool mp_reduce_is_2k(const mp_int *a) MP_WUR; +int mp_reduce_is_2k(const mp_int *a); /* determines k value for 2k reduction */ -mp_err mp_reduce_2k_setup(const mp_int *a, mp_digit *d) MP_WUR; +int mp_reduce_2k_setup(const mp_int *a, mp_digit *d); /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ -mp_err mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d) MP_WUR; +int mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d); /* returns true if a can be reduced with mp_reduce_2k_l */ -mp_bool mp_reduce_is_2k_l(const mp_int *a) MP_WUR; +int mp_reduce_is_2k_l(const mp_int *a); /* determines k value for 2k reduction */ -mp_err mp_reduce_2k_setup_l(const mp_int *a, mp_int *d) MP_WUR; +int mp_reduce_2k_setup_l(const mp_int *a, mp_int *d); /* reduces a modulo b where b is of the form 2**p - k [0 <= a] */ -mp_err mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d) MP_WUR; +int mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d); /* Y = G**X (mod P) */ -mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) MP_WUR; +int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y); /* ---> Primes <--- */ /* number of primes */ #ifdef MP_8BIT -# define PRIVATE_MP_PRIME_TAB_SIZE 31 +# define PRIME_SIZE 31 #else -# define PRIVATE_MP_PRIME_TAB_SIZE 256 +# define PRIME_SIZE 256 #endif -#define PRIME_SIZE (MP_DEPRECATED_PRAGMA("PRIME_SIZE has been made internal") PRIVATE_MP_PRIME_TAB_SIZE) /* table of first PRIME_SIZE primes */ -MP_DEPRECATED(internal) extern const mp_digit ltm_prime_tab[PRIVATE_MP_PRIME_TAB_SIZE]; +extern const mp_digit ltm_prime_tab[PRIME_SIZE]; /* result=1 if a is divisible by one of the first PRIME_SIZE primes */ -MP_DEPRECATED(mp_prime_is_prime) mp_err mp_prime_is_divisible(const mp_int *a, mp_bool *result) MP_WUR; +int mp_prime_is_divisible(const mp_int *a, int *result); /* performs one Fermat test of "a" using base "b". * Sets result to 0 if composite or 1 if probable prime */ -mp_err mp_prime_fermat(const mp_int *a, const mp_int *b, mp_bool *result) MP_WUR; +int mp_prime_fermat(const mp_int *a, const mp_int *b, int *result); /* performs one Miller-Rabin test of "a" using base "b". * Sets result to 0 if composite or 1 if probable prime */ -mp_err mp_prime_miller_rabin(const mp_int *a, const mp_int *b, mp_bool *result) MP_WUR; +int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result); /* This gives [for a given bit size] the number of trials required * such that Miller-Rabin gives a prob of failure lower than 2^-96 */ -int mp_prime_rabin_miller_trials(int size) MP_WUR; +int mp_prime_rabin_miller_trials(int size); /* performs one strong Lucas-Selfridge test of "a". * Sets result to 0 if composite or 1 if probable prime */ -mp_err mp_prime_strong_lucas_selfridge(const mp_int *a, mp_bool *result) MP_WUR; +int mp_prime_strong_lucas_selfridge(const mp_int *a, int *result); /* performs one Frobenius test of "a" as described by Paul Underwood. * Sets result to 0 if composite or 1 if probable prime */ -mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) MP_WUR; +int mp_prime_frobenius_underwood(const mp_int *N, int *result); /* performs t random rounds of Miller-Rabin on "a" additional to * bases 2 and 3. Also performs an initial sieve of trial @@ -629,14 +533,14 @@ mp_err mp_prime_frobenius_underwood(const mp_int *N, mp_bool *result) MP_WUR; * * Sets result to 1 if probably prime, 0 otherwise */ -mp_err mp_prime_is_prime(const mp_int *a, int t, mp_bool *result) MP_WUR; +int mp_prime_is_prime(const mp_int *a, int t, int *result); /* finds the next prime after the number "a" using "t" trials * of Miller-Rabin. * * bbs_style = 1 means the prime must be congruent to 3 mod 4 */ -mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) MP_WUR; +int mp_prime_next_prime(mp_int *a, int t, int bbs_style); /* makes a truly random prime of a given size (bytes), * call with bbs = 1 if you want it to be congruent to 3 mod 4 @@ -647,57 +551,52 @@ mp_err mp_prime_next_prime(mp_int *a, int t, int bbs_style) MP_WUR; * * The prime generated will be larger than 2^(8*size). */ -#define mp_prime_random(a, t, size, bbs, cb, dat) (MP_DEPRECATED_PRAGMA("mp_prime_random has been deprecated, use mp_prime_rand instead") mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?MP_PRIME_BBS:0, cb, dat)) +#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) /* makes a truly random prime of a given size (bits), * * Flags are as follows: * - * MP_PRIME_BBS - make prime congruent to 3 mod 4 - * MP_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies MP_PRIME_BBS) - * MP_PRIME_2MSB_ON - make the 2nd highest bit one + * LTM_PRIME_BBS - make prime congruent to 3 mod 4 + * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS) + * LTM_PRIME_2MSB_ON - make the 2nd highest bit one * * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself * so it can be NULL * */ -MP_DEPRECATED(mp_prime_rand) mp_err mp_prime_random_ex(mp_int *a, int t, int size, int flags, - private_mp_prime_callback cb, void *dat) MP_WUR; -mp_err mp_prime_rand(mp_int *a, int t, int size, int flags) MP_WUR; - -/* Integer logarithm to integer base */ -mp_err mp_ilogb(const mp_int *a, mp_digit base, mp_int *c) MP_WUR; +int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat); /* ---> radix conversion <--- */ -int mp_count_bits(const mp_int *a) MP_WUR; - -int mp_unsigned_bin_size(const mp_int *a) MP_WUR; -mp_err mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c) MP_WUR; -mp_err mp_to_unsigned_bin(const mp_int *a, unsigned char *b) MP_WUR; -mp_err mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) MP_WUR; - -int mp_signed_bin_size(const mp_int *a) MP_WUR; -mp_err mp_read_signed_bin(mp_int *a, const unsigned char *b, int c) MP_WUR; -mp_err mp_to_signed_bin(const mp_int *a, unsigned char *b) MP_WUR; -mp_err mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen) MP_WUR; - -mp_err mp_read_radix(mp_int *a, const char *str, int radix) MP_WUR; -mp_err mp_toradix(const mp_int *a, char *str, int radix) MP_WUR; -mp_err mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen) MP_WUR; -mp_err mp_radix_size(const mp_int *a, int radix, int *size) MP_WUR; - -#ifndef MP_NO_FILE -mp_err mp_fread(mp_int *a, int radix, FILE *stream) MP_WUR; -mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) MP_WUR; +int mp_count_bits(const mp_int *a); + +int mp_unsigned_bin_size(const mp_int *a); +int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c); +int mp_to_unsigned_bin(const mp_int *a, unsigned char *b); +int mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen); + +int mp_signed_bin_size(const mp_int *a); +int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c); +int mp_to_signed_bin(const mp_int *a, unsigned char *b); +int mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen); + +int mp_read_radix(mp_int *a, const char *str, int radix); +int mp_toradix(const mp_int *a, char *str, int radix); +int mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen); +int mp_radix_size(const mp_int *a, int radix, int *size); + +#ifndef LTM_NO_FILE +int mp_fread(mp_int *a, int radix, FILE *stream); +int mp_fwrite(const mp_int *a, int radix, FILE *stream); #endif -#define mp_read_raw(mp, str, len) (MP_DEPRECATED_PRAGMA("replaced by mp_read_signed_bin") mp_read_signed_bin((mp), (str), (len))) -#define mp_raw_size(mp) (MP_DEPRECATED_PRAGMA("replaced by mp_signed_bin_size") mp_signed_bin_size(mp)) -#define mp_toraw(mp, str) (MP_DEPRECATED_PRAGMA("replaced by mp_to_signed_bin") mp_to_signed_bin((mp), (str))) -#define mp_read_mag(mp, str, len) (MP_DEPRECATED_PRAGMA("replaced by mp_read_unsigned_bin") mp_read_unsigned_bin((mp), (str), (len)) -#define mp_mag_size(mp) (MP_DEPRECATED_PRAGMA("replaced by mp_unsigned_bin_size") mp_unsigned_bin_size(mp)) -#define mp_tomag(mp, str) (MP_DEPRECATED_PRAGMA("replaced by mp_to_unsigned_bin") mp_to_unsigned_bin((mp), (str))) +#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) +#define mp_raw_size(mp) mp_signed_bin_size(mp) +#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) +#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) +#define mp_mag_size(mp) mp_unsigned_bin_size(mp) +#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) #define mp_tobinary(M, S) mp_toradix((M), (S), 2) #define mp_tooctal(M, S) mp_toradix((M), (S), 8) @@ -709,3 +608,8 @@ mp_err mp_fwrite(const mp_int *a, int radix, FILE *stream) MP_WUR; #endif #endif + + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/tommath_class.h b/src/ltm/tommath_class.h index dfc0be13..7dfd838b 100644 --- a/src/ltm/tommath_class.h +++ b/src/ltm/tommath_class.h @@ -1,8 +1,16 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ #if !(defined(LTM1) && defined(LTM2) && defined(LTM3)) -#define LTM_INSIDE #if defined(LTM2) # define LTM3 #endif @@ -10,9 +18,14 @@ # define LTM2 #endif #define LTM1 + #if defined(LTM_ALL) -# define BN_CUTOFFS_C -# define BN_DEPRECATED_C +# define BN_ERROR_C +# define BN_FAST_MP_INVMOD_C +# define BN_FAST_MP_MONTGOMERY_REDUCE_C +# define BN_FAST_S_MP_MUL_DIGS_C +# define BN_FAST_S_MP_MUL_HIGH_DIGS_C +# define BN_FAST_S_MP_SQR_C # define BN_MP_2EXPT_C # define BN_MP_ABS_C # define BN_MP_ADD_C @@ -29,7 +42,6 @@ # define BN_MP_COMPLEMENT_C # define BN_MP_COPY_C # define BN_MP_COUNT_BITS_C -# define BN_MP_DECR_C # define BN_MP_DIV_C # define BN_MP_DIV_2_C # define BN_MP_DIV_2D_C @@ -38,37 +50,35 @@ # define BN_MP_DR_IS_MODULUS_C # define BN_MP_DR_REDUCE_C # 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_D_C +# define BN_MP_EXPT_D_EX_C # define BN_MP_EXPTMOD_C +# define BN_MP_EXPTMOD_FAST_C # define BN_MP_EXTEUCLID_C # define BN_MP_FREAD_C # define BN_MP_FWRITE_C # define BN_MP_GCD_C +# define BN_MP_GET_BIT_C # define BN_MP_GET_DOUBLE_C -# define BN_MP_GET_I32_C -# define BN_MP_GET_I64_C -# define BN_MP_GET_MAG32_C -# define BN_MP_GET_MAG64_C +# define BN_MP_GET_INT_C +# define BN_MP_GET_LONG_C +# define BN_MP_GET_LONG_LONG_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 -# define BN_MP_INIT_I32_C -# define BN_MP_INIT_I64_C # define BN_MP_INIT_MULTI_C # define BN_MP_INIT_SET_C +# define BN_MP_INIT_SET_INT_C # define BN_MP_INIT_SIZE_C -# define BN_MP_INIT_U32_C -# define BN_MP_INIT_U64_C # define BN_MP_INVMOD_C +# define BN_MP_INVMOD_SLOW_C # define BN_MP_IS_SQUARE_C -# define BN_MP_ISEVEN_C -# define BN_MP_ISODD_C +# define BN_MP_JACOBI_C +# define BN_MP_KARATSUBA_MUL_C +# define BN_MP_KARATSUBA_SQR_C # define BN_MP_KRONECKER_C # define BN_MP_LCM_C # define BN_MP_LSHD_C @@ -84,15 +94,17 @@ # define BN_MP_MUL_D_C # define BN_MP_MULMOD_C # define BN_MP_N_ROOT_C +# define BN_MP_N_ROOT_EX_C # define BN_MP_NEG_C # define BN_MP_OR_C # define BN_MP_PRIME_FERMAT_C # define BN_MP_PRIME_FROBENIUS_UNDERWOOD_C +# define BN_MP_PRIME_IS_DIVISIBLE_C # define BN_MP_PRIME_IS_PRIME_C # define BN_MP_PRIME_MILLER_RABIN_C # define BN_MP_PRIME_NEXT_PRIME_C # define BN_MP_PRIME_RABIN_MILLER_TRIALS_C -# define BN_MP_PRIME_RAND_C +# define BN_MP_PRIME_RANDOM_EX_C # define BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C # define BN_MP_RADIX_SIZE_C # define BN_MP_RADIX_SMAP_C @@ -111,13 +123,11 @@ # define BN_MP_RSHD_C # define BN_MP_SET_C # define BN_MP_SET_DOUBLE_C -# define BN_MP_SET_I32_C -# define BN_MP_SET_I64_C -# define BN_MP_SET_U32_C -# define BN_MP_SET_U64_C +# define BN_MP_SET_INT_C +# define BN_MP_SET_LONG_C +# define BN_MP_SET_LONG_LONG_C # define BN_MP_SHRINK_C # define BN_MP_SIGNED_BIN_SIZE_C -# define BN_MP_SIGNED_RSH_C # define BN_MP_SQR_C # define BN_MP_SQRMOD_C # define BN_MP_SQRT_C @@ -125,110 +135,80 @@ # define BN_MP_SUB_C # define BN_MP_SUB_D_C # define BN_MP_SUBMOD_C +# define BN_MP_TC_AND_C +# define BN_MP_TC_DIV_2D_C +# define BN_MP_TC_OR_C +# define BN_MP_TC_XOR_C # define BN_MP_TO_SIGNED_BIN_C # define BN_MP_TO_SIGNED_BIN_N_C # define BN_MP_TO_UNSIGNED_BIN_C # define BN_MP_TO_UNSIGNED_BIN_N_C +# define BN_MP_TOOM_MUL_C +# define BN_MP_TOOM_SQR_C # define BN_MP_TORADIX_C # define BN_MP_TORADIX_N_C # define BN_MP_UNSIGNED_BIN_SIZE_C # define BN_MP_XOR_C # define BN_MP_ZERO_C # define BN_PRIME_TAB_C +# define BN_REVERSE_C # define BN_S_MP_ADD_C -# define BN_S_MP_BALANCE_MUL_C # define BN_S_MP_EXPTMOD_C -# define BN_S_MP_EXPTMOD_FAST_C -# define BN_S_MP_GET_BIT_C -# define BN_S_MP_INVMOD_FAST_C -# define BN_S_MP_INVMOD_SLOW_C -# define BN_S_MP_KARATSUBA_MUL_C -# define BN_S_MP_KARATSUBA_SQR_C -# define BN_S_MP_MONTGOMERY_REDUCE_FAST_C # define BN_S_MP_MUL_DIGS_C -# define BN_S_MP_MUL_DIGS_FAST_C # define BN_S_MP_MUL_HIGH_DIGS_C -# define BN_S_MP_MUL_HIGH_DIGS_FAST_C -# define BN_S_MP_PRIME_IS_DIVISIBLE_C -# define BN_S_MP_RAND_JENKINS_C -# define BN_S_MP_RAND_PLATFORM_C -# define BN_S_MP_REVERSE_C # define BN_S_MP_SQR_C -# define BN_S_MP_SQR_FAST_C # define BN_S_MP_SUB_C -# define BN_S_MP_TOOM_MUL_C -# define BN_S_MP_TOOM_SQR_C -#endif +# define BNCORE_C #endif -#if defined(BN_CUTOFFS_C) + +#if defined(BN_ERROR_C) +# define BN_MP_ERROR_TO_STRING_C #endif -#if defined(BN_DEPRECATED_C) -# define BN_FAST_MP_INVMOD_C -# define BN_FAST_MP_MONTGOMERY_REDUCE_C -# define BN_FAST_S_MP_MUL_DIGS_C -# define BN_FAST_S_MP_MUL_HIGH_DIGS_C -# define BN_FAST_S_MP_SQR_C -# define BN_MP_AND_C -# define BN_MP_BALANCE_MUL_C +#if defined(BN_FAST_MP_INVMOD_C) +# define BN_MP_ISEVEN_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_COPY_C +# define BN_MP_MOD_C +# define BN_MP_ISZERO_C +# define BN_MP_SET_C +# define BN_MP_DIV_2_C +# define BN_MP_ISODD_C +# define BN_MP_SUB_C +# define BN_MP_CMP_C # define BN_MP_CMP_D_C -# define BN_MP_EXPTMOD_FAST_C -# define BN_MP_EXPT_D_C -# define BN_MP_EXPT_D_EX_C -# define BN_MP_GET_BIT_C -# define BN_MP_GET_INT_C -# define BN_MP_GET_LONG_C -# define BN_MP_GET_LONG_LONG_C -# define BN_MP_GET_MAG32_C -# define BN_MP_GET_MAG64_C -# define BN_MP_INIT_SET_INT_C -# define BN_MP_INIT_U32_C -# define BN_MP_INVMOD_SLOW_C -# define BN_MP_JACOBI_C -# define BN_MP_KARATSUBA_MUL_C -# define BN_MP_KARATSUBA_SQR_C -# define BN_MP_KRONECKER_C -# define BN_MP_N_ROOT_C -# define BN_MP_N_ROOT_EX_C -# define BN_MP_OR_C -# define BN_MP_PRIME_IS_DIVISIBLE_C -# define BN_MP_PRIME_RANDOM_EX_C -# define BN_MP_RAND_DIGIT_C -# define BN_MP_SET_INT_C -# define BN_MP_SET_LONG_C -# define BN_MP_SET_LONG_LONG_C -# define BN_MP_SET_U32_C -# define BN_MP_SET_U64_C -# define BN_MP_SIGNED_RSH_C -# define BN_MP_TC_AND_C -# define BN_MP_TC_DIV_2D_C -# define BN_MP_TC_OR_C -# define BN_MP_TC_XOR_C -# define BN_MP_TOOM_MUL_C -# define BN_MP_TOOM_SQR_C -# define BN_MP_XOR_C -# define BN_S_MP_BALANCE_MUL_C -# define BN_S_MP_EXPTMOD_FAST_C -# define BN_S_MP_GET_BIT_C -# define BN_S_MP_INVMOD_FAST_C -# define BN_S_MP_INVMOD_SLOW_C -# define BN_S_MP_KARATSUBA_MUL_C -# define BN_S_MP_KARATSUBA_SQR_C -# define BN_S_MP_MONTGOMERY_REDUCE_FAST_C -# define BN_S_MP_MUL_DIGS_FAST_C -# define BN_S_MP_MUL_HIGH_DIGS_FAST_C -# define BN_S_MP_PRIME_IS_DIVISIBLE_C -# define BN_S_MP_PRIME_RANDOM_EX_C -# define BN_S_MP_RAND_SOURCE_C -# define BN_S_MP_REVERSE_C -# define BN_S_MP_SQR_FAST_C -# define BN_S_MP_TOOM_MUL_C -# define BN_S_MP_TOOM_SQR_C +# define BN_MP_ADD_C +# define BN_MP_CMP_MAG_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_MULTI_C #endif -#if defined(BN_MP_2EXPT_C) +#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C) +# define BN_MP_GROW_C +# define BN_MP_RSHD_C +# define BN_MP_CLAMP_C +# define BN_MP_CMP_MAG_C +# define BN_S_MP_SUB_C +#endif + +#if defined(BN_FAST_S_MP_MUL_DIGS_C) # define BN_MP_GROW_C +# define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C) +# define BN_MP_GROW_C +# define BN_MP_CLAMP_C +#endif + +#if defined(BN_FAST_S_MP_SQR_C) +# define BN_MP_GROW_C +# define BN_MP_CLAMP_C +#endif + +#if defined(BN_MP_2EXPT_C) # define BN_MP_ZERO_C +# define BN_MP_GROW_C #endif #if defined(BN_MP_ABS_C) @@ -236,27 +216,29 @@ #endif #if defined(BN_MP_ADD_C) -# define BN_MP_CMP_MAG_C # define BN_S_MP_ADD_C +# define BN_MP_CMP_MAG_C # define BN_S_MP_SUB_C #endif #if defined(BN_MP_ADD_D_C) -# define BN_MP_CLAMP_C # define BN_MP_GROW_C # define BN_MP_SUB_D_C +# define BN_MP_CLAMP_C #endif #if defined(BN_MP_ADDMOD_C) +# define BN_MP_INIT_C # define BN_MP_ADD_C # define BN_MP_CLEAR_C -# define BN_MP_INIT_C # define BN_MP_MOD_C #endif #if defined(BN_MP_AND_C) +# define BN_MP_INIT_COPY_C # define BN_MP_CLAMP_C -# define BN_MP_GROW_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_CLAMP_C) @@ -280,6 +262,7 @@ #endif #if defined(BN_MP_CNT_LSB_C) +# define BN_MP_ISZERO_C #endif #if defined(BN_MP_COMPLEMENT_C) @@ -294,127 +277,153 @@ #if defined(BN_MP_COUNT_BITS_C) #endif -#if defined(BN_MP_DECR_C) -# define BN_MP_INCR_C -# define BN_MP_SET_C -# define BN_MP_SUB_D_C -# define BN_MP_ZERO_C -#endif - #if defined(BN_MP_DIV_C) -# define BN_MP_ADD_C -# define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C -# define BN_MP_CMP_C +# define BN_MP_ISZERO_C # define BN_MP_CMP_MAG_C # define BN_MP_COPY_C +# define BN_MP_ZERO_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_SET_C # define BN_MP_COUNT_BITS_C +# define BN_MP_ABS_C +# define BN_MP_MUL_2D_C +# define BN_MP_CMP_C +# define BN_MP_SUB_C +# define BN_MP_ADD_C # define BN_MP_DIV_2D_C # define BN_MP_EXCH_C +# define BN_MP_CLEAR_MULTI_C +# define BN_MP_INIT_SIZE_C # define BN_MP_INIT_C # define BN_MP_INIT_COPY_C -# define BN_MP_INIT_SIZE_C # define BN_MP_LSHD_C -# define BN_MP_MUL_2D_C -# define BN_MP_MUL_D_C # define BN_MP_RSHD_C -# define BN_MP_SUB_C -# define BN_MP_ZERO_C +# define BN_MP_MUL_D_C +# define BN_MP_CLAMP_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_DIV_2_C) -# define BN_MP_CLAMP_C # define BN_MP_GROW_C +# define BN_MP_CLAMP_C #endif #if defined(BN_MP_DIV_2D_C) -# define BN_MP_CLAMP_C # define BN_MP_COPY_C +# define BN_MP_ZERO_C # define BN_MP_MOD_2D_C # define BN_MP_RSHD_C -# define BN_MP_ZERO_C +# define BN_MP_CLAMP_C #endif #if defined(BN_MP_DIV_3_C) +# define BN_MP_INIT_SIZE_C # define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C # define BN_MP_EXCH_C -# define BN_MP_INIT_SIZE_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_DIV_D_C) -# define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C +# define BN_MP_ISZERO_C # define BN_MP_COPY_C # define BN_MP_DIV_2D_C # define BN_MP_DIV_3_C -# define BN_MP_EXCH_C # define BN_MP_INIT_SIZE_C +# define BN_MP_CLAMP_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_DR_IS_MODULUS_C) #endif #if defined(BN_MP_DR_REDUCE_C) +# define BN_MP_GROW_C # define BN_MP_CLAMP_C # define BN_MP_CMP_MAG_C -# define BN_MP_GROW_C # define BN_S_MP_SUB_C #endif #if defined(BN_MP_DR_SETUP_C) #endif -#if defined(BN_MP_ERROR_TO_STRING_C) -#endif - #if defined(BN_MP_EXCH_C) #endif #if defined(BN_MP_EXPORT_C) -# define BN_MP_CLEAR_C +# define BN_MP_INIT_COPY_C # define BN_MP_COUNT_BITS_C # define BN_MP_DIV_2D_C -# define BN_MP_INIT_COPY_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_EXPT_D_C) -# define BN_MP_CLEAR_C +# define BN_MP_EXPT_D_EX_C +#endif + +#if defined(BN_MP_EXPT_D_EX_C) # define BN_MP_INIT_COPY_C -# define BN_MP_MUL_C # define BN_MP_SET_C +# define BN_MP_MUL_C +# define BN_MP_CLEAR_C # define BN_MP_SQR_C #endif #if defined(BN_MP_EXPTMOD_C) -# define BN_MP_ABS_C -# define BN_MP_CLEAR_C -# define BN_MP_CLEAR_MULTI_C -# define BN_MP_DR_IS_MODULUS_C # define BN_MP_INIT_C # define BN_MP_INVMOD_C -# define BN_MP_REDUCE_IS_2K_C +# define BN_MP_CLEAR_C +# define BN_MP_ABS_C +# define BN_MP_CLEAR_MULTI_C # define BN_MP_REDUCE_IS_2K_L_C # define BN_S_MP_EXPTMOD_C -# define BN_S_MP_EXPTMOD_FAST_C +# define BN_MP_DR_IS_MODULUS_C +# define BN_MP_REDUCE_IS_2K_C +# define BN_MP_ISODD_C +# define BN_MP_EXPTMOD_FAST_C #endif -#if defined(BN_MP_EXTEUCLID_C) -# define BN_MP_CLEAR_MULTI_C +#if defined(BN_MP_EXPTMOD_FAST_C) +# define BN_MP_COUNT_BITS_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_CLEAR_C +# define BN_MP_MONTGOMERY_SETUP_C +# define BN_FAST_MP_MONTGOMERY_REDUCE_C +# define BN_MP_MONTGOMERY_REDUCE_C +# define BN_MP_DR_SETUP_C +# define BN_MP_DR_REDUCE_C +# define BN_MP_REDUCE_2K_SETUP_C +# define BN_MP_REDUCE_2K_C +# define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C +# define BN_MP_MULMOD_C +# define BN_MP_SET_C +# define BN_MP_MOD_C # define BN_MP_COPY_C -# define BN_MP_DIV_C +# define BN_MP_SQR_C +# define BN_MP_MUL_C # define BN_MP_EXCH_C +#endif + +#if defined(BN_MP_EXTEUCLID_C) # define BN_MP_INIT_MULTI_C -# define BN_MP_MUL_C -# define BN_MP_NEG_C # define BN_MP_SET_C +# define BN_MP_COPY_C +# define BN_MP_ISZERO_C +# define BN_MP_DIV_C +# define BN_MP_MUL_C # define BN_MP_SUB_C +# define BN_MP_NEG_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_MULTI_C #endif #if defined(BN_MP_FREAD_C) -# define BN_MP_ADD_D_C -# define BN_MP_MUL_D_C # define BN_MP_ZERO_C +# define BN_MP_S_RMAP_REVERSE_SZ_C +# define BN_MP_S_RMAP_REVERSE_C +# define BN_MP_MUL_D_C +# define BN_MP_ADD_D_C +# define BN_MP_CMP_D_C #endif #if defined(BN_MP_FWRITE_C) @@ -423,87 +432,57 @@ #endif #if defined(BN_MP_GCD_C) +# define BN_MP_ISZERO_C # define BN_MP_ABS_C -# define BN_MP_CLEAR_C -# define BN_MP_CMP_MAG_C +# define BN_MP_INIT_COPY_C # define BN_MP_CNT_LSB_C # define BN_MP_DIV_2D_C +# define BN_MP_CMP_MAG_C # define BN_MP_EXCH_C -# define BN_MP_INIT_COPY_C -# define BN_MP_MUL_2D_C # define BN_S_MP_SUB_C +# define BN_MP_MUL_2D_C +# define BN_MP_CLEAR_C #endif -#if defined(BN_MP_GET_DOUBLE_C) +#if defined(BN_MP_GET_BIT_C) +# define BN_MP_ISZERO_C #endif -#if defined(BN_MP_GET_I32_C) -# define BN_MP_GET_MAG32_C +#if defined(BN_MP_GET_DOUBLE_C) +# define BN_MP_ISNEG_C #endif -#if defined(BN_MP_GET_I64_C) -# define BN_MP_GET_MAG64_C +#if defined(BN_MP_GET_INT_C) #endif -#if defined(BN_MP_GET_MAG32_C) +#if defined(BN_MP_GET_LONG_C) #endif -#if defined(BN_MP_GET_MAG64_C) +#if defined(BN_MP_GET_LONG_LONG_C) #endif #if defined(BN_MP_GROW_C) #endif -#if defined(BN_MP_ILOGB_C) -# define BN_MP_CLEAR_MULTI_C -# define BN_MP_CMP_C -# define BN_MP_CMP_D_C -# define BN_MP_COPY_C -# define BN_MP_COUNT_BITS_C -# define BN_MP_EXCH_C -# define BN_MP_EXPT_D_C -# define BN_MP_INIT_MULTI_C -# define BN_MP_MUL_C -# define BN_MP_SET_C -# define BN_MP_SET_U32_C -# define BN_MP_SQR_C -# 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 -# define BN_MP_SET_C +# define BN_MP_MUL_2D_C +# define BN_MP_CLAMP_C #endif #if defined(BN_MP_INIT_C) #endif #if defined(BN_MP_INIT_COPY_C) -# define BN_MP_CLEAR_C -# define BN_MP_COPY_C # define BN_MP_INIT_SIZE_C -#endif - -#if defined(BN_MP_INIT_I32_C) -# define BN_MP_INIT_C -# define BN_MP_SET_I32_C -#endif - -#if defined(BN_MP_INIT_I64_C) -# define BN_MP_INIT_C -# define BN_MP_SET_I64_C +# define BN_MP_COPY_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_INIT_MULTI_C) -# define BN_MP_CLEAR_C +# define BN_MP_ERR_C # define BN_MP_INIT_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_INIT_SET_C) @@ -511,78 +490,119 @@ # define BN_MP_SET_C #endif -#if defined(BN_MP_INIT_SIZE_C) -#endif - -#if defined(BN_MP_INIT_U32_C) +#if defined(BN_MP_INIT_SET_INT_C) # define BN_MP_INIT_C -# define BN_MP_SET_U32_C +# define BN_MP_SET_INT_C #endif -#if defined(BN_MP_INIT_U64_C) +#if defined(BN_MP_INIT_SIZE_C) # define BN_MP_INIT_C -# define BN_MP_SET_U64_C #endif #if defined(BN_MP_INVMOD_C) # define BN_MP_CMP_D_C -# define BN_S_MP_INVMOD_FAST_C -# define BN_S_MP_INVMOD_SLOW_C +# define BN_MP_ISODD_C +# define BN_FAST_MP_INVMOD_C +# define BN_MP_INVMOD_SLOW_C #endif -#if defined(BN_MP_IS_SQUARE_C) -# define BN_MP_CLEAR_C -# define BN_MP_CMP_MAG_C -# define BN_MP_GET_I32_C -# define BN_MP_INIT_U32_C +#if defined(BN_MP_INVMOD_SLOW_C) +# define BN_MP_ISZERO_C +# define BN_MP_INIT_MULTI_C # define BN_MP_MOD_C +# define BN_MP_COPY_C +# define BN_MP_ISEVEN_C +# define BN_MP_SET_C +# define BN_MP_DIV_2_C +# define BN_MP_ISODD_C +# define BN_MP_ADD_C +# define BN_MP_SUB_C +# define BN_MP_CMP_C +# define BN_MP_CMP_D_C +# define BN_MP_CMP_MAG_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_IS_SQUARE_C) # define BN_MP_MOD_D_C +# define BN_MP_INIT_SET_INT_C +# define BN_MP_MOD_C +# define BN_MP_GET_INT_C # define BN_MP_SQRT_C # define BN_MP_SQR_C +# define BN_MP_CMP_MAG_C +# define BN_MP_CLEAR_C #endif -#if defined(BN_MP_ISEVEN_C) +#if defined(BN_MP_JACOBI_C) +# define BN_MP_KRONECKER_C +# define BN_MP_ISNEG_C +# define BN_MP_CMP_D_C #endif -#if defined(BN_MP_ISODD_C) +#if defined(BN_MP_KARATSUBA_MUL_C) +# define BN_MP_MUL_C +# define BN_MP_INIT_SIZE_C +# define BN_MP_CLAMP_C +# define BN_S_MP_ADD_C +# define BN_MP_ADD_C +# define BN_S_MP_SUB_C +# define BN_MP_LSHD_C +# define BN_MP_CLEAR_C #endif -#if defined(BN_MP_KRONECKER_C) +#if defined(BN_MP_KARATSUBA_SQR_C) +# define BN_MP_INIT_SIZE_C +# define BN_MP_CLAMP_C +# define BN_MP_SQR_C +# define BN_S_MP_ADD_C +# define BN_S_MP_SUB_C +# define BN_MP_LSHD_C +# define BN_MP_ADD_C # define BN_MP_CLEAR_C -# define BN_MP_CMP_D_C +#endif + +#if defined(BN_MP_KRONECKER_C) +# define BN_MP_ISZERO_C +# define BN_MP_ISEVEN_C +# define BN_MP_INIT_COPY_C # define BN_MP_CNT_LSB_C -# define BN_MP_COPY_C # define BN_MP_DIV_2D_C -# define BN_MP_INIT_C -# define BN_MP_INIT_COPY_C +# define BN_MP_CMP_D_C +# define BN_MP_COPY_C # define BN_MP_MOD_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_LCM_C) -# define BN_MP_CLEAR_MULTI_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_GCD_C # define BN_MP_CMP_MAG_C # define BN_MP_DIV_C -# define BN_MP_GCD_C -# define BN_MP_INIT_MULTI_C # define BN_MP_MUL_C +# define BN_MP_CLEAR_MULTI_C #endif #if defined(BN_MP_LSHD_C) +# define BN_MP_ISZERO_C # define BN_MP_GROW_C +# define BN_MP_RSHD_C #endif #if defined(BN_MP_MOD_C) -# define BN_MP_ADD_C -# define BN_MP_CLEAR_C +# define BN_MP_INIT_SIZE_C # define BN_MP_DIV_C +# define BN_MP_CLEAR_C +# define BN_MP_ISZERO_C # define BN_MP_EXCH_C -# define BN_MP_INIT_SIZE_C +# define BN_MP_ADD_C #endif #if defined(BN_MP_MOD_2D_C) -# define BN_MP_CLAMP_C -# define BN_MP_COPY_C # define BN_MP_ZERO_C +# define BN_MP_COPY_C +# define BN_MP_CLAMP_C #endif #if defined(BN_MP_MOD_D_C) @@ -590,20 +610,20 @@ #endif #if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C) -# define BN_MP_2EXPT_C -# define BN_MP_CMP_MAG_C # define BN_MP_COUNT_BITS_C -# define BN_MP_MUL_2_C +# define BN_MP_2EXPT_C # define BN_MP_SET_C +# define BN_MP_MUL_2_C +# define BN_MP_CMP_MAG_C # define BN_S_MP_SUB_C #endif #if defined(BN_MP_MONTGOMERY_REDUCE_C) -# define BN_MP_CLAMP_C -# define BN_MP_CMP_MAG_C +# define BN_FAST_MP_MONTGOMERY_REDUCE_C # define BN_MP_GROW_C +# define BN_MP_CLAMP_C # define BN_MP_RSHD_C -# define BN_S_MP_MONTGOMERY_REDUCE_FAST_C +# define BN_MP_CMP_MAG_C # define BN_S_MP_SUB_C #endif @@ -611,11 +631,11 @@ #endif #if defined(BN_MP_MUL_C) -# define BN_S_MP_BALANCE_MUL_C -# define BN_S_MP_KARATSUBA_MUL_C +# define BN_MP_TOOM_MUL_C +# define BN_MP_KARATSUBA_MUL_C +# define BN_FAST_S_MP_MUL_DIGS_C +# define BN_S_MP_MUL_C # define BN_S_MP_MUL_DIGS_C -# define BN_S_MP_MUL_DIGS_FAST_C -# define BN_S_MP_TOOM_MUL_C #endif #if defined(BN_MP_MUL_2_C) @@ -623,185 +643,203 @@ #endif #if defined(BN_MP_MUL_2D_C) -# define BN_MP_CLAMP_C # define BN_MP_COPY_C # define BN_MP_GROW_C # define BN_MP_LSHD_C +# define BN_MP_CLAMP_C #endif #if defined(BN_MP_MUL_D_C) -# define BN_MP_CLAMP_C # define BN_MP_GROW_C +# define BN_MP_CLAMP_C #endif #if defined(BN_MP_MULMOD_C) -# define BN_MP_CLEAR_C # define BN_MP_INIT_SIZE_C -# define BN_MP_MOD_C # define BN_MP_MUL_C +# define BN_MP_CLEAR_C +# define BN_MP_MOD_C #endif #if defined(BN_MP_N_ROOT_C) -# define BN_MP_2EXPT_C -# define BN_MP_ADD_D_C -# define BN_MP_CLEAR_MULTI_C -# define BN_MP_CMP_C +# define BN_MP_N_ROOT_EX_C +#endif + +#if defined(BN_MP_N_ROOT_EX_C) +# define BN_MP_INIT_C +# define BN_MP_SET_C # define BN_MP_COPY_C -# define BN_MP_COUNT_BITS_C -# define BN_MP_DIV_C -# define BN_MP_EXCH_C -# define BN_MP_EXPT_D_C -# define BN_MP_INIT_MULTI_C +# define BN_MP_EXPT_D_EX_C # define BN_MP_MUL_C -# define BN_MP_MUL_D_C -# define BN_MP_SET_C # define BN_MP_SUB_C +# define BN_MP_MUL_D_C +# define BN_MP_DIV_C +# define BN_MP_CMP_C # define BN_MP_SUB_D_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_NEG_C) # define BN_MP_COPY_C +# define BN_MP_ISZERO_C #endif #if defined(BN_MP_OR_C) +# define BN_MP_INIT_COPY_C # define BN_MP_CLAMP_C -# define BN_MP_GROW_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_PRIME_FERMAT_C) -# define BN_MP_CLEAR_C -# define BN_MP_CMP_C # define BN_MP_CMP_D_C -# define BN_MP_EXPTMOD_C # define BN_MP_INIT_C +# define BN_MP_EXPTMOD_C +# define BN_MP_CMP_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_PRIME_FROBENIUS_UNDERWOOD_C) -# define BN_MP_ADD_C -# define BN_MP_ADD_D_C -# define BN_MP_CLEAR_MULTI_C -# define BN_MP_CMP_C -# define BN_MP_COUNT_BITS_C -# define BN_MP_EXCH_C -# define BN_MP_GCD_C +# define BN_MP_PRIME_IS_PRIME_C # define BN_MP_INIT_MULTI_C +# define BN_MP_SET_LONG_C +# define BN_MP_SQR_C +# define BN_MP_SUB_D_C # define BN_MP_KRONECKER_C -# define BN_MP_MOD_C +# define BN_MP_GCD_C +# define BN_MP_ADD_D_C +# define BN_MP_SET_C +# define BN_MP_COUNT_BITS_C # define BN_MP_MUL_2_C -# define BN_MP_MUL_C # define BN_MP_MUL_D_C -# define BN_MP_SET_C -# define BN_MP_SET_U32_C -# define BN_MP_SQR_C +# define BN_MP_ADD_C +# define BN_MP_MUL_C # define BN_MP_SUB_C -# define BN_MP_SUB_D_C -# define BN_S_MP_GET_BIT_C +# define BN_MP_MOD_C +# define BN_MP_GET_BIT_C +# define BN_MP_EXCH_C +# define BN_MP_ISZERO_C +# define BN_MP_CMP_C +# define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_PRIME_IS_DIVISIBLE_C) +# define BN_MP_MOD_D_C #endif #if defined(BN_MP_PRIME_IS_PRIME_C) -# define BN_MP_CLEAR_C -# define BN_MP_CMP_C +# define BN_MP_ISEVEN_C +# define BN_MP_IS_SQUARE_C # define BN_MP_CMP_D_C -# define BN_MP_COUNT_BITS_C -# define BN_MP_DIV_2D_C +# define BN_MP_PRIME_IS_DIVISIBLE_C # define BN_MP_INIT_SET_C -# define BN_MP_IS_SQUARE_C # define BN_MP_PRIME_MILLER_RABIN_C +# define BN_MP_PRIME_FROBENIUS_UNDERWOOD_C # define BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C -# define BN_MP_RAND_C # define BN_MP_READ_RADIX_C +# define BN_MP_CMP_C # define BN_MP_SET_C -# define BN_S_MP_PRIME_IS_DIVISIBLE_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_RAND_C +# define BN_MP_DIV_2D_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_PRIME_MILLER_RABIN_C) -# define BN_MP_CLEAR_C -# define BN_MP_CMP_C # define BN_MP_CMP_D_C +# define BN_MP_INIT_COPY_C +# define BN_MP_SUB_D_C # define BN_MP_CNT_LSB_C # define BN_MP_DIV_2D_C # define BN_MP_EXPTMOD_C -# define BN_MP_INIT_C -# define BN_MP_INIT_COPY_C +# define BN_MP_CMP_C # define BN_MP_SQRMOD_C -# define BN_MP_SUB_D_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_PRIME_NEXT_PRIME_C) -# define BN_MP_ADD_D_C -# define BN_MP_CLEAR_C # define BN_MP_CMP_D_C -# define BN_MP_INIT_C -# define BN_MP_MOD_D_C -# define BN_MP_PRIME_IS_PRIME_C # define BN_MP_SET_C # define BN_MP_SUB_D_C +# define BN_MP_ISEVEN_C +# define BN_MP_MOD_D_C +# define BN_MP_INIT_C +# define BN_MP_ADD_D_C +# define BN_MP_PRIME_IS_PRIME_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C) #endif -#if defined(BN_MP_PRIME_RAND_C) -# define BN_MP_ADD_D_C -# define BN_MP_DIV_2_C -# define BN_MP_MUL_2_C -# define BN_MP_PRIME_IS_PRIME_C +#if defined(BN_MP_PRIME_RANDOM_EX_C) # define BN_MP_READ_UNSIGNED_BIN_C +# define BN_MP_PRIME_IS_PRIME_C # define BN_MP_SUB_D_C -# define BN_S_MP_PRIME_RANDOM_EX_C -# define BN_S_MP_RAND_CB_C -# define BN_S_MP_RAND_SOURCE_C +# define BN_MP_DIV_2_C +# define BN_MP_MUL_2_C +# define BN_MP_ADD_D_C #endif #if defined(BN_MP_PRIME_STRONG_LUCAS_SELFRIDGE_C) -# define BN_MP_ADD_C -# define BN_MP_ADD_D_C +# define BN_MP_PRIME_IS_PRIME_C +# define BN_MP_MUL_D_C +# define BN_MP_MUL_SI_C +# define BN_MP_INIT_C +# define BN_MP_SET_LONG_C +# define BN_MP_MUL_C # define BN_MP_CLEAR_C -# define BN_MP_CLEAR_MULTI_C -# define BN_MP_CMP_C +# define BN_MP_INIT_MULTI_C +# define BN_MP_GCD_C # define BN_MP_CMP_D_C +# define BN_MP_CMP_C +# define BN_MP_KRONECKER_C +# define BN_MP_ADD_D_C # define BN_MP_CNT_LSB_C -# define BN_MP_COUNT_BITS_C # define BN_MP_DIV_2D_C -# define BN_MP_DIV_2_C -# define BN_MP_GCD_C -# define BN_MP_INIT_C -# define BN_MP_INIT_MULTI_C -# define BN_MP_KRONECKER_C -# define BN_MP_MOD_C -# define BN_MP_MUL_2_C -# define BN_MP_MUL_C # define BN_MP_SET_C -# define BN_MP_SET_I32_C -# define BN_MP_SET_U32_C +# define BN_MP_MUL_2_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_MOD_C # define BN_MP_SQR_C # define BN_MP_SUB_C +# define BN_MP_GET_BIT_C +# define BN_MP_ADD_C +# define BN_MP_ISODD_C +# define BN_MP_DIV_2_C # define BN_MP_SUB_D_C -# define BN_S_MP_GET_BIT_C -# define BN_S_MP_MUL_SI_C +# define BN_MP_ISZERO_C +# define BN_MP_CLEAR_MULTI_C #endif #if defined(BN_MP_RADIX_SIZE_C) -# define BN_MP_CLEAR_C +# define BN_MP_ISZERO_C # define BN_MP_COUNT_BITS_C -# define BN_MP_DIV_D_C # define BN_MP_INIT_COPY_C +# define BN_MP_DIV_D_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_RADIX_SMAP_C) +# define BN_MP_S_RMAP_C +# define BN_MP_S_RMAP_REVERSE_C +# define BN_MP_S_RMAP_REVERSE_SZ_C #endif #if defined(BN_MP_RAND_C) -# define BN_MP_GROW_C -# define BN_MP_RAND_SOURCE_C # define BN_MP_ZERO_C -# define BN_S_MP_RAND_SOURCE_C +# define BN_MP_ADD_D_C +# define BN_MP_LSHD_C #endif #if defined(BN_MP_READ_RADIX_C) -# define BN_MP_ADD_D_C -# define BN_MP_MUL_D_C # define BN_MP_ZERO_C +# define BN_MP_S_RMAP_REVERSE_SZ_C +# define BN_MP_S_RMAP_REVERSE_C +# define BN_MP_MUL_D_C +# define BN_MP_ADD_D_C +# define BN_MP_ISZERO_C #endif #if defined(BN_MP_READ_SIGNED_BIN_C) @@ -809,68 +847,71 @@ #endif #if defined(BN_MP_READ_UNSIGNED_BIN_C) -# define BN_MP_CLAMP_C # define BN_MP_GROW_C -# define BN_MP_MUL_2D_C # define BN_MP_ZERO_C +# define BN_MP_MUL_2D_C +# define BN_MP_CLAMP_C #endif #if defined(BN_MP_REDUCE_C) -# define BN_MP_ADD_C -# define BN_MP_CLEAR_C -# define BN_MP_CMP_C -# define BN_MP_CMP_D_C +# define BN_MP_REDUCE_SETUP_C # define BN_MP_INIT_COPY_C -# define BN_MP_LSHD_C -# define BN_MP_MOD_2D_C -# define BN_MP_MUL_C # define BN_MP_RSHD_C -# define BN_MP_SET_C -# define BN_MP_SUB_C -# define BN_S_MP_MUL_DIGS_C +# define BN_MP_MUL_C # define BN_S_MP_MUL_HIGH_DIGS_C +# define BN_FAST_S_MP_MUL_HIGH_DIGS_C +# define BN_MP_MOD_2D_C +# define BN_S_MP_MUL_DIGS_C +# define BN_MP_SUB_C +# define BN_MP_CMP_D_C +# define BN_MP_SET_C +# define BN_MP_LSHD_C +# define BN_MP_ADD_C +# define BN_MP_CMP_C # define BN_S_MP_SUB_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_REDUCE_2K_C) -# define BN_MP_CLEAR_C -# define BN_MP_CMP_MAG_C +# define BN_MP_INIT_C # define BN_MP_COUNT_BITS_C # define BN_MP_DIV_2D_C -# define BN_MP_INIT_C # define BN_MP_MUL_D_C # define BN_S_MP_ADD_C +# define BN_MP_CMP_MAG_C # define BN_S_MP_SUB_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_REDUCE_2K_L_C) -# define BN_MP_CLEAR_C -# define BN_MP_CMP_MAG_C +# define BN_MP_INIT_C # define BN_MP_COUNT_BITS_C # define BN_MP_DIV_2D_C -# define BN_MP_INIT_C # define BN_MP_MUL_C # define BN_S_MP_ADD_C +# define BN_MP_CMP_MAG_C # define BN_S_MP_SUB_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_REDUCE_2K_SETUP_C) +# define BN_MP_INIT_C +# define BN_MP_COUNT_BITS_C # define BN_MP_2EXPT_C # define BN_MP_CLEAR_C -# define BN_MP_COUNT_BITS_C -# define BN_MP_INIT_C # define BN_S_MP_SUB_C #endif #if defined(BN_MP_REDUCE_2K_SETUP_L_C) +# define BN_MP_INIT_C # define BN_MP_2EXPT_C -# define BN_MP_CLEAR_C # define BN_MP_COUNT_BITS_C -# define BN_MP_INIT_C # define BN_S_MP_SUB_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_REDUCE_IS_2K_C) +# define BN_MP_REDUCE_2K_C # define BN_MP_COUNT_BITS_C #endif @@ -887,26 +928,26 @@ #endif #if defined(BN_MP_SET_C) +# define BN_MP_ZERO_C #endif #if defined(BN_MP_SET_DOUBLE_C) +# define BN_MP_SET_LONG_LONG_C # define BN_MP_DIV_2D_C # define BN_MP_MUL_2D_C -# define BN_MP_SET_U64_C -#endif - -#if defined(BN_MP_SET_I32_C) -# define BN_MP_SET_U32_C +# define BN_MP_ISZERO_C #endif -#if defined(BN_MP_SET_I64_C) -# define BN_MP_SET_U64_C +#if defined(BN_MP_SET_INT_C) +# define BN_MP_ZERO_C +# define BN_MP_MUL_2D_C +# define BN_MP_CLAMP_C #endif -#if defined(BN_MP_SET_U32_C) +#if defined(BN_MP_SET_LONG_C) #endif -#if defined(BN_MP_SET_U64_C) +#if defined(BN_MP_SET_LONG_LONG_C) #endif #if defined(BN_MP_SHRINK_C) @@ -916,73 +957,112 @@ # define BN_MP_UNSIGNED_BIN_SIZE_C #endif -#if defined(BN_MP_SIGNED_RSH_C) -# define BN_MP_ADD_D_C -# define BN_MP_DIV_2D_C -# define BN_MP_SUB_D_C -#endif - #if defined(BN_MP_SQR_C) -# define BN_S_MP_KARATSUBA_SQR_C +# define BN_MP_TOOM_SQR_C +# define BN_MP_KARATSUBA_SQR_C +# define BN_FAST_S_MP_SQR_C # define BN_S_MP_SQR_C -# define BN_S_MP_SQR_FAST_C -# define BN_S_MP_TOOM_SQR_C #endif #if defined(BN_MP_SQRMOD_C) -# define BN_MP_CLEAR_C # define BN_MP_INIT_C -# define BN_MP_MOD_C # define BN_MP_SQR_C +# define BN_MP_CLEAR_C +# define BN_MP_MOD_C #endif #if defined(BN_MP_SQRT_C) +# define BN_MP_N_ROOT_C +# define BN_MP_ISZERO_C +# define BN_MP_ZERO_C +# define BN_MP_INIT_COPY_C +# define BN_MP_RSHD_C +# define BN_MP_DIV_C # define BN_MP_ADD_C -# define BN_MP_CLEAR_C -# define BN_MP_CMP_MAG_C # define BN_MP_DIV_2_C -# define BN_MP_DIV_C +# define BN_MP_CMP_MAG_C # define BN_MP_EXCH_C -# define BN_MP_INIT_C -# define BN_MP_INIT_COPY_C -# define BN_MP_RSHD_C -# define BN_MP_ZERO_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_SQRTMOD_PRIME_C) -# define BN_MP_ADD_D_C -# define BN_MP_CLEAR_MULTI_C # define BN_MP_CMP_D_C -# define BN_MP_COPY_C -# define BN_MP_DIV_2_C -# define BN_MP_EXPTMOD_C +# define BN_MP_ZERO_C +# define BN_MP_JACOBI_C # define BN_MP_INIT_MULTI_C -# define BN_MP_KRONECKER_C # define BN_MP_MOD_D_C +# define BN_MP_ADD_D_C +# define BN_MP_DIV_2_C +# define BN_MP_EXPTMOD_C +# define BN_MP_COPY_C +# define BN_MP_SUB_D_C +# define BN_MP_ISEVEN_C +# define BN_MP_SET_INT_C +# define BN_MP_SQRMOD_C # define BN_MP_MULMOD_C # define BN_MP_SET_C -# define BN_MP_SET_U32_C -# define BN_MP_SQRMOD_C -# define BN_MP_SUB_D_C -# define BN_MP_ZERO_C +# define BN_MP_CLEAR_MULTI_C #endif #if defined(BN_MP_SUB_C) -# define BN_MP_CMP_MAG_C # define BN_S_MP_ADD_C +# define BN_MP_CMP_MAG_C # define BN_S_MP_SUB_C #endif #if defined(BN_MP_SUB_D_C) +# define BN_MP_GROW_C # define BN_MP_ADD_D_C # define BN_MP_CLAMP_C -# define BN_MP_GROW_C #endif #if defined(BN_MP_SUBMOD_C) -# define BN_MP_CLEAR_C # define BN_MP_INIT_C +# define BN_MP_SUB_C +# define BN_MP_CLEAR_C # define BN_MP_MOD_C +#endif + +#if defined(BN_MP_TC_AND_C) +# define BN_MP_ISNEG_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_INIT_SET_INT_C +# define BN_MP_MUL_2D_C +# define BN_MP_INIT_C +# define BN_MP_ADD_C +# define BN_MP_CLEAR_C +# define BN_MP_AND_C +# define BN_MP_SUB_C +#endif + +#if defined(BN_MP_TC_DIV_2D_C) +# define BN_MP_ISNEG_C +# define BN_MP_DIV_2D_C +# define BN_MP_ADD_D_C +# define BN_MP_SUB_D_C +#endif + +#if defined(BN_MP_TC_OR_C) +# define BN_MP_ISNEG_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_INIT_SET_INT_C +# define BN_MP_MUL_2D_C +# define BN_MP_INIT_C +# define BN_MP_ADD_C +# define BN_MP_CLEAR_C +# define BN_MP_OR_C +# define BN_MP_SUB_C +#endif + +#if defined(BN_MP_TC_XOR_C) +# define BN_MP_ISNEG_C +# define BN_MP_COUNT_BITS_C +# define BN_MP_INIT_SET_INT_C +# define BN_MP_MUL_2D_C +# define BN_MP_INIT_C +# define BN_MP_ADD_C +# define BN_MP_CLEAR_C +# define BN_MP_XOR_C # define BN_MP_SUB_C #endif @@ -996,29 +1076,65 @@ #endif #if defined(BN_MP_TO_UNSIGNED_BIN_C) -# define BN_MP_CLEAR_C -# define BN_MP_DIV_2D_C # define BN_MP_INIT_COPY_C -# define BN_S_MP_REVERSE_C +# define BN_MP_ISZERO_C +# define BN_MP_DIV_2D_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_TO_UNSIGNED_BIN_N_C) -# define BN_MP_TO_UNSIGNED_BIN_C # define BN_MP_UNSIGNED_BIN_SIZE_C +# define BN_MP_TO_UNSIGNED_BIN_C +#endif + +#if defined(BN_MP_TOOM_MUL_C) +# define BN_MP_INIT_MULTI_C +# define BN_MP_MOD_2D_C +# define BN_MP_COPY_C +# define BN_MP_RSHD_C +# define BN_MP_MUL_C +# define BN_MP_MUL_2_C +# define BN_MP_ADD_C +# define BN_MP_SUB_C +# define BN_MP_DIV_2_C +# define BN_MP_MUL_2D_C +# define BN_MP_MUL_D_C +# define BN_MP_DIV_3_C +# define BN_MP_LSHD_C +# define BN_MP_CLEAR_MULTI_C +#endif + +#if defined(BN_MP_TOOM_SQR_C) +# define BN_MP_INIT_MULTI_C +# define BN_MP_MOD_2D_C +# define BN_MP_COPY_C +# define BN_MP_RSHD_C +# define BN_MP_SQR_C +# define BN_MP_MUL_2_C +# define BN_MP_ADD_C +# define BN_MP_SUB_C +# define BN_MP_DIV_2_C +# define BN_MP_MUL_2D_C +# define BN_MP_MUL_D_C +# define BN_MP_DIV_3_C +# define BN_MP_LSHD_C +# define BN_MP_CLEAR_MULTI_C #endif #if defined(BN_MP_TORADIX_C) -# define BN_MP_CLEAR_C -# define BN_MP_DIV_D_C +# define BN_MP_ISZERO_C # define BN_MP_INIT_COPY_C -# define BN_S_MP_REVERSE_C +# define BN_MP_DIV_D_C +# define BN_MP_CLEAR_C +# define BN_MP_S_RMAP_C #endif #if defined(BN_MP_TORADIX_N_C) -# define BN_MP_CLEAR_C -# define BN_MP_DIV_D_C +# define BN_MP_ISZERO_C # define BN_MP_INIT_COPY_C -# define BN_S_MP_REVERSE_C +# define BN_MP_DIV_D_C +# define BN_MP_CLEAR_C +# define BN_MP_S_RMAP_C #endif #if defined(BN_MP_UNSIGNED_BIN_SIZE_C) @@ -1026,8 +1142,10 @@ #endif #if defined(BN_MP_XOR_C) +# define BN_MP_INIT_COPY_C # define BN_MP_CLAMP_C -# define BN_MP_GROW_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_C #endif #if defined(BN_MP_ZERO_C) @@ -1036,209 +1154,71 @@ #if defined(BN_PRIME_TAB_C) #endif -#if defined(BN_S_MP_ADD_C) -# define BN_MP_CLAMP_C -# define BN_MP_GROW_C +#if defined(BN_REVERSE_C) #endif -#if defined(BN_S_MP_BALANCE_MUL_C) -# define BN_MP_ADD_C -# define BN_MP_CLEAR_C -# define BN_MP_CLEAR_MULTI_C -# define BN_MP_EXCH_C -# define BN_MP_INIT_MULTI_C -# define BN_MP_INIT_SIZE_C -# define BN_MP_LSHD_C -# define BN_MP_MUL_C +#if defined(BN_S_MP_ADD_C) +# define BN_MP_GROW_C +# define BN_MP_CLAMP_C #endif #if defined(BN_S_MP_EXPTMOD_C) -# define BN_MP_CLEAR_C -# define BN_MP_COPY_C # define BN_MP_COUNT_BITS_C -# define BN_MP_EXCH_C # define BN_MP_INIT_C -# define BN_MP_MOD_C -# define BN_MP_MUL_C -# define BN_MP_REDUCE_2K_SETUP_L_C -# define BN_MP_REDUCE_SETUP_C -# define BN_MP_SET_C -# define BN_MP_SQR_C -#endif - -#if defined(BN_S_MP_EXPTMOD_FAST_C) # define BN_MP_CLEAR_C -# define BN_MP_COPY_C -# define BN_MP_COUNT_BITS_C -# define BN_MP_DR_SETUP_C -# define BN_MP_EXCH_C -# define BN_MP_INIT_SIZE_C +# define BN_MP_REDUCE_SETUP_C +# define BN_MP_REDUCE_C +# define BN_MP_REDUCE_2K_SETUP_L_C +# define BN_MP_REDUCE_2K_L_C # define BN_MP_MOD_C -# define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C -# define BN_MP_MONTGOMERY_SETUP_C -# define BN_MP_MULMOD_C -# define BN_MP_MUL_C -# define BN_MP_REDUCE_2K_SETUP_C -# define BN_MP_SET_C -# define BN_MP_SQR_C -#endif - -#if defined(BN_S_MP_GET_BIT_C) -#endif - -#if defined(BN_S_MP_INVMOD_FAST_C) -# define BN_MP_ADD_C -# define BN_MP_CLEAR_MULTI_C -# define BN_MP_CMP_C -# define BN_MP_CMP_D_C -# define BN_MP_CMP_MAG_C # define BN_MP_COPY_C -# define BN_MP_DIV_2_C -# define BN_MP_EXCH_C -# define BN_MP_INIT_MULTI_C -# define BN_MP_MOD_C +# define BN_MP_SQR_C +# define BN_MP_MUL_C # define BN_MP_SET_C -# define BN_MP_SUB_C -#endif - -#if defined(BN_S_MP_INVMOD_SLOW_C) -# define BN_MP_ADD_C -# define BN_MP_CLEAR_MULTI_C -# define BN_MP_CMP_C -# define BN_MP_CMP_D_C -# define BN_MP_CMP_MAG_C -# define BN_MP_COPY_C -# define BN_MP_DIV_2_C # define BN_MP_EXCH_C -# define BN_MP_INIT_MULTI_C -# define BN_MP_MOD_C -# define BN_MP_SET_C -# define BN_MP_SUB_C -#endif - -#if defined(BN_S_MP_KARATSUBA_MUL_C) -# define BN_MP_ADD_C -# define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C -# define BN_MP_INIT_SIZE_C -# define BN_MP_LSHD_C -# define BN_MP_MUL_C -# define BN_S_MP_ADD_C -# define BN_S_MP_SUB_C -#endif - -#if defined(BN_S_MP_KARATSUBA_SQR_C) -# define BN_MP_ADD_C -# define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C -# define BN_MP_INIT_SIZE_C -# define BN_MP_LSHD_C -# define BN_MP_SQR_C -# define BN_S_MP_ADD_C -# define BN_S_MP_SUB_C -#endif - -#if defined(BN_S_MP_MONTGOMERY_REDUCE_FAST_C) -# define BN_MP_CLAMP_C -# define BN_MP_CMP_MAG_C -# define BN_MP_GROW_C -# define BN_S_MP_SUB_C #endif #if defined(BN_S_MP_MUL_DIGS_C) -# define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C -# define BN_MP_EXCH_C +# define BN_FAST_S_MP_MUL_DIGS_C # define BN_MP_INIT_SIZE_C -# define BN_S_MP_MUL_DIGS_FAST_C -#endif - -#if defined(BN_S_MP_MUL_DIGS_FAST_C) # define BN_MP_CLAMP_C -# define BN_MP_GROW_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_C #endif #if defined(BN_S_MP_MUL_HIGH_DIGS_C) -# define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C -# define BN_MP_EXCH_C +# define BN_FAST_S_MP_MUL_HIGH_DIGS_C # define BN_MP_INIT_SIZE_C -# define BN_S_MP_MUL_HIGH_DIGS_FAST_C -#endif - -#if defined(BN_S_MP_MUL_HIGH_DIGS_FAST_C) # define BN_MP_CLAMP_C -# define BN_MP_GROW_C -#endif - -#if defined(BN_S_MP_PRIME_IS_DIVISIBLE_C) -# define BN_MP_MOD_D_C -#endif - -#if defined(BN_S_MP_RAND_JENKINS_C) -# define BN_S_MP_RAND_JENKINS_INIT_C -#endif - -#if defined(BN_S_MP_RAND_PLATFORM_C) -#endif - -#if defined(BN_S_MP_REVERSE_C) +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_C #endif #if defined(BN_S_MP_SQR_C) -# define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C -# define BN_MP_EXCH_C # define BN_MP_INIT_SIZE_C -#endif - -#if defined(BN_S_MP_SQR_FAST_C) # define BN_MP_CLAMP_C -# define BN_MP_GROW_C +# define BN_MP_EXCH_C +# define BN_MP_CLEAR_C #endif #if defined(BN_S_MP_SUB_C) -# define BN_MP_CLAMP_C # define BN_MP_GROW_C -#endif - -#if defined(BN_S_MP_TOOM_MUL_C) -# define BN_MP_ADD_C # define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C -# define BN_MP_CLEAR_MULTI_C -# define BN_MP_DIV_2_C -# define BN_MP_DIV_3_C -# define BN_MP_INIT_MULTI_C -# define BN_MP_INIT_SIZE_C -# define BN_MP_LSHD_C -# define BN_MP_MUL_2_C -# define BN_MP_MUL_C -# define BN_MP_SUB_C #endif -#if defined(BN_S_MP_TOOM_SQR_C) -# define BN_MP_ADD_C -# define BN_MP_CLAMP_C -# define BN_MP_CLEAR_C -# define BN_MP_DIV_2_C -# define BN_MP_INIT_C -# define BN_MP_INIT_SIZE_C -# define BN_MP_LSHD_C -# define BN_MP_MUL_2_C -# define BN_MP_MUL_C -# define BN_MP_SQR_C -# define BN_MP_SUB_C +#if defined(BNCORE_C) #endif -#ifdef LTM_INSIDE -#undef LTM_INSIDE #ifdef LTM3 # define LTM_LAST #endif -#include "tommath_superclass.h" -#include "tommath_class.h" +#include <tommath_superclass.h> +#include <tommath_class.h> #else # define LTM_LAST #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/tommath_cutoffs.h b/src/ltm/tommath_cutoffs.h deleted file mode 100644 index a65a9b3e..00000000 --- a/src/ltm/tommath_cutoffs.h +++ /dev/null @@ -1,13 +0,0 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ -/* - Current values evaluated on an AMD A8-6600K (64-bit). - Type "make tune" to optimize them for your machine but - be aware that it may take a long time. It took 2:30 minutes - on the aforementioned machine for example. - */ - -#define MP_DEFAULT_KARATSUBA_MUL_CUTOFF 80 -#define MP_DEFAULT_KARATSUBA_SQR_CUTOFF 120 -#define MP_DEFAULT_TOOM_MUL_CUTOFF 350 -#define MP_DEFAULT_TOOM_SQR_CUTOFF 400 diff --git a/src/ltm/tommath_private.h b/src/ltm/tommath_private.h index a684fa1a..8c195d36 100644 --- a/src/ltm/tommath_private.h +++ b/src/ltm/tommath_private.h @@ -1,287 +1,122 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ - +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ #ifndef TOMMATH_PRIV_H_ #define TOMMATH_PRIV_H_ #include "tommath.h" -#include "tommath_class.h" +#include <ctype.h> -/* - * Private symbols - * --------------- - * - * On Unix symbols can be marked as hidden if libtommath is compiled - * as a shared object. By default, symbols are visible. - * As of now, this feature is opt-in via the MP_PRIVATE_SYMBOLS define. - * - * On Win32 a .def file must be used to specify the exported symbols. - */ -#if defined (MP_PRIVATE_SYMBOLS) && __GNUC__ >= 4 -# define MP_PRIVATE __attribute__ ((visibility ("hidden"))) -#else -# define MP_PRIVATE +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) #endif -/* Hardening libtommath - * -------------------- - * - * By default memory is zeroed before calling - * MP_FREE to avoid leaking data. This is good - * practice in cryptographical applications. - * - * Note however that memory allocators used - * in cryptographical applications can often - * be configured by itself to clear memory, - * rendering the clearing in tommath unnecessary. - * See for example https://github.com/GrapheneOS/hardened_malloc - * and the option CONFIG_ZERO_ON_FREE. - * - * Furthermore there are applications which - * value performance more and want this - * feature to be disabled. For such applications - * define MP_NO_ZERO_ON_FREE during compilation. - */ -#ifdef MP_NO_ZERO_ON_FREE -# define MP_FREE_BUFFER(mem, size) MP_FREE((mem), (size)) -# define MP_FREE_DIGITS(mem, digits) MP_FREE((mem), sizeof (mp_digit) * (size_t)(digits)) -#else -# define MP_FREE_BUFFER(mem, size) \ -do { \ - size_t fs_ = (size); \ - void* fm_ = (mem); \ - if (fm_ != NULL) { \ - MP_ZERO_BUFFER(fm_, fs_); \ - MP_FREE(fm_, fs_); \ - } \ -} while (0) -# define MP_FREE_DIGITS(mem, digits) \ -do { \ - int fd_ = (digits); \ - void* fm_ = (mem); \ - if (fm_ != NULL) { \ - size_t fs_ = sizeof (mp_digit) * (size_t)fd_; \ - MP_ZERO_BUFFER(fm_, fs_); \ - MP_FREE(fm_, fs_); \ - } \ -} while (0) +#ifndef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) #endif -#ifdef MP_USE_MEMSET -# include <string.h> -# define MP_ZERO_BUFFER(mem, size) memset((mem), 0, (size)) -# define MP_ZERO_DIGITS(mem, digits) \ -do { \ - int zd_ = (digits); \ - if (zd_ > 0) { \ - memset((mem), 0, sizeof(mp_digit) * (size_t)zd_); \ - } \ -} while (0) -#else -# define MP_ZERO_BUFFER(mem, size) \ -do { \ - size_t zs_ = (size); \ - char* zm_ = (char*)(mem); \ - while (zs_-- > 0u) { \ - *zm_++ = '\0'; \ - } \ -} while (0) -# define MP_ZERO_DIGITS(mem, digits) \ -do { \ - int zd_ = (digits); \ - mp_digit* zm_ = (mem); \ - while (zd_-- > 0) { \ - *zm_++ = 0; \ - } \ -} while (0) -#endif +#ifdef __cplusplus +extern "C" { -/* Tunable cutoffs - * --------------- - * - * - In the default settings, a cutoff X can be modified at runtime - * by adjusting the corresponding X_CUTOFF variable. - * - * - Tunability of the library can be disabled at compile time - * by defining the MP_FIXED_CUTOFFS macro. - * - * - There is an additional file tommath_cutoffs.h, which defines - * the default cutoffs. These can be adjusted manually or by the - * autotuner. - * - */ +/* C++ compilers don't like assigning void * to mp_digit * */ +#define OPT_CAST(x) (x *) -#ifdef MP_FIXED_CUTOFFS -# include "tommath_cutoffs.h" -# define MP_KARATSUBA_MUL_CUTOFF MP_DEFAULT_KARATSUBA_MUL_CUTOFF -# define MP_KARATSUBA_SQR_CUTOFF MP_DEFAULT_KARATSUBA_SQR_CUTOFF -# define MP_TOOM_MUL_CUTOFF MP_DEFAULT_TOOM_MUL_CUTOFF -# define MP_TOOM_SQR_CUTOFF MP_DEFAULT_TOOM_SQR_CUTOFF #else -# define MP_KARATSUBA_MUL_CUTOFF KARATSUBA_MUL_CUTOFF -# define MP_KARATSUBA_SQR_CUTOFF KARATSUBA_SQR_CUTOFF -# define MP_TOOM_MUL_CUTOFF TOOM_MUL_CUTOFF -# define MP_TOOM_SQR_CUTOFF TOOM_SQR_CUTOFF + +/* C on the other hand doesn't care */ +#define OPT_CAST(x) + #endif /* define heap macros */ -#ifndef MP_MALLOC +#ifndef XMALLOC /* default to libc stuff */ -# include <stdlib.h> -# define MP_MALLOC(size) malloc(size) -# define MP_REALLOC(mem, oldsize, newsize) realloc((mem), (newsize)) -# define MP_CALLOC(nmemb, size) calloc((nmemb), (size)) -# define MP_FREE(mem, size) free(mem) +# define XMALLOC malloc +# define XFREE free +# define XREALLOC realloc +# define XCALLOC calloc #else /* prototypes for our heap functions */ -extern void *MP_MALLOC(size_t size); -extern void *MP_REALLOC(void *mem, size_t oldsize, size_t newsize); -extern void *MP_CALLOC(size_t nmemb, size_t size); -extern void MP_FREE(void *mem, size_t size); +extern void *XMALLOC(size_t n); +extern void *XREALLOC(void *p, size_t n); +extern void *XCALLOC(size_t n, size_t s); +extern void XFREE(void *p); #endif -/* TODO: Remove private_mp_word as soon as deprecated mp_word is removed from tommath. */ -#undef mp_word -typedef private_mp_word mp_word; - -#define MP_MIN(x, y) (((x) < (y)) ? (x) : (y)) -#define MP_MAX(x, y) (((x) > (y)) ? (x) : (y)) - -/* Static assertion */ -#define MP_STATIC_ASSERT(msg, cond) typedef char mp_static_assert_##msg[(cond) ? 1 : -1]; - -/* ---> Basic Manipulations <--- */ -#define MP_IS_ZERO(a) ((a)->used == 0) -#define MP_IS_EVEN(a) (((a)->used == 0) || (((a)->dp[0] & 1u) == 0u)) -#define MP_IS_ODD(a) (((a)->used > 0) && (((a)->dp[0] & 1u) == 1u)) - -#define MP_SIZEOF_BITS(type) ((size_t)CHAR_BIT * sizeof(type)) -#define MP_MAXFAST (int)(1uL << (MP_SIZEOF_BITS(mp_word) - (2u * (size_t)MP_DIGIT_BIT))) - -/* TODO: Remove PRIVATE_MP_WARRAY as soon as deprecated MP_WARRAY is removed from tommath.h */ -#undef MP_WARRAY -#define MP_WARRAY PRIVATE_MP_WARRAY - -/* TODO: Remove PRIVATE_MP_PREC as soon as deprecated MP_PREC is removed from tommath.h */ -#ifdef PRIVATE_MP_PREC -# undef MP_PREC -# define MP_PREC PRIVATE_MP_PREC -#endif - -/* Minimum number of available digits in mp_int, MP_PREC >= MP_MIN_PREC */ -#define MP_MIN_PREC ((((int)MP_SIZEOF_BITS(long long) + MP_DIGIT_BIT) - 1) / MP_DIGIT_BIT) - -MP_STATIC_ASSERT(prec_geq_min_prec, MP_PREC >= MP_MIN_PREC) - -/* random number source */ -extern MP_PRIVATE mp_err(*s_mp_rand_source)(void *out, size_t size); - /* lowlevel functions, do not call! */ -MP_PRIVATE mp_bool s_mp_get_bit(const mp_int *a, unsigned int b); -MP_PRIVATE mp_err s_mp_add(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -MP_PRIVATE mp_err s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -MP_PRIVATE mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR; -MP_PRIVATE mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR; -MP_PRIVATE mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR; -MP_PRIVATE mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs) MP_WUR; -MP_PRIVATE mp_err s_mp_sqr_fast(const mp_int *a, mp_int *b) MP_WUR; -MP_PRIVATE mp_err s_mp_sqr(const mp_int *a, mp_int *b) MP_WUR; -MP_PRIVATE mp_err s_mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -MP_PRIVATE mp_err s_mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -MP_PRIVATE mp_err s_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -MP_PRIVATE mp_err s_mp_karatsuba_sqr(const mp_int *a, mp_int *b) MP_WUR; -MP_PRIVATE mp_err s_mp_toom_sqr(const mp_int *a, mp_int *b) MP_WUR; -MP_PRIVATE mp_err s_mp_invmod_fast(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -MP_PRIVATE mp_err s_mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c) MP_WUR; -MP_PRIVATE mp_err s_mp_montgomery_reduce_fast(mp_int *x, const mp_int *n, mp_digit rho) MP_WUR; -MP_PRIVATE mp_err s_mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) MP_WUR; -MP_PRIVATE mp_err s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode) MP_WUR; -MP_PRIVATE mp_err s_mp_rand_platform(void *p, size_t n) MP_WUR; -MP_PRIVATE mp_err s_mp_prime_random_ex(mp_int *a, int t, int size, int flags, private_mp_prime_callback cb, void *dat); -MP_PRIVATE void s_mp_reverse(unsigned char *s, int len); -MP_PRIVATE mp_err s_mp_prime_is_divisible(const mp_int *a, mp_bool *result); - -/* TODO: jenkins prng is not thread safe as of now */ -MP_PRIVATE mp_err s_mp_rand_jenkins(void *p, size_t n) MP_WUR; -MP_PRIVATE void s_mp_rand_jenkins_init(unsigned long long seed); - -extern MP_PRIVATE const char *const mp_s_rmap; -extern MP_PRIVATE const unsigned char mp_s_rmap_reverse[]; -extern MP_PRIVATE const size_t mp_s_rmap_reverse_sz; -extern MP_PRIVATE const mp_digit *s_mp_prime_tab; - -/* deprecated functions */ -MP_DEPRECATED(s_mp_invmod_fast) mp_err fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c); -MP_DEPRECATED(s_mp_montgomery_reduce_fast) mp_err fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, - mp_digit rho); -MP_DEPRECATED(s_mp_mul_digs_fast) mp_err fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, - int digs); -MP_DEPRECATED(s_mp_mul_high_digs_fast) mp_err fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, - mp_int *c, - int digs); -MP_DEPRECATED(s_mp_sqr_fast) mp_err fast_s_mp_sqr(const mp_int *a, mp_int *b); -MP_DEPRECATED(s_mp_balance_mul) mp_err mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c); -MP_DEPRECATED(s_mp_exptmod_fast) mp_err mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, - mp_int *Y, - int redmode); -MP_DEPRECATED(s_mp_invmod_slow) mp_err mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c); -MP_DEPRECATED(s_mp_karatsuba_mul) mp_err mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c); -MP_DEPRECATED(s_mp_karatsuba_sqr) mp_err mp_karatsuba_sqr(const mp_int *a, mp_int *b); -MP_DEPRECATED(s_mp_toom_mul) mp_err mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c); -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); - -/* code-generating macros */ -#define MP_SET_UNSIGNED(name, type) \ - void name(mp_int * a, type b) \ - { \ - int i = 0; \ - while (b != 0u) { \ - a->dp[i++] = ((mp_digit)b & MP_MASK); \ - if (MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) { break; } \ - b >>= ((MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) ? 0 : MP_DIGIT_BIT); \ - } \ - a->used = i; \ - a->sign = MP_ZPOS; \ - MP_ZERO_DIGITS(a->dp + a->used, a->alloc - a->used); \ - } - -#define MP_SET_SIGNED(name, uname, type, utype) \ - void name(mp_int * a, type b) \ - { \ - uname(a, (b < 0) ? -(utype)b : (utype)b); \ - if (b < 0) { a->sign = MP_NEG; } \ - } - -#define MP_INIT_INT(name , set, type) \ - mp_err name(mp_int * a, type b) \ - { \ - mp_err err; \ - if ((err = mp_init(a)) != MP_OKAY) { \ - return err; \ - } \ - set(a, b); \ - return MP_OKAY; \ - } +int s_mp_add(const mp_int *a, const mp_int *b, mp_int *c); +int s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c); +#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) +int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs); +int s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs); +int fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs); +int s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs); +int fast_s_mp_sqr(const mp_int *a, mp_int *b); +int s_mp_sqr(const mp_int *a, mp_int *b); +int mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c); +int mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c); +int mp_karatsuba_sqr(const mp_int *a, mp_int *b); +int mp_toom_sqr(const mp_int *a, mp_int *b); +int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c); +int mp_invmod_slow(const mp_int *a, const mp_int *b, mp_int *c); +int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho); +int mp_exptmod_fast(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode); +int s_mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y, int redmode); +void bn_reverse(unsigned char *s, int len); + +extern const char *const mp_s_rmap; +extern const unsigned char 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: + * x is the counter and unsigned + * a is the pointer to the MPI + * b is the original value that should be set in the MPI. + */ +#define MP_SET_XLONG(func_name, type) \ +int func_name (mp_int * a, type b) \ +{ \ + unsigned int x; \ + int res; \ + \ + mp_zero (a); \ + \ + /* set four bits at a time */ \ + for (x = 0; x < (sizeof(type) * 2u); x++) { \ + /* shift the number up four bits */ \ + if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) { \ + return res; \ + } \ + \ + /* OR in the top four bits of the source */ \ + a->dp[0] |= (mp_digit)(b >> ((sizeof(type) * 8u) - 4u)) & 15uL;\ + \ + /* shift the source up to the next four bits */ \ + b <<= 4; \ + \ + /* ensure that digits are not clamped off */ \ + a->used += 1; \ + } \ + mp_clamp (a); \ + return MP_OKAY; \ +} + +#ifdef __cplusplus +} +#endif -#define MP_GET_MAG(type, name) \ - type name(const mp_int* a) \ - { \ - unsigned i = MP_MIN((unsigned)a->used, (unsigned)((MP_SIZEOF_BITS(type) + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT)); \ - type res = 0u; \ - while (i --> 0u) { \ - res <<= ((MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) ? 0 : MP_DIGIT_BIT); \ - res |= (type)a->dp[i]; \ - if (MP_SIZEOF_BITS(type) <= MP_DIGIT_BIT) { break; } \ - } \ - return res; \ - } +#endif -#define MP_GET_SIGNED(type, name, mag) \ - type name(const mp_int* a) \ - { \ - unsigned long long res = mag(a); \ - return (a->sign == MP_NEG) ? (type)-res : (type)res; \ - } -#endif +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltm/tommath_superclass.h b/src/ltm/tommath_superclass.h index cf178666..7b98ed63 100644 --- a/src/ltm/tommath_superclass.h +++ b/src/ltm/tommath_superclass.h @@ -1,5 +1,14 @@ -/* LibTomMath, multiple-precision integer library -- Tom St Denis */ -/* SPDX-License-Identifier: Unlicense */ +/* LibTomMath, multiple-precision integer library -- Tom St Denis + * + * LibTomMath is a library that provides multiple-precision + * integer arithmetic as well as number theoretic functionality. + * + * The library was designed directly after the MPI library by + * Michael Fromberger but has been written from scratch with + * additional optimizations in place. + * + * SPDX-License-Identifier: Unlicense + */ /* super class file for PK algos */ @@ -33,7 +42,7 @@ # define BN_MP_TO_UNSIGNED_BIN_C # define BN_MP_MOD_D_C # define BN_MP_PRIME_RABIN_MILLER_TRIALS_C -# define BN_S_MP_REVERSE_C +# define BN_REVERSE_C # define BN_PRIME_TAB_C /* other modifiers */ @@ -44,10 +53,10 @@ * like removing support for even moduli, etc... */ # ifdef LTM_LAST -# undef BN_S_MP_TOOM_MUL_C -# undef BN_S_MP_TOOM_SQR_C -# undef BN_S_MP_KARATSUBA_MUL_C -# undef BN_S_MP_KARATSUBA_SQR_C +# undef BN_MP_TOOM_MUL_C +# undef BN_MP_TOOM_SQR_C +# undef BN_MP_KARATSUBA_MUL_C +# undef BN_MP_KARATSUBA_SQR_C # undef BN_MP_REDUCE_C # undef BN_MP_REDUCE_SETUP_C # undef BN_MP_DR_IS_MODULUS_C @@ -59,8 +68,8 @@ # undef BN_S_MP_EXPTMOD_C # undef BN_MP_DIV_3_C # undef BN_S_MP_MUL_HIGH_DIGS_C -# undef BN_S_MP_MUL_HIGH_DIGS_FAST_C -# undef BN_S_MP_INVMOD_FAST_C +# undef BN_FAST_S_MP_MUL_HIGH_DIGS_C +# undef BN_FAST_MP_INVMOD_C /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] @@ -73,3 +82,7 @@ # endif #endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/update-libtom.pl b/src/update-libtom.pl index a5c95e09..5d2ec6de 100755 --- a/src/update-libtom.pl +++ b/src/update-libtom.pl @@ -10,22 +10,22 @@ my $ltc_branch = "develop"; my $ltm_branch = "develop"; my $tmpdir = "/tmp/libtom.git.checkout.$$"; -warn "update libtommath from github (branch: $ltm_branch)..\n"; -system 'rm', '-rf', bsd_glob("$FindBin::Bin/ltm/*"); -system "rm -rf $tmpdir; mkdir $tmpdir"; -system "git clone -b $ltm_branch https://github.com/libtom/libtommath.git $tmpdir && cp $tmpdir/bn*.c $tmpdir/tom*.h $FindBin::Bin/ltm/ && echo ok"; -system "(cd $tmpdir && git log --pretty='%h %ai %s') | head -1"; -# avoid stdint.h hack -system "find '$FindBin::Bin/ltm/' -name '*.c' -o -name '*.h' | xargs sed -i" - . " -e 's/uint8_t/unsigned char/g'" - . " -e 's/uint16_t/unsigned short/g'" - . " -e 's/uint32_t/unsigned int/g'" - . " -e 's/uint64_t/unsigned long long/g'" - . " -e 's/int8_t/char/g'" - . " -e 's/int16_t/short/g'" - . " -e 's/int32_t/int/g'" - . " -e 's/int64_t/long long/g'" - . " -e 's/# *include *<stdint.h>//'"; +#warn "update libtommath from github (branch: $ltm_branch)..\n"; +#system 'rm', '-rf', bsd_glob("$FindBin::Bin/ltm/*"); +#system "rm -rf $tmpdir; mkdir $tmpdir"; +#system "git clone -b $ltm_branch https://github.com/libtom/libtommath.git $tmpdir && cp $tmpdir/bn*.c $tmpdir/tom*.h $FindBin::Bin/ltm/ && echo ok"; +#system "(cd $tmpdir && git log --pretty='%h %ai %s') | head -1"; +## avoid stdint.h hack +#system "find '$FindBin::Bin/ltm/' -name '*.c' -o -name '*.h' | xargs sed -i" +# . " -e 's/uint8_t/unsigned char/g'" +# . " -e 's/uint16_t/unsigned short/g'" +# . " -e 's/uint32_t/unsigned int/g'" +# . " -e 's/uint64_t/unsigned long long/g'" +# . " -e 's/int8_t/char/g'" +# . " -e 's/int16_t/short/g'" +# . " -e 's/int32_t/int/g'" +# . " -e 's/int64_t/long long/g'" +# . " -e 's/# *include *<stdint.h>//'"; warn "update libtomcrypt from github (branch: $ltc_branch)..\n"; system 'rm', '-rf', bsd_glob("$FindBin::Bin/ltc/*"); |